refactor(i18n): new hook api (#7273)

# NEW HOOK API

`useI18n`: same as `useAFFiNEI18N`, with additional APIs

```ts
import { useI18n } from '@affine/i18n'

const i18n = useI18n()
i18n['hello world']() -> 你好世界
```

# NEW GLOBAL i18n Instance

`I18n`: use i18n capabilities outside of React

```ts
import { I18n } from '@affine/i18n'

I18n['hello world']() -> 你好世界
```

# NEW TYPES

`I18nKeys` -> all i18n keys

`I18nString` -> An i18n message (key&options)
transfer and store i18n text outside of React
```ts
const msg: I18nString = {
  key: 'helloworld',
  options: {
    arg1: '123'
  }
}

I18n.t(msg) -> 你好世界123
```

before:

```ts
registerCommand('open-page', {
  name: t('command.open-page')
  // ^- translation happens here,
})
```

after:

```ts
registerCommand('open-page', {
  name: { key: 'command.open-page' }
  // ^- store I18nString here, translate when the command render to UI
})
```
This commit is contained in:
EYHN
2024-06-20 02:19:41 +00:00
parent 5b0f56399c
commit 7c0a686cd9
193 changed files with 553 additions and 575 deletions

View File

@@ -1,5 +1,5 @@
import { Button, IconButton } from '@affine/component/ui/button';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { CloseIcon } from '@blocksuite/icons/rc';
import { useCallback } from 'react';
@@ -18,7 +18,7 @@ export const LocalDemoTips = ({
onLogin,
onEnableCloud,
}: LocalDemoTipsProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const buttonLabel = isLoggedIn
? t['Enable AFFiNE Cloud']()
: t['Sign in and Enable']();

View File

@@ -1,5 +1,5 @@
import { Button } from '@affine/component/ui/button';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { Logo1Icon } from '@blocksuite/icons/rc';
import { useCallback } from 'react';
@@ -12,7 +12,7 @@ export const AffineOtherPageLayout = ({
}: {
children: React.ReactNode;
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
const openDownloadLink = useCallback(() => {
open(runtimeConfig.downloadUrl, '_blank');

View File

@@ -1,8 +1,8 @@
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useMemo } from 'react';
export const useNavConfig = () => {
const t = useAFFiNEI18N();
const t = useI18n();
return useMemo(
() => [
{

View File

@@ -1,4 +1,4 @@
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { ArrowLeftSmallIcon } from '@blocksuite/icons/rc';
import type { FC } from 'react';
@@ -6,7 +6,7 @@ import type { ButtonProps } from '../../ui/button';
import { Button } from '../../ui/button';
export const BackButton: FC<ButtonProps> = props => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<Button
type="plain"

View File

@@ -1,4 +1,4 @@
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useCallback, useState } from 'react';
import { Button } from '../../ui/button';
@@ -13,7 +13,7 @@ export const ChangeEmailPage = ({
onChangeEmail: (email: string) => Promise<boolean>;
onOpenAffine: () => void;
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
const [hasSetUp, setHasSetUp] = useState(false);
const [email, setEmail] = useState('');
const [isValidEmail, setIsValidEmail] = useState(true);

View File

@@ -1,5 +1,5 @@
import type { PasswordLimitsFragment } from '@affine/graphql';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import type { FC } from 'react';
import { useCallback, useState } from 'react';
@@ -20,7 +20,7 @@ export const ChangePasswordPage: FC<{
onSetPassword: propsOnSetPassword,
onOpenAffine,
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
const [hasSetUp, setHasSetUp] = useState(false);
const onSetPassword = useCallback(

View File

@@ -1,4 +1,4 @@
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import type { FC } from 'react';
import { Button } from '../../ui/button';
@@ -7,7 +7,7 @@ import { AuthPageContainer } from './auth-page-container';
export const ConfirmChangeEmail: FC<{
onOpenAffine: () => void;
}> = ({ onOpenAffine }) => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<AuthPageContainer

View File

@@ -1,4 +1,4 @@
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import type { FC } from 'react';
import { Button } from '../../ui/button';
@@ -7,7 +7,7 @@ import { AuthPageContainer } from './auth-page-container';
export const ConfirmChangeEmail: FC<{
onOpenAffine: () => void;
}> = ({ onOpenAffine }) => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<AuthPageContainer

View File

@@ -1,5 +1,5 @@
import { type PasswordLimitsFragment } from '@affine/graphql';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { type Options, passwordStrength } from 'check-password-strength';
import { type FC, useEffect, useMemo } from 'react';
import { useCallback, useState } from 'react';
@@ -43,7 +43,7 @@ export const PasswordInput: FC<
onPrevent: () => void;
}
> = ({ passwordLimits, onPass, onPrevent, ...inputProps }) => {
const t = useAFFiNEI18N();
const t = useI18n();
const [status, setStatus] = useState<Status | null>(null);
const [confirmStatus, setConfirmStatus] = useState<

View File

@@ -1,5 +1,5 @@
import type { PasswordLimitsFragment } from '@affine/graphql';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import type { FC } from 'react';
import { useCallback, useState } from 'react';
@@ -20,7 +20,7 @@ export const SetPasswordPage: FC<{
onSetPassword: propsOnSetPassword,
onOpenAffine,
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
const [hasSetUp, setHasSetUp] = useState(false);
const onSetPassword = useCallback(

View File

@@ -1,5 +1,5 @@
import type { PasswordLimitsFragment } from '@affine/graphql';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import type { FC } from 'react';
import { useCallback, useRef, useState } from 'react';
@@ -13,7 +13,7 @@ export const SetPassword: FC<{
onLater?: () => void;
onSetPassword: (password: string) => void;
}> = ({ passwordLimits, onLater, onSetPassword, showLater = false }) => {
const t = useAFFiNEI18N();
const t = useI18n();
const [passwordPass, setPasswordPass] = useState(false);
const passwordRef = useRef('');

View File

@@ -1,4 +1,4 @@
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import type { FC } from 'react';
import { Button } from '../../ui/button';
@@ -7,7 +7,7 @@ import { AuthPageContainer } from './auth-page-container';
export const SignInSuccessPage: FC<{
onOpenAffine: () => void;
}> = ({ onOpenAffine }) => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<AuthPageContainer
title={t['com.affine.auth.signed.success.title']()}

View File

@@ -1,5 +1,5 @@
import type { PasswordLimitsFragment } from '@affine/graphql';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import type { FC } from 'react';
import { useCallback, useState } from 'react';
@@ -21,7 +21,7 @@ export const SignUpPage: FC<{
onOpenAffine,
openButtonText,
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
const [hasSetUp, setHasSetUp] = useState(false);
const onSetPassword = useCallback(

View File

@@ -1,10 +1,10 @@
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import type { ConfirmModalProps } from '../../ui/modal';
import { ConfirmModal } from '../../ui/modal';
export const PublicLinkDisableModal = (props: ConfirmModalProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<ConfirmModal

View File

@@ -1,6 +1,6 @@
import { AuthPageContainer } from '@affine/component/auth-components';
import type { GetInviteInfoQuery } from '@affine/graphql';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { Avatar } from '../../ui/avatar';
import { Button } from '../../ui/button';
@@ -13,7 +13,7 @@ export const AcceptInvitePage = ({
onOpenWorkspace: () => void;
inviteInfo: GetInviteInfoQuery['getInviteInfo'];
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<AuthPageContainer
title={t['Successfully joined!']()}

View File

@@ -1,5 +1,5 @@
import { Permission } from '@affine/graphql';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useCallback, useEffect, useState } from 'react';
import { ConfirmModal } from '../../ui/modal';
@@ -19,7 +19,7 @@ export const InviteModal = ({
onConfirm,
isMutating,
}: InviteModalProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const [inviteEmail, setInviteEmail] = useState('');
const [permission] = useState(Permission.Write);
const [isValidEmail, setIsValidEmail] = useState(true);

View File

@@ -1,5 +1,5 @@
import { ConfirmModal } from '@affine/component/ui/modal';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useCallback } from 'react';
export interface MemberLimitModalProps {
@@ -19,7 +19,7 @@ export const MemberLimitModal = ({
setOpen,
onConfirm,
}: MemberLimitModalProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const handleConfirm = useCallback(() => {
setOpen(false);
if (isFreePlan) {

View File

@@ -1,4 +1,4 @@
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { SignOutIcon } from '@blocksuite/icons/rc';
import { Avatar } from '../../ui/avatar';
@@ -25,7 +25,7 @@ export const NoPermissionOrNotFound = ({
onSignOut,
signInComponent,
}: NotFoundPageProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<AffineOtherPageLayout>
@@ -69,7 +69,7 @@ export const NotFoundPage = ({
onBack,
onSignOut,
}: NotFoundPageProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<AffineOtherPageLayout>

View File

@@ -2,7 +2,7 @@
// License on the MIT
// https://github.com/emilkowalski/sonner/blob/5cb703edc108a23fd74979235c2f3c4005edd2a7/src/index.tsx
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { CloseIcon, InformationFillDuotoneIcon } from '@blocksuite/icons/rc';
import * as Toast from '@radix-ui/react-toast';
import clsx from 'clsx';
@@ -72,7 +72,7 @@ const typeColorMap = {
};
function NotificationCard(props: NotificationCardProps): ReactNode {
const t = useAFFiNEI18N();
const t = useI18n();
const removeNotification = useSetAtom(removeNotificationAtom);
const { notification, notifications, setHeights, heights, index } = props;

View File

@@ -1,4 +1,4 @@
import type { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { useI18n } from '@affine/i18n';
import { ImportIcon, PlusIcon } from '@blocksuite/icons/rc';
import type { createStore } from 'jotai';
@@ -11,7 +11,7 @@ export function registerAffineCreationCommands({
pageHelper,
t,
}: {
t: ReturnType<typeof useAFFiNEI18N>;
t: ReturnType<typeof useI18n>;
store: ReturnType<typeof createStore>;
pageHelper: ReturnType<typeof usePageHelper>;
}) {

View File

@@ -1,4 +1,4 @@
import type { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { useI18n } from '@affine/i18n';
import { ContactWithUsIcon, NewIcon } from '@blocksuite/icons/rc';
import type { createStore } from 'jotai';
@@ -10,7 +10,7 @@ export function registerAffineHelpCommands({
t,
store,
}: {
t: ReturnType<typeof useAFFiNEI18N>;
t: ReturnType<typeof useI18n>;
store: ReturnType<typeof createStore>;
}) {
const unsubs: Array<() => void> = [];

View File

@@ -1,4 +1,4 @@
import type { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { useI18n } from '@affine/i18n';
import { SidebarIcon } from '@blocksuite/icons/rc';
import type { createStore } from 'jotai';
@@ -9,7 +9,7 @@ export function registerAffineLayoutCommands({
t,
store,
}: {
t: ReturnType<typeof useAFFiNEI18N>;
t: ReturnType<typeof useI18n>;
store: ReturnType<typeof createStore>;
}) {
const unsubs: Array<() => void> = [];

View File

@@ -1,5 +1,5 @@
import { WorkspaceSubPath } from '@affine/core/shared';
import type { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { useI18n } from '@affine/i18n';
import { ArrowRightBigIcon } from '@blocksuite/icons/rc';
import type { DocCollection } from '@blocksuite/store';
import type { createStore } from 'jotai';
@@ -15,7 +15,7 @@ export function registerAffineNavigationCommands({
docCollection,
navigationHelper,
}: {
t: ReturnType<typeof useAFFiNEI18N>;
t: ReturnType<typeof useI18n>;
store: ReturnType<typeof createStore>;
navigationHelper: ReturnType<typeof useNavigateHelper>;
docCollection: DocCollection;

View File

@@ -1,4 +1,4 @@
import type { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { useI18n } from '@affine/i18n';
import { SettingsIcon } from '@blocksuite/icons/rc';
import type { AffineEditorContainer } from '@blocksuite/presets';
import { appSettingAtom } from '@toeverything/infra';
@@ -14,7 +14,7 @@ export function registerAffineSettingsCommands({
theme,
languageHelper,
}: {
t: ReturnType<typeof useAFFiNEI18N>;
t: ReturnType<typeof useI18n>;
store: ReturnType<typeof createStore>;
theme: ReturnType<typeof useTheme>;
languageHelper: ReturnType<typeof useLanguageHelper>;

View File

@@ -1,6 +1,6 @@
import { updateReadyAtom } from '@affine/core/hooks/use-app-updater';
import { apis } from '@affine/electron-api';
import type { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { useI18n } from '@affine/i18n';
import { ResetIcon } from '@blocksuite/icons/rc';
import type { createStore } from 'jotai';
@@ -10,7 +10,7 @@ export function registerAffineUpdatesCommands({
t,
store,
}: {
t: ReturnType<typeof useAFFiNEI18N>;
t: ReturnType<typeof useI18n>;
store: ReturnType<typeof createStore>;
}) {
const unsubs: Array<() => void> = [];

View File

@@ -1,7 +1,6 @@
import { Button } from '@affine/component/ui/button';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { Trans, useI18n } from '@affine/i18n';
import { useTheme } from 'next-themes';
import type { FC, PropsWithChildren, ReactNode } from 'react';
import { useState } from 'react';
@@ -58,7 +57,7 @@ export const ErrorDetail: FC<ErrorDetailProps> = props => {
} = props;
const descriptions = Array.isArray(description) ? description : [description];
const [isBtnLoading, setBtnLoading] = useState(false);
const t = useAFFiNEI18N();
const t = useI18n();
const { resolvedTheme } = useTheme();
const onBtnClick = useAsyncCallback(async () => {

View File

@@ -1,4 +1,4 @@
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import type { FC } from 'react';
import { useCallback } from 'react';
@@ -10,7 +10,7 @@ import type { FallbackProps } from '../error-basic/fallback-creator';
*/
export const AnyErrorFallback: FC<FallbackProps> = props => {
const { error } = props;
const t = useAFFiNEI18N();
const t = useI18n();
const reloadPage = useCallback(() => {
document.location.reload();

View File

@@ -1,5 +1,5 @@
import { NoPageRootError } from '@affine/core/components/blocksuite/block-suite-editor/no-page-error';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { ContactUS, ErrorDetail } from '../error-basic/error-detail';
import { createErrorFallback } from '../error-basic/fallback-creator';
@@ -8,7 +8,7 @@ export const NoPageRootFallback = createErrorFallback(
NoPageRootError,
props => {
const { resetError } = props;
const t = useAFFiNEI18N();
const t = useI18n();
return (
<ErrorDetail

View File

@@ -1,5 +1,5 @@
import { PageNotFoundError } from '@affine/env/constant';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useCallback } from 'react';
import {
@@ -10,7 +10,7 @@ import { ErrorDetail, ErrorStatus } from '../error-basic/error-detail';
import { createErrorFallback } from '../error-basic/fallback-creator';
export const PageNotFoundDetail = createErrorFallback(PageNotFoundError, () => {
const t = useAFFiNEI18N();
const t = useI18n();
const { jumpToIndex } = useNavigateHelper();
const onBtnClick = useCallback(

View File

@@ -1,4 +1,4 @@
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useCallback, useMemo, useState } from 'react';
import { RecoverableError } from '../../../../unexpected-application-state/errors';
@@ -9,7 +9,7 @@ export const RecoverableErrorFallback = createErrorFallback(
RecoverableError,
props => {
const { error, resetError } = props;
const t = useAFFiNEI18N();
const t = useI18n();
const [count, rerender] = useState(0);
const canRetry = error.canRetry();

View File

@@ -2,7 +2,7 @@ import { Button, FlexWrapper, notify } from '@affine/component';
import { openSettingModalAtom } from '@affine/core/atoms';
import { SubscriptionService } from '@affine/core/modules/cloud';
import { mixpanel } from '@affine/core/utils';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { AiIcon } from '@blocksuite/icons/rc';
import {
DocService,
@@ -52,7 +52,7 @@ export const AIOnboardingEdgeless = () => {
SubscriptionService,
});
const t = useAFFiNEI18N();
const t = useI18n();
const notifyId = useLiveData(edgelessNotifyId$);
const generalAIOnboardingOpened = useLiveData(showAIOnboardingGeneral$);
const aiSubscription = useLiveData(subscriptionService.subscription.ai$);

View File

@@ -3,8 +3,7 @@ import { openSettingModalAtom } from '@affine/core/atoms';
import { useBlurRoot } from '@affine/core/hooks/use-blur-root';
import { AuthService, SubscriptionService } from '@affine/core/modules/cloud';
import { mixpanel } from '@affine/core/utils';
import { Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { Trans, useI18n } from '@affine/i18n';
import { ArrowLeftSmallIcon } from '@blocksuite/icons/rc';
import { useLiveData, useServices } from '@toeverything/infra';
import { useAtom } from 'jotai';
@@ -18,7 +17,7 @@ import { Slider } from './slider';
import { showAIOnboardingGeneral$ } from './state';
type PlayListItem = { video: string; title: ReactNode; desc: ReactNode };
type Translate = ReturnType<typeof useAFFiNEI18N>;
type Translate = ReturnType<typeof useI18n>;
const getPlayList = (t: Translate): Array<PlayListItem> => [
{
@@ -92,7 +91,7 @@ export const AIOnboardingGeneral = () => {
const prevVideoRef = useRef<HTMLVideoElement | null>(null);
const loginStatus = useLiveData(authService.session.status$);
const isLoggedIn = loginStatus === 'authenticated';
const t = useAFFiNEI18N();
const t = useI18n();
const open = useLiveData(showAIOnboardingGeneral$);
const aiSubscription = useLiveData(subscriptionService.subscription.ai$);
const [index, setIndex] = useState(0);

View File

@@ -4,7 +4,7 @@ import {
useNavigateHelper,
} from '@affine/core/hooks/use-navigate-helper';
import { AuthService } from '@affine/core/modules/cloud';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { AiIcon } from '@blocksuite/icons/rc';
import { useLiveData, useService } from '@toeverything/infra';
import { cssVar } from '@toeverything/theme';
@@ -30,7 +30,7 @@ const LocalOnboardingAnimation = () => {
};
const FooterActions = ({ onDismiss }: { onDismiss: () => void }) => {
const t = useAFFiNEI18N();
const t = useI18n();
const authService = useService(AuthService);
const loginStatus = useLiveData(authService.session.status$);
const loggedIn = loginStatus === 'authenticated';
@@ -64,7 +64,7 @@ const FooterActions = ({ onDismiss }: { onDismiss: () => void }) => {
};
export const AIOnboardingLocal = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const authService = useService(AuthService);
const notifyId = useLiveData(localNotifyId$);
const timeoutRef = useRef<ReturnType<typeof setTimeout>>();

View File

@@ -8,8 +8,7 @@ import {
import { Button } from '@affine/component/ui/button';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { AuthService } from '@affine/core/modules/cloud';
import { Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { Trans, useI18n } from '@affine/i18n';
import { useLiveData, useService } from '@toeverything/infra';
import { useCallback, useEffect, useState } from 'react';
@@ -36,7 +35,7 @@ export const AfterSignInSendEmail = ({
const [isSending, setIsSending] = useState(false);
const t = useAFFiNEI18N();
const t = useI18n();
const authService = useService(AuthService);
useEffect(() => {
const timer = setInterval(() => {

View File

@@ -7,8 +7,7 @@ import {
} from '@affine/component/auth-components';
import { Button } from '@affine/component/ui/button';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { Trans, useI18n } from '@affine/i18n';
import { useLiveData, useService } from '@toeverything/infra';
import type { FC } from 'react';
import { useCallback, useEffect, useState } from 'react';
@@ -36,7 +35,7 @@ export const AfterSignUpSendEmail: FC<AuthPanelProps> = ({
}, []);
const [isSending, setIsSending] = useState(false);
const t = useAFFiNEI18N();
const t = useI18n();
const authService = useService(AuthService);
const loginStatus = useLiveData(authService.session.status$);
useEffect(() => {

View File

@@ -1,13 +1,13 @@
import { useConfirmModal } from '@affine/component';
import { authAtom } from '@affine/core/atoms';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { atom, useAtom, useSetAtom } from 'jotai';
import { useCallback, useEffect } from 'react';
export const showAILoginRequiredAtom = atom(false);
export const AiLoginRequiredModal = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const [open, setOpen] = useAtom(showAILoginRequiredAtom);
const setAuth = useSetAtom(authAtom);
const { openConfirmModal, closeConfirmModal } = useConfirmModal();

View File

@@ -13,7 +13,7 @@ import {
sendSetPasswordEmailMutation,
sendVerifyEmailMutation,
} from '@affine/graphql';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useLiveData, useService } from '@toeverything/infra';
import { useCallback, useState } from 'react';
@@ -22,7 +22,7 @@ import { ServerConfigService } from '../../../modules/cloud';
import type { AuthPanelProps } from './index';
const useEmailTitle = (emailType: AuthPanelProps['emailType']) => {
const t = useAFFiNEI18N();
const t = useI18n();
switch (emailType) {
case 'setPassword':
@@ -37,7 +37,7 @@ const useEmailTitle = (emailType: AuthPanelProps['emailType']) => {
};
const useNotificationHint = (emailType: AuthPanelProps['emailType']) => {
const t = useAFFiNEI18N();
const t = useI18n();
switch (emailType) {
case 'setPassword':
@@ -50,7 +50,7 @@ const useNotificationHint = (emailType: AuthPanelProps['emailType']) => {
}
};
const useButtonContent = (emailType: AuthPanelProps['emailType']) => {
const t = useAFFiNEI18N();
const t = useI18n();
switch (emailType) {
case 'setPassword':
@@ -138,7 +138,7 @@ export const SendEmail = ({
email,
emailType,
}: AuthPanelProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const serverConfig = useService(ServerConfigService).serverConfig;
const passwordLimits = useLiveData(

View File

@@ -7,7 +7,7 @@ import {
import { Button } from '@affine/component/ui/button';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { AuthService } from '@affine/core/modules/cloud';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useService } from '@toeverything/infra';
import type { FC } from 'react';
import { useCallback, useState } from 'react';
@@ -22,7 +22,7 @@ export const SignInWithPassword: FC<AuthPanelProps> = ({
email,
onSignedIn,
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
const authService = useService(AuthService);
const [password, setPassword] = useState('');

View File

@@ -2,8 +2,7 @@ import { notify } from '@affine/component';
import { AuthInput, ModalHeader } from '@affine/component/auth-components';
import { Button } from '@affine/component/ui/button';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { Trans, useI18n } from '@affine/i18n';
import { ArrowDownBigIcon } from '@blocksuite/icons/rc';
import { useLiveData, useService } from '@toeverything/infra';
import type { FC } from 'react';
@@ -28,7 +27,7 @@ export const SignIn: FC<AuthPanelProps> = ({
email,
onSignedIn,
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
const authService = useService(AuthService);
const [searchParams] = useSearchParams();
const [isMutating, setIsMutating] = useState(false);

View File

@@ -1,6 +1,6 @@
import { Tooltip } from '@affine/component/ui/tooltip';
import { mixpanel } from '@affine/core/utils';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useLiveData, useServices } from '@toeverything/infra';
import { useSetAtom } from 'jotai';
import { useCallback, useEffect } from 'react';
@@ -49,7 +49,7 @@ export const UserPlanButton = () => {
[setSettingModalAtom]
);
const t = useAFFiNEI18N();
const t = useI18n();
if (!hasPayment) {
// no payment feature

View File

@@ -6,7 +6,7 @@ import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { DebugLogger } from '@affine/debug';
import { apis } from '@affine/electron-api';
import { WorkspaceFlavour } from '@affine/env/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import {
initEmptyPage,
useLiveData,
@@ -55,7 +55,7 @@ const NameWorkspaceContent = ({
onConfirmName,
...props
}: NameWorkspaceContentProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const [workspaceName, setWorkspaceName] = useState('');
const [enable, setEnable] = useState(shouldEnableCloud);
const session = useService(AuthService).session;
@@ -182,7 +182,7 @@ export const CreateWorkspaceModal = ({
onCreate,
}: ModalProps) => {
const [step, setStep] = useState<CreateWorkspaceStep>();
const t = useAFFiNEI18N();
const t = useI18n();
const workspacesService = useService(WorkspacesService);
const [loading, setLoading] = useState(false);

View File

@@ -4,7 +4,7 @@ import {
openHistoryTipsModalAtom,
} from '@affine/core/atoms';
import { useEnableCloud } from '@affine/core/hooks/affine/use-enable-cloud';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useService, WorkspaceService } from '@toeverything/infra';
import { useAtom, useSetAtom } from 'jotai';
import { useCallback } from 'react';
@@ -12,7 +12,7 @@ import { useCallback } from 'react';
import TopSvg from './top-svg';
export const HistoryTipsModal = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const currentWorkspace = useService(WorkspaceService).workspace;
const [open, setOpen] = useAtom(openHistoryTipsModalAtom);
const setTempDisableCloudOpen = useSetAtom(openDisableCloudAlertModalAtom);

View File

@@ -1,10 +1,10 @@
import { OverlayModal } from '@affine/component';
import { openIssueFeedbackModalAtom } from '@affine/core/atoms';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useAtom } from 'jotai';
export const IssueFeedbackModal = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const [open, setOpen] = useAtom(openIssueFeedbackModalAtom);
return (

View File

@@ -6,8 +6,7 @@ import { openSettingModalAtom } from '@affine/core/atoms';
import { useDocCollectionPageTitle } from '@affine/core/hooks/use-block-suite-workspace-page-title';
import { WorkspacePermissionService } from '@affine/core/modules/permissions';
import { WorkspaceQuotaService } from '@affine/core/modules/quota';
import { i18nTime, Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { i18nTime, Trans, useI18n } from '@affine/i18n';
import { CloseIcon, ToggleCollapseIcon } from '@blocksuite/icons/rc';
import type { Doc as BlockSuiteDoc, DocCollection } from '@blocksuite/store';
import * as Collapsible from '@radix-ui/react-collapsible';
@@ -234,7 +233,7 @@ const PlanPrompt = () => {
});
}, [setSettingModalAtom]);
const t = useAFFiNEI18N();
const t = useI18n();
const planTitle = useMemo(() => {
return (
@@ -315,7 +314,7 @@ const PageHistoryList = ({
onLoadMore: (() => void) | false;
loadingMore: boolean;
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
const historyListByDay = useMemo(() => {
return historyListGroupByDay(historyList);
}, [historyList]);
@@ -410,7 +409,7 @@ const PageHistoryList = ({
};
const EmptyHistoryPrompt = () => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<div
@@ -447,7 +446,7 @@ const PageHistoryManager = ({
const snapshotPage = useSnapshotPage(docCollection, pageDocId, activeVersion);
const t = useAFFiNEI18N();
const t = useI18n();
const { onRestore, isMutating } = useRestorePage(docCollection, pageId);

View File

@@ -1,8 +1,7 @@
import { ConfirmModal } from '@affine/component';
import { WorkspacePropertiesAdapter } from '@affine/core/modules/properties';
import type { PageInfoCustomPropertyMeta } from '@affine/core/modules/properties/services/schema';
import { Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { Trans, useI18n } from '@affine/i18n';
import { useService } from '@toeverything/infra';
import { useMemo } from 'react';
@@ -19,7 +18,7 @@ export const ConfirmDeletePropertyModal = ({
onConfirm: () => void;
onCancel: () => void;
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
const adapter = useService(WorkspacePropertiesAdapter);
const count = useMemo(() => {
const manager = new PagePropertiesMetaManager(adapter);

View File

@@ -1,5 +1,5 @@
import { Menu, Scrollable } from '@affine/component';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { chunk } from 'lodash-es';
import { useEffect, useRef } from 'react';
@@ -32,7 +32,7 @@ export const IconsSelectorPanel = ({
iconButton.scrollIntoView({ block: 'center' });
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const t = useAFFiNEI18N();
const t = useI18n();
return (
<Scrollable.Root>
<div role="heading" className={styles.menuHeader}>

View File

@@ -7,7 +7,7 @@ import {
Scrollable,
} from '@affine/component';
import type { PageInfoCustomPropertyMeta } from '@affine/core/modules/properties/services/schema';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import type { KeyboardEventHandler, MouseEventHandler } from 'react';
import { cloneElement, isValidElement, useCallback } from 'react';
@@ -102,7 +102,7 @@ export const EditPropertyNameMenuItem = ({
[onBlur]
);
const t = useAFFiNEI18N();
const t = useI18n();
return (
<div className={styles.propertyRowNamePopupRow}>
<IconsSelectorButton
@@ -126,7 +126,7 @@ export const PropertyTypeMenuItem = ({
property: PageInfoCustomPropertyMeta;
}) => {
const Icon = nameToIcon(getDefaultIconName(property.type), property.type);
const t = useAFFiNEI18N();
const t = useI18n();
return (
<div className={styles.propertyRowTypeItem}>
{t['com.affine.page-properties.create-property.menu.header']()}

View File

@@ -4,8 +4,7 @@ import type {
PageInfoCustomPropertyMeta,
PagePropertyType,
} from '@affine/core/modules/properties/services/schema';
import { i18nTime } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { i18nTime, useI18n } from '@affine/i18n';
import { DocService, useService } from '@toeverything/infra';
import { noop } from 'lodash-es';
import type { ChangeEventHandler } from 'react';
@@ -40,7 +39,7 @@ export const DateValue = ({ property }: PropertyRowValueProps) => {
[manager, property.id]
);
const t = useAFFiNEI18N();
const t = useI18n();
return (
<Menu items={<DatePicker value={property.value} onChange={handleChange} />}>
@@ -102,7 +101,7 @@ export const TextValue = ({ property }: PropertyRowValueProps) => {
},
[]
);
const t = useAFFiNEI18N();
const t = useI18n();
useEffect(() => {
setValue(property.value);
}, [property.value]);
@@ -148,7 +147,7 @@ export const NumberValue = ({ property }: PropertyRowValueProps) => {
},
[]
);
const t = useAFFiNEI18N();
const t = useI18n();
useEffect(() => {
setValue(property.value);
}, [property.value]);
@@ -169,7 +168,7 @@ export const NumberValue = ({ property }: PropertyRowValueProps) => {
export const TagsValue = () => {
const doc = useService(DocService).doc;
const t = useAFFiNEI18N();
const t = useI18n();
return (
<TagsInlineEditor

View File

@@ -14,8 +14,7 @@ import type {
PageInfoCustomPropertyMeta,
PagePropertyType,
} from '@affine/core/modules/properties/services/schema';
import { i18nTime } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { i18nTime, useI18n } from '@affine/i18n';
import { assertExists } from '@blocksuite/global/utils';
import {
ArrowDownSmallIcon,
@@ -254,7 +253,7 @@ const VisibilityModeSelector = ({
property: PageInfoCustomProperty;
}) => {
const manager = useContext(managerContext);
const t = useAFFiNEI18N();
const t = useI18n();
const meta = manager.getCustomPropertyMeta(property.id);
const visibility = property.visibility || 'visible';
@@ -317,7 +316,7 @@ export const PagePropertiesSettingsPopup = ({
children,
}: PagePropertiesSettingsPopupProps) => {
const manager = useContext(managerContext);
const t = useAFFiNEI18N();
const t = useI18n();
const menuItems = useMemo(() => {
const options: MenuItemOption[] = [];
@@ -457,7 +456,7 @@ export const PagePropertyRowNameMenu = ({
onFinishEditing,
property.id,
]);
const t = useAFFiNEI18N();
const t = useI18n();
const handleNameBlur = useCallback(
(v: string) => {
manager.updateCustomPropertyMeta(meta.id, {
@@ -596,7 +595,7 @@ export const PagePropertiesTableHeader = ({
}: PagePropertiesTableHeaderProps) => {
const manager = useContext(managerContext);
const t = useAFFiNEI18N();
const t = useI18n();
const backlinks = useBlockSuitePageBacklinks(
manager.workspace.docCollection,
manager.pageId
@@ -788,7 +787,7 @@ const PagePropertyRow = ({ property }: PagePropertyRowProps) => {
};
const PageTagsRow = () => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<div
className={styles.tagsPropertyRow}
@@ -882,7 +881,7 @@ export const PagePropertiesCreatePropertyMenuItems = ({
onCreated,
metaManager,
}: PagePropertiesCreatePropertyMenuItemsProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const onAddProperty = useCallback(
(
e: React.MouseEvent,
@@ -943,7 +942,7 @@ const PagePropertiesAddPropertyMenuItems = ({
}: PagePropertiesAddPropertyMenuItemsProps) => {
const manager = useContext(managerContext);
const t = useAFFiNEI18N();
const t = useI18n();
const metaList = manager.metaManager.getOrderedPropertiesSchema();
const nonRequiredMetaList = metaList.filter(meta => !meta.required);
const isChecked = useCallback(
@@ -1004,7 +1003,7 @@ const PagePropertiesAddPropertyMenuItems = ({
};
export const PagePropertiesAddProperty = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const [adding, setAdding] = useState(true);
const manager = useContext(managerContext);
const toggleAdding: MouseEventHandler = useCallback(e => {

View File

@@ -3,7 +3,7 @@ import { IconButton, Input, Menu, Scrollable } from '@affine/component';
import { useNavigateHelper } from '@affine/core/hooks/use-navigate-helper';
import { WorkspaceLegacyProperties } from '@affine/core/modules/properties';
import { DeleteTagConfirmModal, TagService } from '@affine/core/modules/tag';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { DeleteIcon, MoreHorizontalIcon, TagsIcon } from '@blocksuite/icons/rc';
import { useLiveData, useService } from '@toeverything/infra';
import clsx from 'clsx';
@@ -73,7 +73,7 @@ export const EditTagMenu = ({
tagId: string;
onTagDelete: (tagIds: string[]) => void;
}>) => {
const t = useAFFiNEI18N();
const t = useI18n();
const legacyProperties = useService(WorkspaceLegacyProperties);
const tagList = useService(TagService).tagList;
const tag = useLiveData(tagList.tagByTagId$(tagId));
@@ -172,7 +172,7 @@ export const EditTagMenu = ({
};
export const TagsEditor = ({ pageId, readonly }: TagsEditorProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const tagList = useService(TagService).tagList;
const tags = useLiveData(tagList.tags$);
const tagIds = useLiveData(tagList.tagIdsByPageId$(pageId));

View File

@@ -1,5 +1,5 @@
import { ConfirmModal } from '@affine/component/ui/modal';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useAtom } from 'jotai';
import { useCallback } from 'react';
@@ -8,7 +8,7 @@ import * as styles from './style.css';
export const PaymentDisableModal = () => {
const [open, setOpen] = useAtom(openPaymentDisableAtom);
const t = useAFFiNEI18N();
const t = useI18n();
const onClickCancel = useCallback(() => {
setOpen(false);

View File

@@ -4,14 +4,14 @@ import { UserQuotaService } from '@affine/core/modules/cloud';
import { WorkspacePermissionService } from '@affine/core/modules/permissions';
import { WorkspaceQuotaService } from '@affine/core/modules/quota';
import { mixpanel } from '@affine/core/utils';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useLiveData, useService, WorkspaceService } from '@toeverything/infra';
import bytes from 'bytes';
import { useAtom, useSetAtom } from 'jotai';
import { useCallback, useEffect, useMemo } from 'react';
export const CloudQuotaModal = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const currentWorkspace = useService(WorkspaceService).workspace;
const [open, setOpen] = useAtom(openQuotaModalAtom);
const workspaceQuotaService = useService(WorkspaceQuotaService);

View File

@@ -1,12 +1,12 @@
import { ConfirmModal } from '@affine/component/ui/modal';
import { openQuotaModalAtom } from '@affine/core/atoms';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useService, WorkspaceService } from '@toeverything/infra';
import { useAtom } from 'jotai';
import { useCallback, useEffect } from 'react';
export const LocalQuotaModal = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const currentWorkspace = useService(WorkspaceService).workspace;
const [open, setOpen] = useAtom(openQuotaModalAtom);

View File

@@ -5,7 +5,7 @@ import {
useInsidePeekView,
} from '@affine/core/modules/peek-view';
import { WorkbenchLink } from '@affine/core/modules/workbench';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import {
LinkedEdgelessIcon,
LinkedPageIcon,
@@ -29,7 +29,7 @@ export interface PageReferenceRendererOptions {
docCollection: DocCollection;
pageMetaHelper: ReturnType<typeof useDocMetaHelper>;
journalHelper: ReturnType<typeof useJournalHelper>;
t: ReturnType<typeof useAFFiNEI18N>;
t: ReturnType<typeof useI18n>;
}
// use a function to be rendered in the lit renderer
export function pageReferenceRenderer({
@@ -77,7 +77,7 @@ export function AffinePageReference({
}) {
const pageMetaHelper = useDocMetaHelper(docCollection);
const journalHelper = useJournalHelper(docCollection);
const t = useAFFiNEI18N();
const t = useI18n();
const docsService = useService(DocsService);
const mode$ = LiveData.from(docsService.list.observeMode(pageId), null);

View File

@@ -7,7 +7,7 @@ import {
UserCopilotQuotaService,
} from '@affine/core/modules/cloud';
import { mixpanel } from '@affine/core/utils';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useLiveData, useService } from '@toeverything/infra';
import { cssVar } from '@toeverything/theme';
import { useSetAtom } from 'jotai';
@@ -17,7 +17,7 @@ import { AIResume, AISubscribe } from '../general-setting/plans/ai/actions';
import * as styles from './storage-progress.css';
export const AIUsagePanel = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const setOpenSettingModal = useSetAtom(openSettingModalAtom);
const serverConfigService = useService(ServerConfigService);
const hasPaymentFeature = useLiveData(

View File

@@ -6,7 +6,7 @@ import {
import { Avatar } from '@affine/component/ui/avatar';
import { Button } from '@affine/component/ui/button';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { ArrowRightSmallIcon, CameraIcon } from '@blocksuite/icons/rc';
import {
useEnsureLiveData,
@@ -31,7 +31,7 @@ import { StorageProgress } from './storage-progress';
import * as styles from './style.css';
export const UserAvatar = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const session = useService(AuthService).session;
const account = useEnsureLiveData(session.account$);
@@ -89,7 +89,7 @@ export const UserAvatar = () => {
};
export const AvatarAndName = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const session = useService(AuthService).session;
const account = useEnsureLiveData(session.account$);
const [input, setInput] = useState<string>(account.label);
@@ -158,7 +158,7 @@ export const AvatarAndName = () => {
};
const StoragePanel = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const setSettingModalAtom = useSetAtom(openSettingModalAtom);
const onUpgrade = useCallback(() => {
@@ -193,7 +193,7 @@ export const AccountSetting: FC = () => {
const serverFeatures = useLiveData(
serverConfigService.serverConfig.features$
);
const t = useAFFiNEI18N();
const t = useI18n();
const session = authService.session;
useEffect(() => {
session.revalidate();

View File

@@ -1,5 +1,5 @@
import { Button, ErrorMessage, Skeleton, Tooltip } from '@affine/component';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useLiveData, useService } from '@toeverything/infra';
import { cssVar } from '@toeverything/theme';
import { useEffect, useMemo } from 'react';
@@ -22,7 +22,7 @@ enum ButtonType {
}
export const StorageProgress = ({ onUpgrade }: StorageProgressProgress) => {
const t = useAFFiNEI18N();
const t = useI18n();
const quota = useService(UserQuotaService).quota;
useEffect(() => {

View File

@@ -5,7 +5,7 @@ import {
SettingWrapper,
} from '@affine/component/setting-components';
import { useAppUpdater } from '@affine/core/hooks/use-app-updater';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { ArrowRightSmallIcon, OpenInNewIcon } from '@blocksuite/icons/rc';
import { useCallback } from 'react';
@@ -17,7 +17,7 @@ import * as styles from './style.css';
import { UpdateCheckSection } from './update-check-section';
export const AboutAffine = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const { appSettings, updateSettings } = useAppSettingHelper();
const { toggleAutoCheck, toggleAutoDownload } = useAppUpdater();
const channel = runtimeConfig.appBuildType;

View File

@@ -3,7 +3,7 @@ import { SettingRow } from '@affine/component/setting-components';
import { Button } from '@affine/component/ui/button';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { useAppUpdater } from '@affine/core/hooks/use-app-updater';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import clsx from 'clsx';
import { useCallback, useMemo, useState } from 'react';
@@ -17,7 +17,7 @@ enum CheckUpdateStatus {
}
const useUpdateStatusLabels = (checkUpdateStatus: CheckUpdateStatus) => {
const t = useAFFiNEI18N();
const t = useI18n();
const { updateAvailable, downloadProgress, updateReady, checkingForUpdates } =
useAppUpdater();
@@ -91,7 +91,7 @@ const useUpdateStatusLabels = (checkUpdateStatus: CheckUpdateStatus) => {
};
export const UpdateCheckSection = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const {
checkForUpdates,
downloadUpdate,

View File

@@ -4,7 +4,7 @@ import {
SettingRow,
SettingWrapper,
} from '@affine/component/setting-components';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import type { AppSetting } from '@toeverything/infra';
import { fontStyleOptions, windowFrameStyleOptions } from '@toeverything/infra';
import { useTheme } from 'next-themes';
@@ -16,7 +16,7 @@ import { DateFormatSetting } from './date-format-setting';
import { settingWrapper } from './style.css';
export const ThemeSettings = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const { setTheme, theme } = useTheme();
return (
@@ -45,7 +45,7 @@ export const ThemeSettings = () => {
};
const FontFamilySettings = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const { appSettings, updateSettings } = useAppSettingHelper();
return (
<RadioButtonGroup
@@ -92,7 +92,7 @@ const FontFamilySettings = () => {
};
export const AppearanceSettings = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const { appSettings, updateSettings } = useAppSettingHelper();

View File

@@ -18,8 +18,7 @@ import {
SubscriptionRecurring,
SubscriptionStatus,
} from '@affine/graphql';
import { i18nTime, Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { i18nTime, Trans, useI18n } from '@affine/i18n';
import { ArrowRightSmallIcon } from '@blocksuite/icons/rc';
import { useLiveData, useService } from '@toeverything/infra';
import { useSetAtom } from 'jotai';
@@ -54,7 +53,7 @@ const getMessageKey = (
};
export const BillingSettings = () => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<>
@@ -85,7 +84,7 @@ export const BillingSettings = () => {
};
const SubscriptionSettings = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const subscriptionService = useService(SubscriptionService);
useEffect(() => {
subscriptionService.subscription.revalidate();
@@ -248,7 +247,7 @@ const SubscriptionSettings = () => {
};
const AIPlanCard = ({ onClick }: { onClick: () => void }) => {
const t = useAFFiNEI18N();
const t = useI18n();
const subscriptionService = useService(SubscriptionService);
useEffect(() => {
subscriptionService.subscription.revalidate();
@@ -325,7 +324,7 @@ const PlanAction = ({
plan: string;
gotoPlansSetting: () => void;
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<Button
@@ -345,7 +344,7 @@ const PaymentMethodUpdater = () => {
const { isMutating, trigger } = useMutation({
mutation: createCustomerPortalMutation,
});
const t = useAFFiNEI18N();
const t = useI18n();
const update = useAsyncCallback(async () => {
await trigger(null, {
@@ -368,7 +367,7 @@ const PaymentMethodUpdater = () => {
};
const ResumeSubscription = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const [open, setOpen] = useState(false);
return (
@@ -392,7 +391,7 @@ const CancelSubscription = ({ loading }: { loading?: boolean }) => {
};
const BillingHistory = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const { data: invoicesCountQueryResult } = useQuery({
query: getInvoicesCountQuery,
});
@@ -437,7 +436,7 @@ const InvoiceLine = ({
}: {
invoice: NonNullable<InvoicesQuery['currentUser']>['invoices'][0];
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
const open = useCallback(() => {
if (invoice.link) {
@@ -471,7 +470,7 @@ const InvoiceLine = ({
};
const SubscriptionSettingSkeleton = () => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<SettingWrapper
title={t['com.affine.payment.billing-setting.information']()}
@@ -485,7 +484,7 @@ const SubscriptionSettingSkeleton = () => {
};
const BillingHistorySkeleton = () => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<SettingWrapper title={t['com.affine.payment.billing-setting.history']()}>
<div className={styles.billingHistorySkeleton}>

View File

@@ -2,7 +2,7 @@ import { Button, Checkbox, Loading, Switch } from '@affine/component';
import { SettingHeader } from '@affine/component/setting-components';
import { useAppSettingHelper } from '@affine/core/hooks/affine/use-app-setting-helper';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useAtom } from 'jotai';
import { atomWithStorage } from 'jotai/utils';
import { Suspense, useCallback, useState } from 'react';
@@ -15,7 +15,7 @@ const ExperimentalFeaturesPrompt = ({
}: {
onConfirm: () => void;
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
const [checked, setChecked] = useState(false);
const onChange: (
@@ -160,7 +160,7 @@ const BlocksuiteFeatureFlagSettings = () => {
};
const ExperimentalFeaturesMain = () => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<>

View File

@@ -1,5 +1,5 @@
import { UserFeatureService } from '@affine/core/modules/cloud/services/user-feature';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import {
AppearanceIcon,
ExperimentIcon,
@@ -30,7 +30,7 @@ interface GeneralSettingListItem {
export type GeneralSettingList = GeneralSettingListItem[];
export const useGeneralSettingList = (): GeneralSettingList => {
const t = useAFFiNEI18N();
const t = useI18n();
const { authService, serverConfigService, userFeatureService } = useServices({
AuthService,
ServerConfigService,

View File

@@ -2,14 +2,14 @@ import { Button, type ButtonProps, useConfirmModal } from '@affine/component';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { SubscriptionService } from '@affine/core/modules/cloud';
import { SubscriptionPlan } from '@affine/graphql';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useService } from '@toeverything/infra';
import { nanoid } from 'nanoid';
import { useState } from 'react';
export interface AICancelProps extends ButtonProps {}
export const AICancel = ({ ...btnProps }: AICancelProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const [isMutating, setMutating] = useState(false);
const [idempotencyKey, setIdempotencyKey] = useState(nanoid());
const subscription = useService(SubscriptionService).subscription;

View File

@@ -1,11 +1,11 @@
import { Button, type ButtonProps } from '@affine/component';
import { authAtom } from '@affine/core/atoms';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useSetAtom } from 'jotai';
import { useCallback } from 'react';
export const AILogin = (btnProps: ButtonProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const setOpen = useSetAtom(authAtom);
const onClickSignIn = useCallback(() => {

View File

@@ -7,7 +7,7 @@ import {
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { SubscriptionService } from '@affine/core/modules/cloud';
import { SubscriptionPlan } from '@affine/graphql';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { SingleSelectSelectSolidIcon } from '@blocksuite/icons/rc';
import { useService } from '@toeverything/infra';
import { cssVar } from '@toeverything/theme';
@@ -17,7 +17,7 @@ import { useState } from 'react';
export interface AIResumeProps extends ButtonProps {}
export const AIResume = ({ ...btnProps }: AIResumeProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const [idempotencyKey, setIdempotencyKey] = useState(nanoid());
const subscription = useService(SubscriptionService).subscription;

View File

@@ -3,7 +3,7 @@ import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { SubscriptionService } from '@affine/core/modules/cloud';
import { mixpanel, popupWindow } from '@affine/core/utils';
import { SubscriptionPlan, SubscriptionRecurring } from '@affine/graphql';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useLiveData, useService } from '@toeverything/infra';
import { nanoid } from 'nanoid';
import { useEffect, useState } from 'react';
@@ -21,7 +21,7 @@ export const AISubscribe = ({ ...btnProps }: AISubscribeProps) => {
subscriptionService.prices.revalidate();
}, [subscriptionService]);
const t = useAFFiNEI18N();
const t = useI18n();
useEffect(() => {
if (isOpenedExternalWindow) {

View File

@@ -1,7 +1,6 @@
import { Button } from '@affine/component';
import { AuthService, SubscriptionService } from '@affine/core/modules/cloud';
import { i18nTime } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { i18nTime, useI18n } from '@affine/i18n';
import { useLiveData, useService } from '@toeverything/infra';
import { useEffect } from 'react';
@@ -11,7 +10,7 @@ import * as styles from './ai-plan.css';
import { AIBenefits } from './benefits';
export const AIPlan = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const authService = useService(AuthService);
const subscriptionService = useService(SubscriptionService);

View File

@@ -1,4 +1,4 @@
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import {
CheckBoxCheckLinearIcon,
PenIcon,
@@ -8,7 +8,7 @@ import { useMemo } from 'react';
import * as styles from './ai-plan.css';
const benefitsGetter = (t: ReturnType<typeof useAFFiNEI18N>) => [
const benefitsGetter = (t: ReturnType<typeof useI18n>) => [
{
name: t['com.affine.payment.ai.benefit.g1'](),
icon: <TextIcon />,
@@ -39,7 +39,7 @@ const benefitsGetter = (t: ReturnType<typeof useAFFiNEI18N>) => [
];
export const AIBenefits = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const benefits = useMemo(() => benefitsGetter(t), [t]);
// TODO: responsive
return (

View File

@@ -1,13 +1,13 @@
// TODO: we don't handle i18n for now
// it's better to manage all equity at server side
import { SubscriptionPlan, SubscriptionRecurring } from '@affine/graphql';
import type { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { useI18n } from '@affine/i18n';
import { AfFiNeIcon } from '@blocksuite/icons/rc';
import type { ReactNode } from 'react';
import { planTitleTitleCaption } from './style.css';
type T = ReturnType<typeof useAFFiNEI18N>;
type T = ReturnType<typeof useI18n>;
export type Benefits = Record<
string,

View File

@@ -1,7 +1,6 @@
import { Switch } from '@affine/component';
import { SubscriptionPlan, SubscriptionRecurring } from '@affine/graphql';
import { Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { Trans, useI18n } from '@affine/i18n';
import { useLiveData, useService } from '@toeverything/infra';
import { useEffect, useMemo, useRef, useState } from 'react';
import type { FallbackProps } from 'react-error-boundary';
@@ -20,7 +19,7 @@ const getRecurringLabel = ({
t,
}: {
recurring: SubscriptionRecurring;
t: ReturnType<typeof useAFFiNEI18N>;
t: ReturnType<typeof useI18n>;
}) => {
return recurring === SubscriptionRecurring.Monthly
? t['com.affine.payment.recurring-monthly']()
@@ -28,7 +27,7 @@ const getRecurringLabel = ({
};
const Settings = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const loggedIn =
useLiveData(useService(AuthService).session.status$) === 'authenticated';
@@ -214,7 +213,7 @@ export const AFFiNEPricingPlans = () => {
};
const PlansErrorBoundary = ({ resetErrorBoundary }: FallbackProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const scroll = (
<div className={styles.errorTip}>

View File

@@ -1,7 +1,7 @@
import { Button, Divider, IconButton } from '@affine/component';
import { SettingHeader } from '@affine/component/setting-components';
import { openSettingModalAtom } from '@affine/core/atoms';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import {
ArrowDownBigIcon,
ArrowRightBigIcon,
@@ -27,7 +27,7 @@ import { settingModalScrollContainerAtom } from '../../atoms';
import * as styles from './layout.css';
export const SeeAllLink = () => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<a
@@ -82,7 +82,7 @@ export interface PlanLayoutProps {
}
export const PlanLayout = ({ cloud, ai, aiTip }: PlanLayoutProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const [{ scrollAnchor }, setOpenSettingModal] = useAtom(openSettingModalAtom);
const aiPricingPlanRef = useRef<HTMLDivElement>(null);
const aiScrollTipRef = useRef<HTMLDivElement>(null);

View File

@@ -1,7 +1,7 @@
import { Button } from '@affine/component/ui/button';
import type { ConfirmModalProps } from '@affine/component/ui/modal';
import { ConfirmModal, Modal } from '@affine/component/ui/modal';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { DialogTrigger } from '@radix-ui/react-dialog';
import type { ReactNode } from 'react';
import { useEffect, useRef } from 'react';
@@ -26,7 +26,7 @@ export const ConfirmLoadingModal = ({
loading?: boolean;
content?: ReactNode;
} & ConfirmModalProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const confirmed = useRef(false);
const title = t[`com.affine.payment.modal.${type}.title`]();
@@ -79,7 +79,7 @@ export const DowngradeModal = ({
onOpenChange?: (open: boolean) => void;
onCancel?: () => void;
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
const canceled = useRef(false);
useEffect(() => {

View File

@@ -5,8 +5,7 @@ import { AuthService, SubscriptionService } from '@affine/core/modules/cloud';
import { popupWindow } from '@affine/core/utils';
import type { SubscriptionRecurring } from '@affine/graphql';
import { SubscriptionPlan, SubscriptionStatus } from '@affine/graphql';
import { Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { Trans, useI18n } from '@affine/i18n';
import { DoneIcon } from '@blocksuite/icons/rc';
import { useLiveData, useService } from '@toeverything/infra';
import { useAtom, useSetAtom } from 'jotai';
@@ -86,7 +85,7 @@ export const PlanCard = (props: PlanCardProps) => {
};
const ActionButton = ({ detail, recurring }: PlanCardProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const loggedIn =
useLiveData(useService(AuthService).session.status$) === 'authenticated';
const subscriptionService = useService(SubscriptionService);
@@ -157,7 +156,7 @@ const ActionButton = ({ detail, recurring }: PlanCardProps) => {
};
const CurrentPlan = () => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<Button className={styles.planAction}>
{t['com.affine.payment.current-plan']()}
@@ -166,7 +165,7 @@ const CurrentPlan = () => {
};
const Downgrade = ({ disabled }: { disabled?: boolean }) => {
const t = useAFFiNEI18N();
const t = useI18n();
const [open, setOpen] = useState(false);
const tooltipContent = disabled
@@ -192,7 +191,7 @@ const Downgrade = ({ disabled }: { disabled?: boolean }) => {
};
const BookDemo = ({ plan }: { plan: SubscriptionPlan }) => {
const t = useAFFiNEI18N();
const t = useI18n();
const url = useMemo(() => {
switch (plan) {
case SubscriptionPlan.Team:
@@ -227,7 +226,7 @@ const BookDemo = ({ plan }: { plan: SubscriptionPlan }) => {
const Upgrade = ({ recurring }: { recurring: SubscriptionRecurring }) => {
const [isMutating, setMutating] = useState(false);
const [isOpenedExternalWindow, setOpenedExternalWindow] = useState(false);
const t = useAFFiNEI18N();
const t = useI18n();
const subscriptionService = useService(SubscriptionService);
@@ -296,7 +295,7 @@ const ChangeRecurring = ({
disabled?: boolean;
due: string;
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
const [open, setOpen] = useState(false);
const [isMutating, setIsMutating] = useState(false);
// allow replay request on network error until component unmount or success
@@ -369,7 +368,7 @@ const SignUpAction = ({ children }: PropsWithChildren) => {
};
const ResumeButton = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const [open, setOpen] = useState(false);
const [hovered, setHovered] = useState(false);

View File

@@ -2,7 +2,7 @@ import {
SettingHeader,
SettingWrapper,
} from '@affine/component/setting-components';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import type { ShortcutsInfo } from '../../../../../hooks/affine/use-shortcuts';
import {
@@ -41,7 +41,7 @@ const ShortcutsPanel = ({
};
export const Shortcuts = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const markdownShortcutsInfo = useMarkdownShortcuts();
const pageShortcutsInfo = usePageShortcuts();

View File

@@ -9,7 +9,7 @@ import { useWorkspaceInfo } from '@affine/core/hooks/use-workspace-info';
import { AuthService } from '@affine/core/modules/cloud';
import { UserFeatureService } from '@affine/core/modules/cloud/services/user-feature';
import { UNTITLED_WORKSPACE_NAME } from '@affine/env/constant';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { Logo1Icon } from '@blocksuite/icons/rc';
import type { WorkspaceMetadata } from '@toeverything/infra';
import {
@@ -73,7 +73,7 @@ export const UserInfo = ({ onAccountSettingClick, active }: UserInfoProps) => {
};
export const SignInButton = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const [, setAuthModal] = useAtom(authAtom);
return (
@@ -111,7 +111,7 @@ export const SettingSidebar = ({
) => void;
selectedWorkspaceId: string | null;
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
const loginStatus = useLiveData(useService(AuthService).session.status$);
const generalList = useGeneralSettingList();
const onAccountSettingClick = useCallback(() => {
@@ -259,7 +259,7 @@ const subTabConfigs = [
},
] satisfies {
key: WorkspaceSubTab;
title: keyof ReturnType<typeof useAFFiNEI18N>;
title: keyof ReturnType<typeof useI18n>;
}[];
const avatarImageProps = { style: { borderRadius: 2 } };
@@ -280,7 +280,7 @@ const WorkspaceListItem = ({
const name = information?.name ?? UNTITLED_WORKSPACE_NAME;
const currentWorkspace = workspaceService.workspace;
const isCurrent = currentWorkspace.id === meta.id;
const t = useAFFiNEI18N();
const t = useI18n();
useEffect(() => {
userFeatureService.userFeature.revalidate();

View File

@@ -4,8 +4,7 @@ import { ConfirmModal } from '@affine/component/ui/modal';
import { useWorkspaceInfo } from '@affine/core/hooks/use-workspace-info';
import { UNTITLED_WORKSPACE_NAME } from '@affine/env/constant';
import { WorkspaceFlavour } from '@affine/env/workspace';
import { Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { Trans, useI18n } from '@affine/i18n';
import type { WorkspaceMetadata } from '@toeverything/infra';
import { useCallback, useState } from 'react';
@@ -25,7 +24,7 @@ export const WorkspaceDeleteModal = ({
const info = useWorkspaceInfo(workspaceMetadata);
const workspaceName = info?.name ?? UNTITLED_WORKSPACE_NAME;
const allowDelete = deleteStr === workspaceName;
const t = useAFFiNEI18N();
const t = useI18n();
const handleOnEnter = useCallback(() => {
if (allowDelete) {

View File

@@ -3,7 +3,7 @@ import { SettingRow } from '@affine/component/setting-components';
import { ConfirmModal } from '@affine/component/ui/modal';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { WorkspacePermissionService } from '@affine/core/modules/permissions';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { ArrowRightSmallIcon } from '@blocksuite/icons/rc';
import {
GlobalContextService,
@@ -35,7 +35,7 @@ export const DeleteLeaveWorkspace = () => {
WorkspacePermissionService,
WorkspacesService,
});
const t = useAFFiNEI18N();
const t = useI18n();
const workspace = workspaceService.workspace;
const { jumpToSubPath, jumpToIndex } = useNavigateHelper();
// fixme: cloud regression

View File

@@ -3,7 +3,7 @@ import { Button } from '@affine/component/ui/button';
import { useEnableCloud } from '@affine/core/hooks/affine/use-enable-cloud';
import { UNTITLED_WORKSPACE_NAME } from '@affine/env/constant';
import { WorkspaceFlavour } from '@affine/env/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import {
useLiveData,
useService,
@@ -21,7 +21,7 @@ export interface PublishPanelProps {
}
export const EnableCloudPanel = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const confirmEnableCloud = useEnableCloud();
const workspace = useService(WorkspaceService).workspace;

View File

@@ -4,7 +4,7 @@ import { Button } from '@affine/component/ui/button';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { useSystemOnline } from '@affine/core/hooks/use-system-online';
import { apis } from '@affine/electron-api';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import type { Workspace, WorkspaceMetadata } from '@toeverything/infra';
import { useState } from 'react';
@@ -18,7 +18,7 @@ export const ExportPanel = ({
workspace,
}: ExportPanelProps) => {
const workspaceId = workspaceMetadata.id;
const t = useAFFiNEI18N();
const t = useI18n();
const [saving, setSaving] = useState(false);
const isOnline = useSystemOnline();

View File

@@ -6,7 +6,7 @@ import {
import { useWorkspace } from '@affine/core/hooks/use-workspace';
import { useWorkspaceInfo } from '@affine/core/hooks/use-workspace-info';
import { UNTITLED_WORKSPACE_NAME } from '@affine/env/constant';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { ArrowRightSmallIcon } from '@blocksuite/icons/rc';
import { FrameworkScope } from '@toeverything/infra';
import { useCallback } from 'react';
@@ -22,7 +22,7 @@ import type { WorkspaceSettingDetailProps } from './types';
export const WorkspaceSettingDetail = ({
workspaceMetadata,
}: WorkspaceSettingDetailProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
// useWorkspace hook is a vary heavy operation here, but we need syncing name and avatar changes here,
// we don't have a better way to do this now

View File

@@ -26,7 +26,7 @@ import { WorkspaceQuotaService } from '@affine/core/modules/quota';
import { mixpanel } from '@affine/core/utils';
import { WorkspaceFlavour } from '@affine/env/workspace';
import { Permission } from '@affine/graphql';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { MoreVerticalIcon } from '@blocksuite/icons/rc';
import {
useEnsureLiveData,
@@ -58,7 +58,7 @@ import * as style from './style.css';
const COUNT_PER_PAGE = 8;
type OnRevoke = (memberId: string) => void;
const MembersPanelLocal = () => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<Tooltip content={t['com.affine.settings.member-tooltip']()}>
<div className={style.fakeWrapper}>
@@ -105,7 +105,7 @@ export const CloudWorkspaceMembersPanel = () => {
? checkMemberCountLimit(memberCount, workspaceQuota.memberLimit)
: null;
const t = useAFFiNEI18N();
const t = useI18n();
const { invite, isMutating } = useInviteMember(workspace.id);
const revokeMemberPermission = useRevokeMemberPermission(workspace.id);
@@ -258,7 +258,7 @@ export const CloudWorkspaceMembersPanel = () => {
);
};
export const MembersPanelFallback = () => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<>
@@ -282,7 +282,7 @@ const MemberListFallback = ({ memberCount }: { memberCount: number }) => {
}
return 'auto';
}, [memberCount]);
const t = useAFFiNEI18N();
const t = useI18n();
return (
<div
@@ -338,7 +338,7 @@ const MemberItem = ({
currentAccount: AuthAccountInfo;
onRevoke: OnRevoke;
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
const handleRevoke = useCallback(() => {
onRevoke(member.id);

View File

@@ -6,7 +6,7 @@ import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { WorkspacePermissionService } from '@affine/core/modules/permissions';
import { validateAndReduceImage } from '@affine/core/utils/reduce-image';
import { UNTITLED_WORKSPACE_NAME } from '@affine/env/constant';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { CameraIcon } from '@blocksuite/icons/rc';
import { useLiveData, useService, WorkspaceService } from '@toeverything/infra';
import type { KeyboardEvent, MouseEvent } from 'react';
@@ -17,7 +17,7 @@ import * as style from './style.css';
const avatarImageProps = { style: { borderRadius: 8 } };
export const ProfilePanel = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const workspace = useService(WorkspaceService).workspace;
const permissionService = useService(WorkspacePermissionService);

View File

@@ -2,8 +2,7 @@ import { Button, IconButton, Menu } from '@affine/component';
import { SettingHeader } from '@affine/component/setting-components';
import { useWorkspaceInfo } from '@affine/core/hooks/use-workspace-info';
import type { PageInfoCustomPropertyMeta } from '@affine/core/modules/properties/services/schema';
import { Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { Trans, useI18n } from '@affine/i18n';
import {
DeleteIcon,
FilterIcon,
@@ -61,7 +60,7 @@ const EditPropertyButton = ({
}: {
property: PageInfoCustomPropertyMeta;
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
const manager = useContext(managerContext);
const [localPropertyMeta, setLocalPropertyMeta] = useState(() => ({
...property,
@@ -202,7 +201,7 @@ const CustomPropertyRow = ({
}) => {
const Icon = nameToIcon(property.icon, property.type);
const required = property.required;
const t = useAFFiNEI18N();
const t = useI18n();
return (
<div
className={styles.propertyRow}
@@ -272,7 +271,7 @@ const CustomPropertyRowsList = ({
const manager = useContext(managerContext);
const properties = manager.getOrderedPropertiesSchema();
const statistics = manager.getPropertyStatistics();
const t = useAFFiNEI18N();
const t = useI18n();
if (filterMode !== 'all') {
const filtered = properties.filter(property => {
@@ -313,7 +312,7 @@ const CustomPropertyRowsList = ({
};
const WorkspaceSettingPropertiesMain = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const manager = useContext(managerContext);
const [filterMode, setFilterMode] = useState<PropertyFilterMode>('all');
const properties = manager.getOrderedPropertiesSchema();
@@ -390,7 +389,7 @@ export const WorkspaceSettingProperties = ({
}: {
workspaceMetadata: WorkspaceMetadata;
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
const workspace = useWorkspace(workspaceMetadata);
const workspaceInfo = useWorkspaceInfo(workspaceMetadata);
const title = workspaceInfo?.name || 'untitled';

View File

@@ -4,7 +4,7 @@ import { ExportMenuItems } from '@affine/core/components/page-list';
import { useExportPage } from '@affine/core/hooks/affine/use-export-page';
import { useSharingUrl } from '@affine/core/hooks/affine/use-share-url';
import { WorkspaceFlavour } from '@affine/env/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { CopyIcon } from '@blocksuite/icons/rc';
import { DocService, useLiveData, useService } from '@toeverything/infra';
@@ -15,7 +15,7 @@ export const ShareExport = ({
workspaceMetadata: workspace,
currentPage,
}: ShareMenuProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const doc = useService(DocService).doc;
const workspaceId = workspace.id;
const pageId = currentPage.id;

View File

@@ -4,7 +4,7 @@ import { Menu } from '@affine/component/ui/menu';
import { useRegisterCopyLinkCommands } from '@affine/core/hooks/affine/use-register-copy-link-commands';
import { useIsActiveView } from '@affine/core/modules/workbench';
import { WorkspaceFlavour } from '@affine/env/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { WebIcon } from '@blocksuite/icons/rc';
import type { Doc } from '@blocksuite/store';
import type { WorkspaceMetadata } from '@toeverything/infra';
@@ -22,7 +22,7 @@ export interface ShareMenuProps {
}
const ShareMenuContent = (props: ShareMenuProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<div className={styles.containerStyle}>
<div className={styles.headerStyle}>
@@ -41,7 +41,7 @@ const ShareMenuContent = (props: ShareMenuProps) => {
};
const LocalShareMenu = (props: ShareMenuProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<Menu
items={<ShareMenuContent {...props} />}
@@ -65,7 +65,7 @@ const LocalShareMenu = (props: ShareMenuProps) => {
};
const CloudShareMenu = (props: ShareMenuProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
// only enable copy link commands when the view is active and the workspace is cloud
const isActiveView = useIsActiveView();

View File

@@ -16,7 +16,7 @@ import { ShareService } from '@affine/core/modules/share-doc';
import { mixpanel } from '@affine/core/utils';
import { WorkspaceFlavour } from '@affine/env/workspace';
import { PublicPageMode } from '@affine/graphql';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import {
ArrowRightSmallIcon,
SingleSelectSelectSolidIcon,
@@ -36,7 +36,7 @@ import * as styles from './index.css';
import type { ShareMenuProps } from './share-menu';
export const LocalSharePage = (props: ShareMenuProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<div className={styles.localSharePage}>
@@ -95,7 +95,7 @@ export const AffineSharePage = (props: ShareMenuProps) => {
urlType: 'share',
});
const t = useAFFiNEI18N();
const t = useI18n();
const onClickCreateLink = useAsyncCallback(async () => {
try {

View File

@@ -1,6 +1,6 @@
import type { ConfirmModalProps } from '@affine/component/ui/modal';
import { ConfirmModal } from '@affine/component/ui/modal';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useMemo } from 'react';
type SignOutConfirmModalI18NKeys =
@@ -11,7 +11,7 @@ type SignOutConfirmModalI18NKeys =
export const SignOutModal = ({ ...props }: ConfirmModalProps) => {
const { title, description, cancelText, confirmButtonOptions = {} } = props;
const t = useAFFiNEI18N();
const t = useI18n();
const defaultTexts = useMemo(() => {
const getDefaultText = (key: SignOutConfirmModalI18NKeys) => {

View File

@@ -1,10 +1,10 @@
import { OverlayModal } from '@affine/component';
import { openStarAFFiNEModalAtom } from '@affine/core/atoms';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useAtom } from 'jotai';
export const StarAFFiNEModal = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const [open, setOpen] = useAtom(openStarAFFiNEModalAtom);
return (

View File

@@ -1,8 +1,7 @@
import { AuthPageContainer } from '@affine/component/auth-components';
import { Button } from '@affine/component/ui/button';
import { useNavigateHelper } from '@affine/core/hooks/use-navigate-helper';
import { Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { Trans, useI18n } from '@affine/i18n';
import { type ReactNode, useCallback } from 'react';
import { useSearchParams } from 'react-router-dom';
@@ -15,7 +14,7 @@ const UpgradeSuccessLayout = ({
title?: ReactNode;
description?: ReactNode;
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
const [params] = useSearchParams();
const { jumpToIndex, openInApp } = useNavigateHelper();
@@ -56,7 +55,7 @@ const UpgradeSuccessLayout = ({
};
export const CloudUpgradeSuccess = () => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<UpgradeSuccessLayout
title={t['com.affine.payment.upgrade-success-page.title']()}
@@ -66,7 +65,7 @@ export const CloudUpgradeSuccess = () => {
};
export const AIUpgradeSuccess = () => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<UpgradeSuccessLayout

View File

@@ -1,8 +1,7 @@
import { Empty } from '@affine/component';
import type { ModalProps } from '@affine/component/ui/modal';
import { Modal } from '@affine/component/ui/modal';
import { Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { Trans, useI18n } from '@affine/i18n';
import { useCallback } from 'react';
import {
@@ -13,7 +12,7 @@ import {
} from './style';
export const TmpDisableAffineCloudModal = (props: ModalProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const onClose = useCallback(() => {
props.onOpenChange?.(false);
}, [props]);

View File

@@ -1,4 +1,4 @@
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { PlusIcon } from '@blocksuite/icons/rc';
import clsx from 'clsx';
import type React from 'react';
@@ -17,7 +17,7 @@ export function AddPageButton({
className,
style,
}: AddPageButtonProps) {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<button

View File

@@ -1,7 +1,7 @@
import { Tooltip } from '@affine/component';
import { popupWindow } from '@affine/core/utils';
import { Unreachable } from '@affine/env/constant';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { CloseIcon, NewIcon, ResetIcon } from '@blocksuite/icons/rc';
import clsx from 'clsx';
import { useCallback, useMemo } from 'react';
@@ -40,7 +40,7 @@ interface ButtonContentProps {
}
function DownloadUpdate({ updateAvailable }: ButtonContentProps) {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<div className={styles.installLabel}>
<span className={styles.ellipsisTextOverflow}>
@@ -52,7 +52,7 @@ function DownloadUpdate({ updateAvailable }: ButtonContentProps) {
}
function UpdateReady({ updateAvailable, appQuitting }: ButtonContentProps) {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<div className={styles.updateAvailableWrapper}>
<div className={styles.installLabelNormal}>
@@ -76,7 +76,7 @@ function DownloadingUpdate({
updateAvailable,
downloadProgress,
}: ButtonContentProps) {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<div className={clsx([styles.updateAvailableWrapper])}>
<div className={clsx([styles.installLabelNormal])}>
@@ -97,7 +97,7 @@ function DownloadingUpdate({
}
function OpenDownloadPage({ updateAvailable }: ButtonContentProps) {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<>
<div className={styles.installLabelNormal}>
@@ -117,7 +117,7 @@ function OpenDownloadPage({ updateAvailable }: ButtonContentProps) {
}
function WhatsNew({ onDismissChangelog }: ButtonContentProps) {
const t = useAFFiNEI18N();
const t = useI18n();
const onClickClose: React.MouseEventHandler = useCallback(
e => {
onDismissChangelog();

View File

@@ -1,4 +1,4 @@
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { SearchIcon } from '@blocksuite/icons/rc';
import clsx from 'clsx';
import type { HTMLAttributes } from 'react';
@@ -12,7 +12,7 @@ interface QuickSearchInputProps extends HTMLAttributes<HTMLDivElement> {
// Although it is called an input, it is actually a button.
export function QuickSearchInput({ onClick, ...props }: QuickSearchInputProps) {
const t = useAFFiNEI18N();
const t = useI18n();
const isMac = environment.isBrowser && environment.isMacOs;
return (

View File

@@ -1,5 +1,5 @@
import { IconButton, Tooltip } from '@affine/component';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { SidebarIcon } from '@blocksuite/icons/rc';
import clsx from 'clsx';
import { useAtom } from 'jotai';
@@ -15,7 +15,7 @@ export const SidebarSwitch = ({
className?: string;
}) => {
const [open, setOpen] = useAtom(appSidebarOpenAtom);
const t = useAFFiNEI18N();
const t = useI18n();
const tooltipContent = open
? t['com.affine.sidebarSwitch.collapse']()
: t['com.affine.sidebarSwitch.expand']();

View File

@@ -1,5 +1,5 @@
import { useJournalInfoHelper } from '@affine/core/hooks/use-journal';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import type { Doc } from '@blocksuite/store';
import * as styles from './styles.css';
@@ -7,7 +7,7 @@ import * as styles from './styles.css';
export const BlocksuiteEditorJournalDocTitle = ({ page }: { page: Doc }) => {
const { localizedJournalDate, isTodayJournal, journalDate } =
useJournalInfoHelper(page.collection, page.id);
const t = useAFFiNEI18N();
const t = useI18n();
// TODO: i18n
const day = journalDate?.format('dddd') ?? null;

View File

@@ -1,7 +1,7 @@
import { FavoriteTag } from '@affine/core/components/page-list';
import { FavoriteItemsAdapter } from '@affine/core/modules/properties';
import { toast } from '@affine/core/utils';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { assertExists } from '@blocksuite/global/utils';
import { useLiveData, useService, WorkspaceService } from '@toeverything/infra';
import { useCallback } from 'react';
@@ -11,7 +11,7 @@ export interface FavoriteButtonProps {
}
export const useFavorite = (pageId: string) => {
const t = useAFFiNEI18N();
const t = useI18n();
const workspace = useService(WorkspaceService).workspace;
const docCollection = workspace.docCollection;
const currentPage = docCollection.getDoc(pageId);

View File

@@ -1,7 +1,7 @@
import { Button } from '@affine/component';
import { useJournalRouteHelper } from '@affine/core/hooks/use-journal';
import type { DocCollection } from '@affine/core/shared';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useCallback } from 'react';
export interface JournalTodayButtonProps {
@@ -11,7 +11,7 @@ export interface JournalTodayButtonProps {
export const JournalTodayButton = ({
docCollection,
}: JournalTodayButtonProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const journalHelper = useJournalRouteHelper(docCollection);
const onToday = useCallback(() => {

View File

@@ -14,7 +14,7 @@ import { useTrashModalHelper } from '@affine/core/hooks/affine/use-trash-modal-h
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { mixpanel } from '@affine/core/utils';
import { WorkspaceFlavour } from '@affine/env/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import {
DuplicateIcon,
EdgelessIcon,
@@ -49,7 +49,7 @@ export const PageHeaderMenuButton = ({
pageId,
isJournal,
}: PageMenuProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const workspace = useService(WorkspaceService).workspace;
const docCollection = workspace.docCollection;

View File

@@ -1,6 +1,6 @@
import { Tooltip } from '@affine/component/ui/tooltip';
import { useBlockSuiteDocMeta } from '@affine/core/hooks/use-block-suite-page-meta';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import {
type DocMode,
DocService,
@@ -24,7 +24,7 @@ export type EditorModeSwitchProps = {
publicMode?: DocMode;
};
const TooltipContent = () => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<>
{t['Switch']()}
@@ -41,7 +41,7 @@ export const EditorModeSwitch = ({
isPublic,
publicMode,
}: EditorModeSwitchProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const pageMeta = useBlockSuiteDocMeta(docCollection).find(
meta => meta.id === pageId
);

Some files were not shown because too many files have changed in this diff Show More