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
@@ -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 () => {
@@ -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();
@@ -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
@@ -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(
@@ -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();
@@ -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$);
@@ -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);
@@ -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>>();
@@ -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(() => {
@@ -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(() => {
@@ -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();
@@ -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(
@@ -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('');
@@ -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);
@@ -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
@@ -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);
@@ -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);
@@ -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 (
@@ -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);
@@ -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);
@@ -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}>
@@ -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']()}
@@ -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
@@ -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 => {
@@ -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));
@@ -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);
@@ -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);
@@ -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);
@@ -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);
@@ -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(
@@ -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();
@@ -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(() => {
@@ -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;
@@ -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,
@@ -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();
@@ -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}>
@@ -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 (
<>
@@ -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,
@@ -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;
@@ -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(() => {
@@ -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;
@@ -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) {
@@ -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);
@@ -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 (
@@ -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,
@@ -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}>
@@ -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);
@@ -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(() => {
@@ -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);
@@ -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();
@@ -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();
@@ -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) {
@@ -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
@@ -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;
@@ -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();
@@ -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
@@ -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);
@@ -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);
@@ -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';
@@ -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;
@@ -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();
@@ -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 {
@@ -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) => {
@@ -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 (
@@ -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
@@ -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]);
@@ -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
@@ -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();
@@ -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 (
@@ -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']();
@@ -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;
@@ -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);
@@ -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(() => {
@@ -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;
@@ -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
);
@@ -1,6 +1,6 @@
import { Button } from '@affine/component/ui/button';
import { useNavigateHelper } from '@affine/core/hooks/use-navigate-helper';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import {
useLiveData,
useService,
@@ -20,7 +20,7 @@ export const AuthenticatedItem = ({
const workspacesService = useService(WorkspacesService);
const workspaces = useLiveData(workspacesService.list.workspaces$);
const isMember = workspaces?.some(workspace => workspace.id === workspaceId);
const t = useAFFiNEI18N();
const t = useI18n();
const { jumpToPage } = useNavigateHelper();
const handleEdit = useCallback(() => {
@@ -1,6 +1,6 @@
import { Button } from '@affine/component/ui/button';
import { useActiveBlocksuiteEditor } from '@affine/core/hooks/use-block-suite-editor';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import type { EdgelessRootService } from '@blocksuite/blocks';
import { PresentationIcon } from '@blocksuite/icons/rc';
import { useCallback, useEffect, useState } from 'react';
@@ -8,7 +8,7 @@ import { useCallback, useEffect, useState } from 'react';
import * as styles from './styles.css';
export const PresentButton = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const [isPresent, setIsPresent] = useState(false);
const [editor] = useActiveBlocksuiteEditor();
@@ -6,7 +6,7 @@ import {
MenuSeparator,
} from '@affine/component/ui/menu';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { SignOutIcon } from '@blocksuite/icons/rc';
import { useLiveData, useService } from '@toeverything/infra';
import { useEffect, useMemo } from 'react';
@@ -54,7 +54,7 @@ const UserInfo = () => {
export const PublishPageUserAvatar = () => {
const authService = useService(AuthService);
const user = useLiveData(authService.session.account$);
const t = useAFFiNEI18N();
const t = useI18n();
const handleSignOut = useAsyncCallback(async () => {
await authService.signOut();
@@ -1,5 +1,5 @@
import { Button } from '@affine/component';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import type { ReactElement } from 'react';
import * as styles from './collection-list-header.css';
@@ -11,7 +11,7 @@ export const CollectionListHeader = ({
node: ReactElement | null;
onCreate: () => void;
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<>
@@ -1,7 +1,7 @@
import { Checkbox } from '@affine/component';
import { getDNDId } from '@affine/core/hooks/affine/use-global-dnd-helper';
import { WorkbenchLink } from '@affine/core/modules/workbench';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useDraggable } from '@dnd-kit/core';
import type { PropsWithChildren } from 'react';
import { useCallback, useMemo } from 'react';
@@ -19,7 +19,7 @@ const ListTitleCell = ({
title,
preview,
}: Pick<PageListItemProps, 'title' | 'preview'>) => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<div data-testid="page-list-item-title" className={styles.titleCell}>
<div
@@ -1,6 +1,6 @@
import type { IconButtonProps } from '@affine/component';
import { IconButton, Tooltip } from '@affine/component';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { FavoritedIcon, FavoriteIcon } from '@blocksuite/icons/rc';
import Lottie from 'lottie-react';
import { forwardRef, useCallback, useState } from 'react';
@@ -14,7 +14,7 @@ export const FavoriteTag = forwardRef<
} & Omit<IconButtonProps, 'children'>
>(({ active, onClick, ...props }, ref) => {
const [playAnimation, setPlayAnimation] = useState(false);
const t = useAFFiNEI18N();
const t = useI18n();
const handleClick = useCallback(
(e: React.MouseEvent<HTMLButtonElement>) => {
e.stopPropagation();
@@ -1,7 +1,7 @@
import { DropdownButton, Menu } from '@affine/component';
import { BlockCard } from '@affine/component/card/block-card';
import { mixpanel } from '@affine/core/utils';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { EdgelessIcon, ImportIcon, PageIcon } from '@blocksuite/icons/rc';
import type { PropsWithChildren } from 'react';
import { useCallback, useState } from 'react';
@@ -20,7 +20,7 @@ export const CreateNewPagePopup = ({
createNewEdgeless,
importFile,
}: NewPageButtonProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<div
style={{
@@ -5,7 +5,7 @@ import {
MenuSeparator,
MenuSub,
} from '@affine/component';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { ArrowDownSmallIcon, DoneIcon } from '@blocksuite/icons/rc';
import { useCallback, useMemo } from 'react';
@@ -19,7 +19,7 @@ type GroupOption = {
};
export const PageDisplayMenu = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const [workspaceProperties, setProperties] = useAllDocDisplayProperties();
const handleSelect = useCallback(
(value: PageGroupByType) => {
@@ -11,7 +11,7 @@ import type { Tag } from '@affine/core/modules/tag';
import { TagService } from '@affine/core/modules/tag';
import { mixpanel } from '@affine/core/utils';
import type { Collection } from '@affine/env/filter';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import {
ArrowDownSmallIcon,
SearchIcon,
@@ -37,7 +37,7 @@ import * as styles from './page-list-header.css';
import { PageListNewPageButton } from './page-list-new-page-button';
export const PageListHeader = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const workspace = useService(WorkspaceService).workspace;
const { importFile, createEdgeless, createPage } = usePageHelper(
workspace.docCollection
@@ -93,7 +93,7 @@ export const CollectionPageListHeader = ({
collection: Collection;
workspaceId: string;
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
const { jumpToCollections } = useNavigateHelper();
const handleJumpToCollections = useCallback(() => {
@@ -186,7 +186,7 @@ export const TagPageListHeader = ({
const tagColor = useLiveData(tag.color$);
const tagTitle = useLiveData(tag.value$);
const t = useAFFiNEI18N();
const t = useI18n();
const { jumpToTags, jumpToCollection } = useNavigateHelper();
const collectionService = useService(CollectionService);
const [openMenu, setOpenMenu] = useState(false);
@@ -269,7 +269,7 @@ interface SwitchTagProps {
}
export const SwitchTag = ({ onClick }: SwitchTagProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const [inputValue, setInputValue] = useState('');
const tagList = useService(TagService).tagList;
const filteredTags = useLiveData(
@@ -4,8 +4,7 @@ import { useBlockSuiteDocMeta } from '@affine/core/hooks/use-block-suite-page-me
import { CollectionService } from '@affine/core/modules/collection';
import type { Tag } from '@affine/core/modules/tag';
import type { Collection, Filter } from '@affine/env/filter';
import { Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { Trans, useI18n } from '@affine/i18n';
import type { DocMeta } from '@blocksuite/store';
import { useService, WorkspaceService } from '@toeverything/infra';
import { useCallback, useMemo, useRef, useState } from 'react';
@@ -28,7 +27,7 @@ import {
} from './page-list-header';
const usePageOperationsRenderer = () => {
const t = useAFFiNEI18N();
const t = useI18n();
const collectionService = useService(CollectionService);
const removeFromAllowList = useCallback(
(id: string) => {
@@ -1,6 +1,6 @@
import type { PopoverProps } from '@affine/component';
import { DatePicker, Popover } from '@affine/component';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import dayjs from 'dayjs';
import { useCallback, useState } from 'react';
@@ -17,7 +17,7 @@ export const DateSelect = ({
value: number;
onChange: (value: number) => void;
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
const [open, setOpen] = useState(false);
const onDateChange = useCallback(
@@ -1,6 +1,6 @@
import { Button, IconButton, Menu } from '@affine/component';
import type { Filter, PropertiesMeta } from '@affine/env/filter';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { CloseIcon, PlusIcon } from '@blocksuite/icons/rc';
import { Condition } from './condition';
@@ -16,7 +16,7 @@ export const FilterList = ({
onChange: (value: Filter[]) => void;
propertiesMeta: PropertiesMeta;
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<div
style={{
@@ -1,5 +1,5 @@
import { Tooltip } from '@affine/component';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { ellipsisTextStyle } from './index.css';
type FilterTagProps = {
@@ -7,7 +7,7 @@ type FilterTagProps = {
};
const useFilterTag = ({ name }: FilterTagProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
switch (name) {
case 'Created':
return t['Created']();
@@ -1,5 +1,5 @@
import { Menu, MenuItem, Scrollable, Tooltip } from '@affine/component';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import clsx from 'clsx';
import type { MouseEvent } from 'react';
import { useMemo } from 'react';
@@ -18,7 +18,7 @@ export const MultiSelect = ({
value: string;
}[];
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
const optionMap = useMemo(
() => Object.fromEntries(options.map(v => [v.value, v])),
[options]
@@ -5,7 +5,7 @@ import type {
PropertiesMeta,
VariableMap,
} from '@affine/env/filter';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import dayjs from 'dayjs';
import type { ReactNode } from 'react';
@@ -81,7 +81,7 @@ export const VariableSelect = ({
onSelect: (value: Filter) => void;
propertiesMeta: PropertiesMeta;
}) => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<div data-testid="variable-select">
<div className={styles.variableSelectTitleStyle}>
@@ -1,7 +1,7 @@
import { FavoriteItemsAdapter } from '@affine/core/modules/properties';
import type { Tag } from '@affine/core/modules/tag';
import { TagService } from '@affine/core/modules/tag';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { FavoritedIcon, FavoriteIcon } from '@blocksuite/icons/rc';
import type { DocMeta } from '@blocksuite/store';
import { LiveData, useLiveData, useService } from '@toeverything/infra';
@@ -39,7 +39,7 @@ const GroupLabel = ({
export const useDateGroupDefinitions = <T extends ListItem>(
key: DateKey
): ItemGroupDefinition<T>[] => {
const t = useAFFiNEI18N();
const t = useI18n();
return useMemo(
() => [
{
@@ -139,7 +139,7 @@ export const useTagGroupDefinitions = (): ItemGroupDefinition<ListItem>[] => {
);
const tags = useLiveData(sortedTagsLiveData$);
const t = useAFFiNEI18N();
const t = useI18n();
const untagged = useMemo(
() => ({
@@ -173,7 +173,7 @@ export const useTagGroupDefinitions = (): ItemGroupDefinition<ListItem>[] => {
export const useFavoriteGroupDefinitions = <
T extends ListItem,
>(): ItemGroupDefinition<T>[] => {
const t = useAFFiNEI18N();
const t = useI18n();
const favAdapter = useService(FavoriteItemsAdapter);
const favourites = useLiveData(favAdapter.favorites$);
return useMemo(
@@ -14,7 +14,7 @@ import { FavoriteItemsAdapter } from '@affine/core/modules/properties';
import { WorkbenchService } from '@affine/core/modules/workbench';
import { mixpanel } from '@affine/core/utils';
import type { Collection, DeleteCollectionInfo } from '@affine/env/filter';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import {
DeleteIcon,
DeletePermanentlyIcon,
@@ -57,7 +57,7 @@ export const PageOperationCell = ({
page,
onRemoveFromAllowList,
}: PageOperationCellProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const currentWorkspace = useService(WorkspaceService).workspace;
const { appSettings } = useAppSettingHelper();
const { setTrashModal } = useTrashModalHelper(currentWorkspace.docCollection);
@@ -233,7 +233,7 @@ export const TrashOperationCell = ({
onPermanentlyDeletePage,
onRestorePage,
}: TrashOperationCellProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const { openConfirmModal } = useConfirmModal();
const onConfirmPermanentlyDelete = useCallback(() => {
@@ -292,7 +292,7 @@ export const CollectionOperationCell = ({
service,
info,
}: CollectionOperationCellProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const favAdapter = useService(FavoriteItemsAdapter);
const { createPage } = usePageHelper(config.docCollection);
@@ -454,7 +454,7 @@ export const TagOperationCell = ({
tag,
onTagDelete,
}: TagOperationCellProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const [open, setOpen] = useState(false);
const handleDelete = useCallback(() => {
@@ -1,11 +1,11 @@
import type { MenuItemProps } from '@affine/component';
import { MenuIcon, MenuItem } from '@affine/component';
import { PublicLinkDisableModal } from '@affine/component/disable-public-link';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { ShareIcon } from '@blocksuite/icons/rc';
export const DisablePublicSharing = (props: MenuItemProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<MenuItem
type="danger"
@@ -1,5 +1,5 @@
import { MenuIcon, MenuItem, MenuSub } from '@affine/component';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import {
ExportIcon,
ExportToHtmlIcon,
@@ -51,7 +51,7 @@ export const ExportMenuItems = ({
className = transitionStyle,
pageMode = 'page',
}: ExportProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const itemMap = useMemo(
() => [
{
@@ -107,7 +107,7 @@ export const ExportMenuItems = ({
};
export const Export = ({ exportHandler, className, pageMode }: ExportProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const items = (
<ExportMenuItems
exportHandler={exportHandler}
@@ -1,10 +1,10 @@
import type { ConfirmModalProps, MenuItemProps } from '@affine/component';
import { ConfirmModal, MenuIcon, MenuItem } from '@affine/component';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { DeleteIcon } from '@blocksuite/icons/rc';
export const MoveToTrash = (props: MenuItemProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<MenuItem
@@ -27,7 +27,7 @@ const MoveToTrashConfirm = ({
}: {
titles: string[];
} & ConfirmModalProps) => {
const t = useAFFiNEI18N();
const t = useI18n();
const multiple = titles.length > 1;
const title = multiple
? t['com.affine.moveToTrash.confirmModal.title.multiple']({
@@ -1,6 +1,6 @@
import { useJournalInfoHelper } from '@affine/core/hooks/use-journal';
import type { Tag } from '@affine/env/filter';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { assertExists } from '@blocksuite/global/utils';
import {
EdgelessIcon,
@@ -82,7 +82,7 @@ export const ItemGroupHeader = <T extends ListItem>({
selectionState.onSelectedIdsChange?.(newSelectedPageIds);
}, [setSelectionActive, selectionState, allSelected, items]);
const t = useAFFiNEI18N();
const t = useI18n();
return label ? (
<div
@@ -148,7 +148,7 @@ export const ItemGroup = <T extends ListItem>({
...items.map(item => item.id),
]);
}, [items, selectionState]);
const t = useAFFiNEI18N();
const t = useI18n();
return (
<Collapsible.Root
data-testid="page-list-group"
@@ -284,7 +284,7 @@ function tagIdToTagOption(
const PageTitle = ({ id }: { id: string }) => {
const doc = useLiveData(useService(DocsService).list.doc$(id));
const title = useLiveData(doc?.title$);
const t = useAFFiNEI18N();
const t = useI18n();
return title || t['Untitled']();
};
@@ -1,6 +1,6 @@
import type { CheckboxProps } from '@affine/component';
import { Checkbox } from '@affine/component';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { MultiSelectIcon } from '@blocksuite/icons/rc';
import clsx from 'clsx';
import { selectAtom } from 'jotai/utils';
@@ -72,7 +72,7 @@ const ListHeaderCheckbox = () => {
};
export const ListHeaderTitleCell = () => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<div className={styles.headerTitleCell}>
<ListHeaderCheckbox />
@@ -1,6 +1,6 @@
import { Button, Input, Menu, toast } from '@affine/component';
import { TagService } from '@affine/core/modules/tag';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useLiveData, useService } from '@toeverything/infra';
import clsx from 'clsx';
import { useCallback, useEffect, useMemo, useState } from 'react';
@@ -35,7 +35,7 @@ export const CreateOrEditTag = ({
const tagList = useService(TagService).tagList;
const tagOptions = useLiveData(tagList.tagMetas$);
const tag = useLiveData(tagList.tagByTagId$(tagMeta?.id));
const t = useAFFiNEI18N();
const t = useI18n();
const [menuOpen, setMenuOpen] = useState(false);
const [tagName, setTagName] = useState(tagMeta?.title || '');
@@ -1,10 +1,10 @@
import { Button } from '@affine/component';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import * as styles from './tag-list-header.css';
export const TagListHeader = ({ onOpen }: { onOpen: () => void }) => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<div className={styles.tagListHeader}>
<div className={styles.tagListHeaderTitle}>{t['Tags']()}</div>
@@ -1,7 +1,7 @@
import { Checkbox } from '@affine/component';
import { getDNDId } from '@affine/core/hooks/affine/use-global-dnd-helper';
import { WorkbenchLink } from '@affine/core/modules/workbench';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useI18n } from '@affine/i18n';
import { useDraggable } from '@dnd-kit/core';
import type { PropsWithChildren } from 'react';
import { useCallback, useMemo } from 'react';
@@ -15,7 +15,7 @@ const TagListTitleCell = ({
title,
pageCount,
}: Pick<TagListItemProps, 'title' | 'pageCount'>) => {
const t = useAFFiNEI18N();
const t = useI18n();
return (
<div data-testid="tag-list-item-title" className={styles.titleCell}>
<div

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