mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-24 22:09:08 +08:00
feat(i18n): static type on i18n (#2225)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { IconButton, Modal, ModalWrapper } from '@affine/component';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { CloseIcon } from '@blocksuite/icons';
|
||||
import type React from 'react';
|
||||
|
||||
@@ -17,7 +17,7 @@ export const EnableAffineCloudModal: React.FC<EnableAffineCloudModalProps> = ({
|
||||
open,
|
||||
onClose,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
const user = useCurrentUser();
|
||||
|
||||
return (
|
||||
@@ -33,8 +33,8 @@ export const EnableAffineCloudModal: React.FC<EnableAffineCloudModalProps> = ({
|
||||
</IconButton>
|
||||
</Header>
|
||||
<Content>
|
||||
<ContentTitle>{t('Enable AFFiNE Cloud')}?</ContentTitle>
|
||||
<StyleTips>{t('Enable AFFiNE Cloud Description')}</StyleTips>
|
||||
<ContentTitle>{t['Enable AFFiNE Cloud']()}?</ContentTitle>
|
||||
<StyleTips>{t['Enable AFFiNE Cloud Description']()}</StyleTips>
|
||||
{/* <StyleTips>{t('Retain cached cloud data')}</StyleTips> */}
|
||||
<div>
|
||||
<StyleButton
|
||||
@@ -45,7 +45,7 @@ export const EnableAffineCloudModal: React.FC<EnableAffineCloudModalProps> = ({
|
||||
onConfirm();
|
||||
}}
|
||||
>
|
||||
{user ? t('Enable') : t('Sign in and Enable')}
|
||||
{user ? t.Enable() : t['Sign in and Enable']()}
|
||||
</StyleButton>
|
||||
<StyleButton
|
||||
shape="round"
|
||||
@@ -53,7 +53,7 @@ export const EnableAffineCloudModal: React.FC<EnableAffineCloudModalProps> = ({
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
{t('Not now')}
|
||||
{t['Not now']()}
|
||||
</StyleButton>
|
||||
</div>
|
||||
</Content>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MenuItem } from '@affine/component';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { CopyIcon } from '@blocksuite/icons';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
@@ -8,11 +8,11 @@ import { toast } from '../../../utils';
|
||||
import type { CommonMenuItemProps } from './types';
|
||||
|
||||
export const CopyLink = ({ onItemClick, onSelect }: CommonMenuItemProps) => {
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
|
||||
const copyUrl = useCallback(() => {
|
||||
navigator.clipboard.writeText(window.location.href);
|
||||
toast(t('Copied link to clipboard'));
|
||||
toast(t['Copied link to clipboard']());
|
||||
}, [t]);
|
||||
|
||||
return (
|
||||
@@ -25,7 +25,7 @@ export const CopyLink = ({ onItemClick, onSelect }: CommonMenuItemProps) => {
|
||||
}}
|
||||
icon={<CopyIcon />}
|
||||
>
|
||||
{t('Copy Link')}
|
||||
{t['Copy Link']()}
|
||||
</MenuItem>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { MenuItem, styled } from '@affine/component';
|
||||
import type { PublicLinkDisableProps } from '@affine/component/share-menu';
|
||||
import { PublicLinkDisableModal } from '@affine/component/share-menu';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { ShareIcon } from '@blocksuite/icons';
|
||||
|
||||
import type { CommonMenuItemProps } from './types';
|
||||
@@ -29,7 +29,7 @@ export const DisablePublicSharing = ({
|
||||
onItemClick,
|
||||
testId,
|
||||
}: CommonMenuItemProps) => {
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
return (
|
||||
<>
|
||||
<StyledMenuItem
|
||||
@@ -41,7 +41,7 @@ export const DisablePublicSharing = ({
|
||||
style={{ color: 'red' }}
|
||||
icon={<ShareIcon />}
|
||||
>
|
||||
{t('Disable Public Sharing')}
|
||||
{t['Disable Public Sharing']()}
|
||||
</StyledMenuItem>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Menu, MenuItem } from '@affine/component';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { ContentParser } from '@blocksuite/blocks/content-parser';
|
||||
import {
|
||||
ArrowRightSmallIcon,
|
||||
@@ -15,7 +15,7 @@ export const Export = ({
|
||||
onSelect,
|
||||
onItemClick,
|
||||
}: CommonMenuItemProps<{ type: 'markdown' | 'html' }>) => {
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
const contentParserRef = useRef<ContentParser>();
|
||||
return (
|
||||
<Menu
|
||||
@@ -37,7 +37,7 @@ export const Export = ({
|
||||
}}
|
||||
icon={<ExportToHtmlIcon />}
|
||||
>
|
||||
{t('Export to HTML')}
|
||||
{t['Export to HTML']()}
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
data-testid="export-to-markdown"
|
||||
@@ -52,7 +52,7 @@ export const Export = ({
|
||||
}}
|
||||
icon={<ExportToMarkdownIcon />}
|
||||
>
|
||||
{t('Export to Markdown')}
|
||||
{t['Export to Markdown']()}
|
||||
</MenuItem>
|
||||
</>
|
||||
}
|
||||
@@ -66,7 +66,7 @@ export const Export = ({
|
||||
onItemClick?.();
|
||||
}}
|
||||
>
|
||||
{t('Export')}
|
||||
{t.Export()}
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MenuItem } from '@affine/component';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { ArrowRightSmallIcon, MoveToIcon } from '@blocksuite/icons';
|
||||
import type { PageMeta } from '@blocksuite/store';
|
||||
import { useRef, useState } from 'react';
|
||||
@@ -27,7 +27,7 @@ export const MoveTo = ({
|
||||
onSelect,
|
||||
onItemClick,
|
||||
}: MoveToProps) => {
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
const ref = useRef<HTMLButtonElement>(null);
|
||||
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
|
||||
const open = anchorEl !== null;
|
||||
@@ -44,7 +44,7 @@ export const MoveTo = ({
|
||||
endIcon={<ArrowRightSmallIcon />}
|
||||
data-testid="move-to-menu-item"
|
||||
>
|
||||
{t('Move to')}
|
||||
{t['Move to']()}
|
||||
</MenuItem>
|
||||
<PinboardMenu
|
||||
anchorEl={anchorEl}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { ConfirmProps } from '@affine/component';
|
||||
import { Confirm, MenuItem } from '@affine/component';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { DeleteTemporarilyIcon } from '@blocksuite/icons';
|
||||
import type { PageMeta } from '@blocksuite/store';
|
||||
|
||||
@@ -11,7 +11,7 @@ export const MoveToTrash = ({
|
||||
onItemClick,
|
||||
testId,
|
||||
}: CommonMenuItemProps) => {
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -23,7 +23,7 @@ export const MoveToTrash = ({
|
||||
}}
|
||||
icon={<DeleteTemporarilyIcon />}
|
||||
>
|
||||
{t('Move to Trash')}
|
||||
{t['Move to Trash']()}
|
||||
</MenuItem>
|
||||
</>
|
||||
);
|
||||
@@ -35,15 +35,15 @@ const ConfirmModal = ({
|
||||
}: {
|
||||
meta: PageMeta;
|
||||
} & ConfirmProps) => {
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
|
||||
return (
|
||||
<Confirm
|
||||
title={t('Delete page?')}
|
||||
content={t('will be moved to Trash', {
|
||||
title={t['Delete page?']()}
|
||||
content={t['will be moved to Trash']({
|
||||
title: meta.title || 'Untitled',
|
||||
})}
|
||||
confirmText={t('Delete')}
|
||||
confirmText={t.Delete()}
|
||||
confirmType="danger"
|
||||
{...confirmModalProps}
|
||||
/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { FlexWrapper } from '@affine/component';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { EdgelessIcon, PageIcon } from '@blocksuite/icons';
|
||||
import type { PageMeta } from '@blocksuite/store';
|
||||
import { useAtomValue } from 'jotai';
|
||||
@@ -16,14 +16,14 @@ export const SearchContent = ({
|
||||
results: PageMeta[];
|
||||
onClick?: (dropId: string) => void;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
const record = useAtomValue(workspacePreferredModeAtom);
|
||||
|
||||
if (results.length) {
|
||||
return (
|
||||
<>
|
||||
<StyledMenuSubTitle>
|
||||
{t('Find results', { number: results.length })}
|
||||
{t['Find results']({ number: `${results.length}` })}
|
||||
</StyledMenuSubTitle>
|
||||
{results.map(meta => {
|
||||
return (
|
||||
@@ -45,7 +45,7 @@ export const SearchContent = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
<StyledMenuSubTitle>{t('Find 0 result')}</StyledMenuSubTitle>
|
||||
<StyledMenuSubTitle>{t['Find 0 result']()}</StyledMenuSubTitle>
|
||||
<FlexWrapper
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { PureMenuProps } from '@affine/component';
|
||||
import { Input, PureMenu, TreeView } from '@affine/component';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { RemoveIcon, SearchIcon } from '@blocksuite/icons';
|
||||
import type { PageMeta } from '@blocksuite/store';
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
@@ -40,7 +40,7 @@ export const PinboardMenu = ({
|
||||
() => propsMetas.filter(m => m.id !== currentMeta.id),
|
||||
[currentMeta.id, propsMetas]
|
||||
);
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
const [query, setQuery] = useState('');
|
||||
const isSearching = query.length > 0;
|
||||
|
||||
@@ -92,7 +92,7 @@ export const PinboardMenu = ({
|
||||
<Input
|
||||
value={query}
|
||||
onChange={setQuery}
|
||||
placeholder={t('Move page to...')}
|
||||
placeholder={t['Move page to...']()}
|
||||
height={32}
|
||||
noBorder={true}
|
||||
onClick={e => e.stopPropagation()}
|
||||
@@ -121,9 +121,9 @@ export const PinboardMenu = ({
|
||||
}}
|
||||
>
|
||||
<RemoveIcon />
|
||||
{t('Remove from Pinboard')}
|
||||
{t['Remove from Pivots']()}
|
||||
</StyledPinboard>
|
||||
<p>{t('RFP')}</p>
|
||||
<p>{t['RFP']()}</p>
|
||||
</StyledMenuFooter>
|
||||
)}
|
||||
</PureMenu>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
|
||||
import { StyledPinboard } from '../styles';
|
||||
|
||||
export const EmptyItem = () => {
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
return (
|
||||
<StyledPinboard disable={true} textWrap={true}>
|
||||
{t('Organize pages to build knowledge')}
|
||||
{t['Organize pages to build knowledge']()}
|
||||
</StyledPinboard>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MenuItem, MuiClickAwayListener, PureMenu } from '@affine/component';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import {
|
||||
MoreVerticalIcon,
|
||||
MoveToIcon,
|
||||
@@ -39,7 +39,7 @@ export const OperationButton = ({
|
||||
onMenuClose,
|
||||
onRename,
|
||||
}: OperationButtonProps) => {
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
|
||||
const timer = useRef<ReturnType<typeof setTimeout>>();
|
||||
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
|
||||
@@ -100,7 +100,7 @@ export const OperationButton = ({
|
||||
}}
|
||||
icon={<PlusIcon />}
|
||||
>
|
||||
{t('Add a subpage inside')}
|
||||
{t['Add a subpage inside']()}
|
||||
</MenuItem>
|
||||
{!isRoot && (
|
||||
<MenuItem
|
||||
@@ -111,7 +111,7 @@ export const OperationButton = ({
|
||||
}}
|
||||
icon={<MoveToIcon />}
|
||||
>
|
||||
{t('Move to')}
|
||||
{t['Move to']()}
|
||||
</MenuItem>
|
||||
)}
|
||||
{!isRoot && (
|
||||
@@ -124,7 +124,7 @@ export const OperationButton = ({
|
||||
}}
|
||||
icon={<PenIcon />}
|
||||
>
|
||||
{t('Rename')}
|
||||
{t['Rename']()}
|
||||
</MenuItem>
|
||||
)}
|
||||
{!isRoot && (
|
||||
@@ -154,7 +154,7 @@ export const OperationButton = ({
|
||||
open={confirmModalOpen}
|
||||
meta={currentMeta}
|
||||
onConfirm={() => {
|
||||
toast(t('Moved to Trash'));
|
||||
toast(t['Moved to Trash']());
|
||||
removeToTrash(currentMeta.id);
|
||||
onDelete();
|
||||
}}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Tooltip } from '@affine/component';
|
||||
import { appSidebarOpenAtom } from '@affine/component/app-sidebar';
|
||||
import { getEnvironment } from '@affine/env';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { useAtom } from 'jotai';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
@@ -21,7 +21,7 @@ export const SidebarSwitch = ({
|
||||
}: SidebarSwitchProps) => {
|
||||
const [open, setOpen] = useAtom(appSidebarOpenAtom);
|
||||
const [tooltipVisible, setTooltipVisible] = useState(false);
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
const checkIsMac = () => {
|
||||
const env = getEnvironment();
|
||||
return env.isBrowser && env.isMacOs;
|
||||
@@ -34,7 +34,7 @@ export const SidebarSwitch = ({
|
||||
}, []);
|
||||
|
||||
tooltipContent =
|
||||
tooltipContent || (open ? t('Collapse sidebar') : t('Expand sidebar'));
|
||||
tooltipContent || (open ? t['Collapse sidebar']() : t['Expand sidebar']());
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { IconButton, Modal, ModalWrapper } from '@affine/component';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { CloseIcon } from '@blocksuite/icons';
|
||||
import type React from 'react';
|
||||
|
||||
@@ -15,7 +15,7 @@ export type TransformWorkspaceToAffineModalProps = {
|
||||
export const TransformWorkspaceToAffineModal: React.FC<
|
||||
TransformWorkspaceToAffineModalProps
|
||||
> = ({ open, onClose, onConform }) => {
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
const user = useCurrentUser();
|
||||
|
||||
return (
|
||||
@@ -35,8 +35,8 @@ export const TransformWorkspaceToAffineModal: React.FC<
|
||||
</IconButton>
|
||||
</Header>
|
||||
<Content>
|
||||
<ContentTitle>{t('Enable AFFiNE Cloud')}?</ContentTitle>
|
||||
<StyleTips>{t('Enable AFFiNE Cloud Description')}</StyleTips>
|
||||
<ContentTitle>{t['Enable AFFiNE Cloud']()}?</ContentTitle>
|
||||
<StyleTips>{t['Enable AFFiNE Cloud Description']()}</StyleTips>
|
||||
{/* <StyleTips>{t('Retain cached cloud data')}</StyleTips> */}
|
||||
<div>
|
||||
<StyleButton
|
||||
@@ -61,7 +61,7 @@ export const TransformWorkspaceToAffineModal: React.FC<
|
||||
// setLoading(false);
|
||||
}}
|
||||
>
|
||||
{user ? t('Enable') : t('Sign in and Enable')}
|
||||
{user ? t['Enable']() : t['Sign in and Enable']()}
|
||||
</StyleButton>
|
||||
<StyleButton
|
||||
shape="round"
|
||||
@@ -69,7 +69,7 @@ export const TransformWorkspaceToAffineModal: React.FC<
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
{t('Not now')}
|
||||
{t['Not now']()}
|
||||
</StyleButton>
|
||||
</div>
|
||||
</Content>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import type { SettingPanel, WorkspaceRegistry } from '@affine/workspace/type';
|
||||
import { settingPanel, WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import type { MouseEvent } from 'react';
|
||||
@@ -39,6 +39,7 @@ export type WorkspaceSettingDetailProps = {
|
||||
|
||||
export type PanelProps = WorkspaceSettingDetailProps;
|
||||
|
||||
type Name = 'General' | 'Sync' | 'Collaboration' | 'Publish' | 'Export';
|
||||
const panelMap = {
|
||||
[settingPanel.General]: {
|
||||
name: 'General',
|
||||
@@ -63,7 +64,7 @@ const panelMap = {
|
||||
},
|
||||
} satisfies {
|
||||
[Key in SettingPanel]: {
|
||||
name: string;
|
||||
name: Name;
|
||||
enable?: (flavour: WorkspaceFlavour) => boolean;
|
||||
ui: React.FC<PanelProps>;
|
||||
};
|
||||
@@ -96,7 +97,7 @@ export const WorkspaceSettingDetail: React.FC<
|
||||
if (!(currentTab in panelMap)) {
|
||||
throw new Error('Invalid activeTab: ' + currentTab);
|
||||
}
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
const workspaceId = workspace.id;
|
||||
useEffect(() => {
|
||||
if (isAffine && isOwner) {
|
||||
@@ -148,7 +149,7 @@ export const WorkspaceSettingDetail: React.FC<
|
||||
data-tab-key={key}
|
||||
onClick={handleTabClick}
|
||||
>
|
||||
{t(value.name)}
|
||||
{t[value.name]()}
|
||||
</WorkspaceSettingTagItem>
|
||||
);
|
||||
})}
|
||||
|
||||
+13
-13
@@ -1,6 +1,6 @@
|
||||
import { Button, IconButton, Menu, MenuItem, Wrapper } from '@affine/component';
|
||||
import { config } from '@affine/env';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { PermissionType } from '@affine/workspace/affine/api';
|
||||
import type { AffineWorkspace, LocalWorkspace } from '@affine/workspace/type';
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
@@ -41,7 +41,7 @@ const AffineRemoteCollaborationPanel: React.FC<
|
||||
}
|
||||
> = ({ workspace }) => {
|
||||
const [isInviteModalShow, setIsInviteModalShow] = useState(false);
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
const { members, removeMember } = useMembers(workspace.id);
|
||||
return (
|
||||
<>
|
||||
@@ -49,11 +49,11 @@ const AffineRemoteCollaborationPanel: React.FC<
|
||||
<ul>
|
||||
<StyledMemberTitleContainer>
|
||||
<StyledMemberNameContainer>
|
||||
{t('Users')} (
|
||||
{t['Users']()} (
|
||||
<span data-testid="member-length">{members.length}</span>)
|
||||
</StyledMemberNameContainer>
|
||||
<StyledMemberRoleContainer>
|
||||
{t('Access level')}
|
||||
{t['Access level']()}
|
||||
</StyledMemberRoleContainer>
|
||||
<div style={{ width: '24px', paddingRight: '48px' }}></div>
|
||||
</StyledMemberTitleContainer>
|
||||
@@ -91,9 +91,9 @@ const AffineRemoteCollaborationPanel: React.FC<
|
||||
<StyledMemberRoleContainer>
|
||||
{member.accepted
|
||||
? member.type !== PermissionType.Owner
|
||||
? t('Member')
|
||||
: t('Owner')
|
||||
: t('Pending')}
|
||||
? t['Member']()
|
||||
: t['Owner']()
|
||||
: t['Pending']()}
|
||||
</StyledMemberRoleContainer>
|
||||
{member.type === PermissionType.Owner ? (
|
||||
<StyledMoreVerticalDiv />
|
||||
@@ -109,14 +109,14 @@ const AffineRemoteCollaborationPanel: React.FC<
|
||||
// @ts-ignore
|
||||
await removeMember(member.id);
|
||||
toast(
|
||||
t('Member has been removed', {
|
||||
t['Member has been removed']({
|
||||
name: user.name,
|
||||
})
|
||||
);
|
||||
}}
|
||||
icon={<DeleteTemporarilyIcon />}
|
||||
>
|
||||
{t('Remove from workspace')}
|
||||
{t['Remove from workspace']()}
|
||||
</MenuItem>
|
||||
</>
|
||||
}
|
||||
@@ -145,7 +145,7 @@ const AffineRemoteCollaborationPanel: React.FC<
|
||||
data-testid="invite-members"
|
||||
shape="circle"
|
||||
>
|
||||
{t('Invite Members')}
|
||||
{t['Invite Members']()}
|
||||
</Button>
|
||||
</StyledMemberButtonContainer>
|
||||
</StyledMemberContainer>
|
||||
@@ -168,11 +168,11 @@ const LocalCollaborationPanel: React.FC<
|
||||
workspace: LocalWorkspace;
|
||||
}
|
||||
> = ({ workspace, onTransferWorkspace }) => {
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
const [open, setOpen] = useState(false);
|
||||
return (
|
||||
<>
|
||||
<Wrapper marginBottom="42px">{t('Collaboration Description')}</Wrapper>
|
||||
<Wrapper marginBottom="42px">{t['Collaboration Description']()}</Wrapper>
|
||||
|
||||
<Button
|
||||
data-testid="local-workspace-enable-cloud-button"
|
||||
@@ -182,7 +182,7 @@ const LocalCollaborationPanel: React.FC<
|
||||
setOpen(true);
|
||||
}}
|
||||
>
|
||||
{t('Enable AFFiNE Cloud')}
|
||||
{t['Enable AFFiNE Cloud']()}
|
||||
</Button>
|
||||
{config.enableLegacyCloud ? (
|
||||
<TransformWorkspaceToAffineModal
|
||||
|
||||
+5
-5
@@ -7,7 +7,7 @@ import {
|
||||
MuiAvatar,
|
||||
styled,
|
||||
} from '@affine/component';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { EmailIcon } from '@blocksuite/icons';
|
||||
import type React from 'react';
|
||||
import { Suspense, useCallback, useState } from 'react';
|
||||
@@ -60,7 +60,7 @@ export const InviteMemberModal = ({
|
||||
const { inviteMember } = useMembers(workspaceId);
|
||||
const [email, setEmail] = useState<string>('');
|
||||
const [showMemberPreview, setShowMemberPreview] = useState(false);
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
const inputChange = useCallback((value: string) => {
|
||||
setEmail(value);
|
||||
}, []);
|
||||
@@ -77,7 +77,7 @@ export const InviteMemberModal = ({
|
||||
/>
|
||||
</Header>
|
||||
<Content>
|
||||
<ContentTitle>{t('Invite Members')}</ContentTitle>
|
||||
<ContentTitle>{t['Invite Members']()}</ContentTitle>
|
||||
<InviteBox>
|
||||
<Input
|
||||
data-testid="invite-member-input"
|
||||
@@ -90,7 +90,7 @@ export const InviteMemberModal = ({
|
||||
onBlur={useCallback(() => {
|
||||
setShowMemberPreview(false);
|
||||
}, [])}
|
||||
placeholder={t('Invite placeholder')}
|
||||
placeholder={t['Invite placeholder']()}
|
||||
/>
|
||||
{showMemberPreview && gmailReg.test(email) && (
|
||||
<Suspense fallback="loading...">
|
||||
@@ -112,7 +112,7 @@ export const InviteMemberModal = ({
|
||||
onInviteSuccess();
|
||||
}}
|
||||
>
|
||||
{t('Invite')}
|
||||
{t['Invite']()}
|
||||
</Button>
|
||||
</Footer>
|
||||
</ModalWrapper>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Button, Wrapper } from '@affine/component';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
|
||||
export const ExportPanel = () => {
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
return (
|
||||
<>
|
||||
<Wrapper marginBottom="42px"> {t('Export Description')}</Wrapper>
|
||||
<Wrapper marginBottom="42px"> {t['Export Description']()}</Wrapper>
|
||||
<Button
|
||||
type="light"
|
||||
shape="circle"
|
||||
@@ -14,7 +14,7 @@ export const ExportPanel = () => {
|
||||
window.apis.openSaveDBFileDialog();
|
||||
}}
|
||||
>
|
||||
{t('Export AFFiNE backup file')}
|
||||
{t['Export AFFiNE backup file']()}
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
|
||||
+8
-7
@@ -1,5 +1,6 @@
|
||||
import { Button, Input, Modal, ModalCloseButton } from '@affine/component';
|
||||
import { Trans, useTranslation } from '@affine/i18n';
|
||||
import { Trans } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-workspace-name';
|
||||
import { useCallback, useState } from 'react';
|
||||
@@ -33,11 +34,11 @@ export const WorkspaceDeleteModal = ({
|
||||
);
|
||||
const [deleteStr, setDeleteStr] = useState<string>('');
|
||||
const allowDelete = deleteStr === workspaceName;
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
|
||||
const handleDelete = useCallback(() => {
|
||||
onDeleteWorkspace().then(() => {
|
||||
toast(t('Successfully deleted'), {
|
||||
toast(t['Successfully deleted'](), {
|
||||
portal: document.body,
|
||||
});
|
||||
});
|
||||
@@ -47,7 +48,7 @@ export const WorkspaceDeleteModal = ({
|
||||
<Modal open={open} onClose={onClose}>
|
||||
<StyledModalWrapper>
|
||||
<ModalCloseButton onClick={onClose} />
|
||||
<StyledModalHeader>{t('Delete Workspace')}?</StyledModalHeader>
|
||||
<StyledModalHeader>{t['Delete Workspace']()}?</StyledModalHeader>
|
||||
{workspace.flavour === WorkspaceFlavour.LOCAL ? (
|
||||
<StyledTextContent>
|
||||
<Trans i18nKey="Delete Workspace Description">
|
||||
@@ -80,7 +81,7 @@ export const WorkspaceDeleteModal = ({
|
||||
}}
|
||||
onChange={setDeleteStr}
|
||||
data-testid="delete-workspace-input"
|
||||
placeholder={t('Placeholder of delete workspace')}
|
||||
placeholder={t['Placeholder of delete workspace']()}
|
||||
value={deleteStr}
|
||||
width={315}
|
||||
height={42}
|
||||
@@ -88,7 +89,7 @@ export const WorkspaceDeleteModal = ({
|
||||
</StyledInputContent>
|
||||
<StyledButtonContent>
|
||||
<Button shape="circle" onClick={onClose}>
|
||||
{t('Cancel')}
|
||||
{t['Cancel']()}
|
||||
</Button>
|
||||
<Button
|
||||
data-testid="delete-workspace-confirm-button"
|
||||
@@ -98,7 +99,7 @@ export const WorkspaceDeleteModal = ({
|
||||
shape="circle"
|
||||
style={{ marginLeft: '24px' }}
|
||||
>
|
||||
{t('Delete')}
|
||||
{t['Delete']()}
|
||||
</Button>
|
||||
</StyledButtonContent>
|
||||
</StyledModalWrapper>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Button, FlexWrapper, MuiFade } from '@affine/component';
|
||||
import { WorkspaceAvatar } from '@affine/component/workspace-avatar';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import { useBlockSuiteWorkspaceAvatarUrl } from '@toeverything/hooks/use-block-suite-workspace-avatar-url';
|
||||
import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-workspace-name';
|
||||
@@ -38,7 +38,7 @@ export const GeneralPanel: React.FC<PanelProps> = ({
|
||||
const [input, setInput] = useState<string>(name);
|
||||
const isOwner = useIsWorkspaceOwner(workspace);
|
||||
const [showEditInput, setShowEditInput] = useState(false);
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
|
||||
const handleUpdateWorkspaceName = (name: string) => {
|
||||
setName(name);
|
||||
@@ -50,7 +50,7 @@ export const GeneralPanel: React.FC<PanelProps> = ({
|
||||
return (
|
||||
<>
|
||||
<StyledRow>
|
||||
<StyledSettingKey>{t('Workspace Avatar')}</StyledSettingKey>
|
||||
<StyledSettingKey>{t['Workspace Avatar']()}</StyledSettingKey>
|
||||
<StyledAvatar disabled={!isOwner}>
|
||||
{isOwner ? (
|
||||
<Upload
|
||||
@@ -72,7 +72,7 @@ export const GeneralPanel: React.FC<PanelProps> = ({
|
||||
</StyledRow>
|
||||
|
||||
<StyledRow>
|
||||
<StyledSettingKey>{t('Workspace Name')}</StyledSettingKey>
|
||||
<StyledSettingKey>{t['Workspace Name']()}</StyledSettingKey>
|
||||
|
||||
<div style={{ position: 'relative' }}>
|
||||
<MuiFade in={!showEditInput}>
|
||||
@@ -84,7 +84,7 @@ export const GeneralPanel: React.FC<PanelProps> = ({
|
||||
setShowEditInput(true);
|
||||
}}
|
||||
>
|
||||
{t('Edit')}
|
||||
{t['Edit']()}
|
||||
</StyledEditButton>
|
||||
)}
|
||||
</FlexWrapper>
|
||||
@@ -97,7 +97,7 @@ export const GeneralPanel: React.FC<PanelProps> = ({
|
||||
width={284}
|
||||
height={38}
|
||||
value={input}
|
||||
placeholder={t('Workspace Name')}
|
||||
placeholder={t['Workspace Name']()}
|
||||
maxLength={50}
|
||||
minLength={0}
|
||||
onChange={newName => {
|
||||
@@ -114,7 +114,7 @@ export const GeneralPanel: React.FC<PanelProps> = ({
|
||||
setShowEditInput(false);
|
||||
}}
|
||||
>
|
||||
{t('Confirm')}
|
||||
{t['Confirm']()}
|
||||
</Button>
|
||||
<Button
|
||||
type="default"
|
||||
@@ -125,7 +125,7 @@ export const GeneralPanel: React.FC<PanelProps> = ({
|
||||
setShowEditInput(false);
|
||||
}}
|
||||
>
|
||||
{t('Cancel')}
|
||||
{t['Cancel']()}
|
||||
</Button>
|
||||
</FlexWrapper>
|
||||
</MuiFade>
|
||||
@@ -165,29 +165,29 @@ export const GeneralPanel: React.FC<PanelProps> = ({
|
||||
}
|
||||
}}
|
||||
>
|
||||
<StyledSettingKey>{t('Workspace Type')}</StyledSettingKey>
|
||||
<StyledSettingKey>{t['Workspace Type']()}</StyledSettingKey>
|
||||
{isOwner ? (
|
||||
workspace.flavour === WorkspaceFlavour.LOCAL ? (
|
||||
<StyledWorkspaceInfo>
|
||||
<LocalWorkspaceIcon />
|
||||
<span>{t('Local Workspace')}</span>
|
||||
<span>{t['Local Workspace']()}</span>
|
||||
</StyledWorkspaceInfo>
|
||||
) : (
|
||||
<StyledWorkspaceInfo>
|
||||
<CloudWorkspaceIcon />
|
||||
<span>{t('Cloud Workspace')}</span>
|
||||
<span>{t['Cloud Workspace']()}</span>
|
||||
</StyledWorkspaceInfo>
|
||||
)
|
||||
) : (
|
||||
<StyledWorkspaceInfo>
|
||||
<JoinedWorkspaceIcon />
|
||||
<span>{t('Joined Workspace')}</span>
|
||||
<span>{t['Joined Workspace']()}</span>
|
||||
</StyledWorkspaceInfo>
|
||||
)}
|
||||
</StyledRow>
|
||||
|
||||
<StyledRow>
|
||||
<StyledSettingKey> {t('Delete Workspace')}</StyledSettingKey>
|
||||
<StyledSettingKey> {t['Delete Workspace']()}</StyledSettingKey>
|
||||
{isOwner ? (
|
||||
<>
|
||||
<Button
|
||||
@@ -199,7 +199,7 @@ export const GeneralPanel: React.FC<PanelProps> = ({
|
||||
setShowDelete(true);
|
||||
}}
|
||||
>
|
||||
{t('Delete Workspace')}
|
||||
{t['Delete Workspace']()}
|
||||
</Button>
|
||||
<WorkspaceDeleteModal
|
||||
onDeleteWorkspace={onDeleteWorkspace}
|
||||
@@ -219,7 +219,7 @@ export const GeneralPanel: React.FC<PanelProps> = ({
|
||||
setShowLeave(true);
|
||||
}}
|
||||
>
|
||||
{t('Leave Workspace')}
|
||||
{t['Leave Workspace']()}
|
||||
</Button>
|
||||
<WorkspaceLeave
|
||||
open={showLeave}
|
||||
|
||||
+6
-6
@@ -1,7 +1,7 @@
|
||||
import { Modal } from '@affine/component';
|
||||
import { ModalCloseButton } from '@affine/component';
|
||||
import { Button } from '@affine/component';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
|
||||
import {
|
||||
StyledButtonContent,
|
||||
@@ -17,7 +17,7 @@ interface WorkspaceDeleteProps {
|
||||
|
||||
export const WorkspaceLeave = ({ open, onClose }: WorkspaceDeleteProps) => {
|
||||
// const { leaveWorkSpace } = useWorkspaceHelper();
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
const handleLeave = async () => {
|
||||
// await leaveWorkSpace();
|
||||
onClose();
|
||||
@@ -27,13 +27,13 @@ export const WorkspaceLeave = ({ open, onClose }: WorkspaceDeleteProps) => {
|
||||
<Modal open={open} onClose={onClose}>
|
||||
<StyledModalWrapper>
|
||||
<ModalCloseButton onClick={onClose} />
|
||||
<StyledModalHeader>{t('Leave Workspace')}</StyledModalHeader>
|
||||
<StyledModalHeader>{t['Leave Workspace']()}</StyledModalHeader>
|
||||
<StyledTextContent>
|
||||
{t('Leave Workspace Description')}
|
||||
{t['Leave Workspace Description']()}
|
||||
</StyledTextContent>
|
||||
<StyledButtonContent>
|
||||
<Button shape="circle" onClick={onClose}>
|
||||
{t('Cancel')}
|
||||
{t['Cancel']()}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleLeave}
|
||||
@@ -41,7 +41,7 @@ export const WorkspaceLeave = ({ open, onClose }: WorkspaceDeleteProps) => {
|
||||
shape="circle"
|
||||
style={{ marginLeft: '24px' }}
|
||||
>
|
||||
{t('Leave')}
|
||||
{t['Leave']()}
|
||||
</Button>
|
||||
</StyledButtonContent>
|
||||
</StyledModalWrapper>
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
Wrapper,
|
||||
} from '@affine/component';
|
||||
import { config } from '@affine/env';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import type { AffineWorkspace, LocalWorkspace } from '@affine/workspace/type';
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import { Box } from '@mui/material';
|
||||
@@ -41,20 +41,20 @@ const PublishPanelAffine: React.FC<PublishPanelAffineProps> = ({
|
||||
);
|
||||
}, []);
|
||||
const shareUrl = origin + '/public-workspace/' + workspace.id;
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
const publishWorkspace = useToggleWorkspacePublish(workspace);
|
||||
const copyUrl = useCallback(() => {
|
||||
navigator.clipboard.writeText(shareUrl);
|
||||
toast(t('Copied link to clipboard'));
|
||||
toast(t['Copied link to clipboard']());
|
||||
}, [shareUrl, t]);
|
||||
|
||||
if (workspace.public) {
|
||||
return (
|
||||
<>
|
||||
<Wrapper marginBottom="42px">{t('Published Description')}</Wrapper>
|
||||
<Wrapper marginBottom="42px">{t['Published Description']()}</Wrapper>
|
||||
|
||||
<Wrapper marginBottom="12px">
|
||||
<Content weight="500">{t('Share with link')}</Content>
|
||||
<Content weight="500">{t['Share with link']()}</Content>
|
||||
</Wrapper>
|
||||
<FlexWrapper>
|
||||
<Input
|
||||
@@ -69,7 +69,7 @@ const PublishPanelAffine: React.FC<PublishPanelAffineProps> = ({
|
||||
shape="circle"
|
||||
style={{ marginLeft: '24px' }}
|
||||
>
|
||||
{t('Copy Link')}
|
||||
{t['Copy Link']()}
|
||||
</Button>
|
||||
</FlexWrapper>
|
||||
<Button
|
||||
@@ -81,14 +81,14 @@ const PublishPanelAffine: React.FC<PublishPanelAffineProps> = ({
|
||||
shape="circle"
|
||||
style={{ marginTop: '38px' }}
|
||||
>
|
||||
{t('Stop publishing')}
|
||||
{t['Stop publishing']()}
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<Wrapper marginBottom="42px">{t('Publishing Description')}</Wrapper>
|
||||
<Wrapper marginBottom="42px">{t['Publishing Description']()}</Wrapper>
|
||||
<Button
|
||||
data-testid="publish-to-web-button"
|
||||
onClick={async () => {
|
||||
@@ -97,7 +97,7 @@ const PublishPanelAffine: React.FC<PublishPanelAffineProps> = ({
|
||||
type="light"
|
||||
shape="circle"
|
||||
>
|
||||
{t('Publish to web')}
|
||||
{t['Publish to web']()}
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
@@ -111,7 +111,7 @@ const PublishPanelLocal: React.FC<PublishPanelLocalProps> = ({
|
||||
workspace,
|
||||
onTransferWorkspace,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
const [open, setOpen] = useState(false);
|
||||
return (
|
||||
<>
|
||||
@@ -120,7 +120,7 @@ const PublishPanelLocal: React.FC<PublishPanelLocalProps> = ({
|
||||
marginBottom: '42px',
|
||||
}}
|
||||
>
|
||||
{t('Publishing')}
|
||||
{t['Publishing']()}
|
||||
</Box>
|
||||
{/* TmpDisableAffineCloudModal */}
|
||||
|
||||
@@ -132,7 +132,7 @@ const PublishPanelLocal: React.FC<PublishPanelLocalProps> = ({
|
||||
setOpen(true);
|
||||
}}
|
||||
>
|
||||
{t('Enable AFFiNE Cloud')}
|
||||
{t['Enable AFFiNE Cloud']()}
|
||||
</Button>
|
||||
{config.enableLegacyCloud ? (
|
||||
<EnableAffineCloudModal
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Content, FlexWrapper, styled } from '@affine/component';
|
||||
import { Trans, useTranslation } from '@affine/i18n';
|
||||
import { Trans } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import { useBlockSuiteWorkspaceAvatarUrl } from '@toeverything/hooks/use-block-suite-workspace-avatar-url';
|
||||
import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-workspace-name';
|
||||
@@ -25,7 +26,7 @@ export const SyncPanel: React.FC<PanelProps> = ({ workspace }) => {
|
||||
workspace.blockSuiteWorkspace
|
||||
);
|
||||
const user = useCurrentUser();
|
||||
const { t } = useTranslation();
|
||||
const t = useAFFiNEI18N();
|
||||
return (
|
||||
<>
|
||||
<FlexWrapper alignItems="center" style={{ marginBottom: '12px' }}>
|
||||
@@ -37,7 +38,7 @@ export const SyncPanel: React.FC<PanelProps> = ({ workspace }) => {
|
||||
/>
|
||||
<StyledWorkspaceName>{name}</StyledWorkspaceName>
|
||||
|
||||
<Content weight={500}>{t('is a Cloud Workspace')}</Content>
|
||||
<Content weight={500}>{t['is a Cloud Workspace']()}</Content>
|
||||
</FlexWrapper>
|
||||
<Trans i18nKey="Cloud Workspace Description">
|
||||
All data will be synchronised and saved to the AFFiNE account
|
||||
|
||||
Reference in New Issue
Block a user