feat(i18n): static type on i18n (#2225)

This commit is contained in:
Himself65
2023-05-04 00:35:09 -05:00
committed by GitHub
parent 66c3b09c67
commit 3d43e61087
80 changed files with 585 additions and 444 deletions
@@ -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>
);
})}
@@ -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
@@ -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>
</>
);
@@ -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}
@@ -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>
&nbsp;
<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