diff --git a/packages/app/src/components/workspace-setting/SyncPage.tsx b/packages/app/src/components/workspace-setting/SyncPage.tsx
index 7e17d83cf8..ddca482143 100644
--- a/packages/app/src/components/workspace-setting/SyncPage.tsx
+++ b/packages/app/src/components/workspace-setting/SyncPage.tsx
@@ -1,15 +1,15 @@
import {
- StyleAsync,
+ StyledButtonContainer,
StyledPublishContent,
StyledPublishExplanation,
StyledWorkspaceName,
- StyledWorkspaceType,
+ StyledEmail,
} from './style';
import { DownloadIcon } from '@blocksuite/icons';
import { Button } from '@/ui/button';
import { Menu, MenuItem } from '@/ui/menu';
import { WorkspaceUnit } from '@affine/datacenter';
-import { useTranslation } from '@affine/i18n';
+import { useTranslation, Trans } from '@affine/i18n';
import { WorkspaceUnitAvatar } from '@/components/workspace-avatar';
import { EnableWorkspaceButton } from '../enable-workspace';
import { useAppState } from '@/providers/app-state-provider';
@@ -28,16 +28,13 @@ export const SyncPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
workspaceUnit={workspace}
style={{ marginRight: '12px' }}
/>
-
{workspace.name};
-
is a Local Workspace.
+
{workspace.name}
+
{t('is a Local Workspace')}
-
- All data is stored on the current device. You can enable AFFiNE
- Cloud for this workspace to keep data in sync with the cloud.
-
-
+ {t('Local Workspace Description')}
+
-
+
>
) : (
<>
@@ -48,14 +45,21 @@ export const SyncPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
workspaceUnit={workspace}
style={{ marginRight: '12px' }}
/>
-
{workspace.name} is
- Cloud Workspace.
+
{workspace.name}
+
{t('is a Cloud Workspace')}
-
- All data will be synchronized and saved to the AFFiNE account{' '}
- {user?.email}
-
-
+
+
+ All data will be synchronised and saved to the AFFiNE account
+
+ {{
+ email: '{' + user?.email + '}.',
+ }}
+
+
+
+
+
@@ -65,7 +69,7 @@ export const SyncPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
}}
icon={ }
>
- {t('Download data to device', { CoreOrAll: 'core' })}
+ {t('Download data', { CoreOrAll: t('core') })}
{
@@ -73,7 +77,7 @@ export const SyncPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
}}
icon={ }
>
- {t('Download data to device', { CoreOrAll: 'all' })}
+ {t('Download data', { CoreOrAll: t('all') })}
>
}
@@ -81,10 +85,10 @@ export const SyncPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
disablePortal={true}
>
- {t('Download data to device', { CoreOrAll: 'all' })}
+ {t('Download data', { CoreOrAll: '' })}
-
+
>
)}
diff --git a/packages/app/src/components/workspace-setting/general/General.tsx b/packages/app/src/components/workspace-setting/general/General.tsx
index 0207cb6a95..5b5bc26843 100644
--- a/packages/app/src/components/workspace-setting/general/General.tsx
+++ b/packages/app/src/components/workspace-setting/general/General.tsx
@@ -50,7 +50,7 @@ export const GeneralPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
return workspace ? (
-
Workspace Avatar
+
{t('Workspace Avatar')}
{
currentWorkspace?.provider === 'local' ? (
- Local Workspace
+ {t('Local Workspace')}
) : (
- All data can be accessed offline
+ {t('Available Offline')}
)
) : (
- Joined Workspace
+ {t('Joined Workspace')}
)}
diff --git a/packages/app/src/components/workspace-setting/member/MembersPage.tsx b/packages/app/src/components/workspace-setting/member/MembersPage.tsx
index 986853652f..caa6047773 100644
--- a/packages/app/src/components/workspace-setting/member/MembersPage.tsx
+++ b/packages/app/src/components/workspace-setting/member/MembersPage.tsx
@@ -89,9 +89,9 @@ export const MembersPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
{member.accepted
? member.type !== 99
- ? 'Member'
- : 'Workspace Owner'
- : 'Pending'}
+ ? t('Member')
+ : t('Owner')
+ : t('Pending')}
{
{
const confirmRemove = await confirm({
- title: 'Delete Member?',
- content: `will delete member`,
- confirmText: 'Delete',
+ title: t('Delete Member?'),
+ content: t('will delete member'),
+ confirmText: t('Delete'),
confirmType: 'danger',
});
@@ -110,11 +110,15 @@ export const MembersPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
return;
}
await removeMember(member.id);
- toast(`${user.name} has been removed`);
+ toast(
+ t('Member has been removed', {
+ name: user.name,
+ })
+ );
}}
icon={ }
>
- Delete
+ {t('Delete')}
>
}
diff --git a/packages/app/src/components/workspace-setting/style.ts b/packages/app/src/components/workspace-setting/style.ts
index 31a19289cc..3e29c53d9e 100644
--- a/packages/app/src/components/workspace-setting/style.ts
+++ b/packages/app/src/components/workspace-setting/style.ts
@@ -90,7 +90,7 @@ export const StyledSettingH2 = styled('h2')<{
marginBottom?: number;
}>(({ marginTop, marginBottom, theme }) => {
return {
- fontWeight: '500',
+ // fontWeight: '500',
fontSize: theme.font.base,
lineHeight: theme.font.lineHeightBase,
marginTop: marginTop ? `${marginTop}px` : '0px',
@@ -101,24 +101,18 @@ export const StyledSettingH2 = styled('h2')<{
export const StyledPublishExplanation = styled('div')(() => {
return {
paddingRight: '48px',
- fontWeight: '500',
- fontSize: '18px',
- lineHeight: '26px',
+ // fontWeight: '500',
marginBottom: '22px',
};
});
export const StyledWorkspaceName = styled('span')(() => {
return {
fontWeight: '400',
- fontSize: '18px',
- lineHeight: '26px',
};
});
export const StyledWorkspaceType = styled('span')(() => {
return {
- fontWeight: '500',
- fontSize: '18px',
- lineHeight: '26px',
+ // fontWeight: '500',
};
});
@@ -136,22 +130,24 @@ export const StyledStopPublishContainer = styled('div')(() => {
};
});
-export const StyledCopyButtonContainer = styled('div')(() => {
+export const StyledButtonContainer = styled('div')(() => {
return {
marginTop: '64px',
};
});
+export const StyledEmail = styled('span')(() => {
+ return {
+ color: '#E8178A',
+ };
+});
-export const StyledPublishContent = styled('div')(() => {
+export const StyledPublishContent = styled('div')(({ theme }) => {
return {
display: 'flex',
+ fontWeight: '500',
flexDirection: 'column',
+ fontSize: theme.font.base,
+ lineHeight: theme.font.lineHeightBase,
flex: 1,
};
});
-
-export const StyleAsync = styled('div')(() => {
- return {
- marginTop: '64px',
- };
-});
diff --git a/packages/app/src/hooks/use-page-helper.ts b/packages/app/src/hooks/use-page-helper.ts
index 00133b03e4..6e5dd98ca8 100644
--- a/packages/app/src/hooks/use-page-helper.ts
+++ b/packages/app/src/hooks/use-page-helper.ts
@@ -1,4 +1,4 @@
-import { uuidv4 } from '@blocksuite/store';
+import { uuidv4, Workspace } from '@blocksuite/store';
import { QueryContent } from '@blocksuite/store/dist/workspace/search';
import { PageMeta, useAppState } from '@/providers/app-state-provider';
import { EditorContainer } from '@blocksuite/editor';
@@ -20,7 +20,10 @@ export type EditorHandlers = {
toggleDeletePage: (pageId: string) => Promise;
toggleFavoritePage: (pageId: string) => Promise;
permanentlyDeletePage: (pageId: string) => void;
- search: (query: QueryContent) => Map;
+ search: (
+ query: QueryContent,
+ workspace?: Workspace
+ ) => Map;
// changeEditorMode: (pageId: string) => void;
changePageMode: (
pageId: string,
@@ -83,9 +86,16 @@ export const usePageHelper = (): EditorHandlers => {
});
return trash;
},
- search: (query: QueryContent) => {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- return currentWorkspace!.blocksuiteWorkspace!.search(query);
+ search: (query: QueryContent, workspace?: Workspace) => {
+ if (workspace) {
+ return workspace.search(query);
+ }
+ if (currentWorkspace) {
+ if (currentWorkspace.blocksuiteWorkspace) {
+ return currentWorkspace.blocksuiteWorkspace.search(query);
+ }
+ }
+ return new Map();
},
changePageMode: async (pageId, mode) => {
const pageMeta = getPageMeta(currentWorkspace, pageId);
diff --git a/packages/app/src/hooks/use-workspace-helper.ts b/packages/app/src/hooks/use-workspace-helper.ts
index 870d954638..ec990feb30 100644
--- a/packages/app/src/hooks/use-workspace-helper.ts
+++ b/packages/app/src/hooks/use-workspace-helper.ts
@@ -3,9 +3,11 @@ import { useConfirm } from '@/providers/ConfirmProvider';
import { toast } from '@/ui/toast';
import { WorkspaceUnit } from '@affine/datacenter';
import router from 'next/router';
+import { useTranslation } from '@affine/i18n';
export const useWorkspaceHelper = () => {
const { confirm } = useConfirm();
+ const { t } = useTranslation();
const { dataCenter, currentWorkspace, user, login } = useAppState();
const createWorkspace = async (name: string) => {
const workspaceInfo = await dataCenter.createWorkspace({
@@ -38,10 +40,10 @@ export const useWorkspaceHelper = () => {
const enableWorkspace = async () => {
confirm({
- title: 'Enable AFFiNE Cloud?',
- content: `If enabled, the data in this workspace will be backed up and synchronized via AFFiNE Cloud.`,
- confirmText: user ? 'Enable' : 'Sign in and Enable',
- cancelText: 'Skip',
+ title: `${t('Enable AFFiNE Cloud')}?`,
+ content: t('Enable AFFiNE Cloud Description'),
+ confirmText: user ? t('Enable') : t('Sign in and Enable'),
+ cancelText: t('Skip'),
confirmType: 'primary',
buttonDirection: 'column',
}).then(async confirm => {
@@ -53,7 +55,7 @@ export const useWorkspaceHelper = () => {
currentWorkspace
);
workspace && router.push(`/workspace/${workspace.id}/setting`);
- toast('Enabled success');
+ toast(t('Enabled success'));
}
});
};
diff --git a/packages/app/src/pages/public-workspace/[workspaceId]/[pageId].tsx b/packages/app/src/pages/public-workspace/[workspaceId]/[pageId].tsx
index 4993246384..7fb0efc002 100644
--- a/packages/app/src/pages/public-workspace/[workspaceId]/[pageId].tsx
+++ b/packages/app/src/pages/public-workspace/[workspaceId]/[pageId].tsx
@@ -1,11 +1,17 @@
import { ReactElement, useEffect, useState } from 'react';
import { useAppState } from '@/providers/app-state-provider';
import type { NextPageWithLayout } from '../..//_app';
-import { styled } from '@/styles';
+import { displayFlex, styled } from '@/styles';
import dynamic from 'next/dynamic';
import { useRouter } from 'next/router';
import { Page as PageStore, Workspace } from '@blocksuite/store';
import { PageLoading } from '@/components/loading';
+import { Breadcrumbs } from '@/ui/breadcrumbs';
+import { IconButton } from '@/ui/button';
+import NextLink from 'next/link';
+import { PaperIcon, SearchIcon } from '@blocksuite/icons';
+import { WorkspaceUnitAvatar } from '@/components/workspace-avatar';
+import { useModal } from '@/providers/GlobalModalProvider';
const DynamicBlocksuite = dynamic(() => import('@/components/editor'), {
ssr: false,
@@ -16,12 +22,16 @@ const Page: NextPageWithLayout = () => {
const { dataCenter } = useAppState();
const router = useRouter();
const [loaded, setLoaded] = useState(false);
+ const [workspaceName, setWorkspaceName] = useState('');
+ const [pageTitle, setPageTitle] = useState('');
+ const { triggerQuickSearchModal } = useModal();
useEffect(() => {
dataCenter
.loadPublicWorkspace(router.query.workspaceId as string)
.then(data => {
- if (data && data.blocksuiteWorkspace) {
+ setWorkspaceName(data.blocksuiteWorkspace?.meta.name as string);
+ if (data.blocksuiteWorkspace) {
setWorkspace(data.blocksuiteWorkspace);
if (
router.query.pageId &&
@@ -32,6 +42,7 @@ const Page: NextPageWithLayout = () => {
const page = data.blocksuiteWorkspace.getPage(
router.query.pageId as string
);
+ page && setPageTitle(page.meta.title);
page && setPage(page);
} else {
router.push('/404');
@@ -46,6 +57,30 @@ const Page: NextPageWithLayout = () => {
<>
{!loaded && }
+
+
+
+
+ {workspaceName}
+
+
+
+ {pageTitle ? pageTitle : 'Untitled'}
+
+
+ {
+ triggerQuickSearchModal();
+ }}
+ >
+
+
+
+
{workspace && page && (
{
return {
- height: 'calc(100vh)',
- padding: '78px 72px',
+ height: '100vh',
overflowY: 'auto',
backgroundColor: theme.colors.pageBackground,
};
});
+export const NavContainer = styled.div(({ theme }) => {
+ return {
+ width: '100vw',
+ padding: '0 12px',
+ height: '60px',
+ ...displayFlex('start', 'center'),
+ backgroundColor: theme.colors.pageBackground,
+ };
+});
+export const StyledBreadcrumbs = styled(NextLink)(({ theme }) => {
+ return {
+ flex: 1,
+ ...displayFlex('center', 'center'),
+ paddingLeft: '12px',
+ span: {
+ padding: '0 12px',
+ fontSize: theme.font.base,
+ lineHeight: theme.font.lineHeightBase,
+ },
+ ':hover': { color: theme.colors.primaryColor },
+ transition: 'all .15s',
+ ':visited': {
+ color: theme.colors.popoverColor,
+ ':hover': { color: theme.colors.primaryColor },
+ },
+ };
+});
+export const SearchButton = styled(IconButton)(({ theme }) => {
+ return {
+ color: theme.colors.iconColor,
+ fontSize: '24px',
+ marginLeft: 'auto',
+ padding: '0 24px',
+ };
+});
diff --git a/packages/app/src/pages/public-workspace/[workspaceId]/index.tsx b/packages/app/src/pages/public-workspace/[workspaceId]/index.tsx
index 113c61c2a6..3d4a8a4dc3 100644
--- a/packages/app/src/pages/public-workspace/[workspaceId]/index.tsx
+++ b/packages/app/src/pages/public-workspace/[workspaceId]/index.tsx
@@ -2,16 +2,28 @@ import { PageList } from '@/components/page-list';
import { ReactElement, useEffect, useState } from 'react';
import { PageMeta, useAppState } from '@/providers/app-state-provider';
import { useRouter } from 'next/router';
-import { PageContainer } from './[pageId]';
+import {
+ PageContainer,
+ NavContainer,
+ StyledBreadcrumbs,
+ SearchButton,
+} from './[pageId]';
+import { Breadcrumbs } from '@/ui/breadcrumbs';
+import { WorkspaceUnitAvatar } from '@/components/workspace-avatar';
+import { SearchIcon } from '@blocksuite/icons';
+import { useModal } from '@/providers/GlobalModalProvider';
const All = () => {
const { dataCenter } = useAppState();
const router = useRouter();
const [pageList, setPageList] = useState([]);
+ const [workspaceName, setWorkspaceName] = useState('');
+ const { triggerQuickSearchModal } = useModal();
useEffect(() => {
dataCenter
.loadPublicWorkspace(router.query.workspaceId as string)
.then(data => {
setPageList(data.blocksuiteWorkspace?.meta.pageMetas as PageMeta[]);
+ setWorkspaceName(data.blocksuiteWorkspace?.meta.name as string);
})
.catch(() => {
router.push('/404');
@@ -20,6 +32,23 @@ const All = () => {
return (
+
+
+
+
+ {workspaceName}
+
+
+ {
+ triggerQuickSearchModal();
+ }}
+ >
+
+
+
!p.trash)}
showFavoriteTag={false}
diff --git a/packages/app/src/pages/workspace/[workspaceId]/setting.tsx b/packages/app/src/pages/workspace/[workspaceId]/setting.tsx
index 975e3d6ff1..ffab84524c 100644
--- a/packages/app/src/pages/workspace/[workspaceId]/setting.tsx
+++ b/packages/app/src/pages/workspace/[workspaceId]/setting.tsx
@@ -19,41 +19,37 @@ import { WorkspaceUnit } from '@affine/datacenter';
import { useTranslation } from '@affine/i18n';
import { PageListHeader } from '@/components/header';
-type TabNames = 'General' | 'Sync' | 'Collaboration' | 'Publish' | 'Export';
-
-const tabMap: {
- name: TabNames;
- panelRender: (workspace: WorkspaceUnit) => ReactNode;
-}[] = [
- {
- name: 'General',
- panelRender: workspace => ,
- },
- {
- name: 'Sync',
- panelRender: workspace => ,
- },
- {
- name: 'Collaboration',
- panelRender: workspace => ,
- },
- {
- name: 'Publish',
- panelRender: workspace => ,
- },
- // TODO: next version will finish this feature
- // {
- // name: 'Export',
- // panelRender: workspace => ,
- // },
-];
-
-const WorkspaceSetting = () => {
+const useTabMap = () => {
const { t } = useTranslation();
- const { currentWorkspace, isOwner } = useAppState();
-
- const [activeTab, setActiveTab] = useState(tabMap[0].name);
- const handleTabChange = (tab: TabNames) => {
+ const { isOwner } = useAppState();
+ const tabMap: {
+ name: string;
+ panelRender: (workspace: WorkspaceUnit) => ReactNode;
+ }[] = [
+ {
+ name: t('General'),
+ panelRender: workspace => ,
+ },
+ {
+ name: t('Sync'),
+ panelRender: workspace => ,
+ },
+ {
+ name: t('Collaboration'),
+ panelRender: workspace => ,
+ },
+ {
+ name: t('Publish'),
+ panelRender: workspace => ,
+ },
+ // TODO: next version will finish this feature
+ // {
+ // name: t('Export'),
+ // panelRender: workspace => ,
+ // },
+ ];
+ const [activeTab, setActiveTab] = useState(tabMap[0].name);
+ const handleTabChange = (tab: string) => {
setActiveTab(tab);
};
@@ -61,7 +57,7 @@ const WorkspaceSetting = () => {
tab => tab.name === activeTab
)?.panelRender;
let tableArr: {
- name: TabNames;
+ name: string;
panelRender: (workspace: WorkspaceUnit) => ReactNode;
}[] = tabMap;
if (!isOwner) {
@@ -72,6 +68,14 @@ const WorkspaceSetting = () => {
},
];
}
+ return { activeTabPanelRender, tableArr, handleTabChange, activeTab };
+};
+
+const WorkspaceSetting = () => {
+ const { t } = useTranslation();
+ const { currentWorkspace } = useAppState();
+ const { activeTabPanelRender, tableArr, handleTabChange, activeTab } =
+ useTabMap();
return (
<>
diff --git a/packages/app/src/ui/breadcrumbs/index.ts b/packages/app/src/ui/breadcrumbs/index.ts
new file mode 100644
index 0000000000..007554be72
--- /dev/null
+++ b/packages/app/src/ui/breadcrumbs/index.ts
@@ -0,0 +1,8 @@
+import MuiBreadcrumbs from '@mui/material/Breadcrumbs';
+import { styled } from '@/styles';
+
+export const Breadcrumbs = styled(MuiBreadcrumbs)(({ theme }) => {
+ return {
+ color: theme.colors.popoverColor,
+ };
+});
diff --git a/packages/data-center/src/provider/affine/affine.ts b/packages/data-center/src/provider/affine/affine.ts
index 025ef96d39..d4c786f461 100644
--- a/packages/data-center/src/provider/affine/affine.ts
+++ b/packages/data-center/src/provider/affine/affine.ts
@@ -13,7 +13,11 @@ import { getApis, Workspace } from './apis/index.js';
import type { Apis, WorkspaceDetail, Callback } from './apis';
import { token } from './apis/token.js';
import { WebsocketClient } from './channel';
-import { loadWorkspaceUnit, createWorkspaceUnit } from './utils.js';
+import {
+ loadWorkspaceUnit,
+ createWorkspaceUnit,
+ migrateBlobDB,
+} from './utils.js';
import { WorkspaceUnit } from '../../workspace-unit.js';
import { createBlocksuiteWorkspace, applyUpdate } from '../../utils/index.js';
import type { SyncMode } from '../../workspace-unit';
@@ -390,6 +394,8 @@ export class AffineProvider extends BaseProvider {
syncMode: 'core',
});
+ await migrateBlobDB(workspaceUnit.id, id);
+
const blocksuiteWorkspace = createBlocksuiteWorkspace(id);
assert(workspaceUnit.blocksuiteWorkspace);
await applyUpdate(
diff --git a/packages/data-center/src/provider/affine/idb-kv.ts b/packages/data-center/src/provider/affine/idb-kv.ts
new file mode 100644
index 0000000000..72f854dd82
--- /dev/null
+++ b/packages/data-center/src/provider/affine/idb-kv.ts
@@ -0,0 +1,23 @@
+import { createStore, keys, setMany, getMany } from 'idb-keyval';
+import * as idb from 'lib0/indexeddb.js';
+
+type IDBInstance = {
+ keys: () => Promise;
+ deleteDB: () => Promise;
+ setMany: (entries: [string, T][]) => Promise;
+ getMany: (keys: string[]) => Promise;
+};
+
+export function getDatabase(
+ type: string,
+ database: string
+): IDBInstance {
+ const name = `${database}_${type}`;
+ const db = createStore(name, type);
+ return {
+ keys: () => keys(db),
+ deleteDB: () => idb.deleteDB(name),
+ setMany: entries => setMany(entries, db),
+ getMany: keys => getMany(keys, db),
+ };
+}
diff --git a/packages/data-center/src/provider/affine/utils.ts b/packages/data-center/src/provider/affine/utils.ts
index 4bb401fbf2..25e2127e50 100644
--- a/packages/data-center/src/provider/affine/utils.ts
+++ b/packages/data-center/src/provider/affine/utils.ts
@@ -4,6 +4,7 @@ import { createBlocksuiteWorkspace } from '../../utils/index.js';
import type { Apis } from './apis';
import { setDefaultAvatar } from '../utils.js';
import { applyUpdate } from '../../utils/index.js';
+import { getDatabase } from './idb-kv.js';
export const loadWorkspaceUnit = async (
params: WorkspaceUnitCtorParams,
@@ -54,3 +55,34 @@ export const createWorkspaceUnit = async (params: WorkspaceUnitCtorParams) => {
return workspaceUnit;
};
+
+interface PendingTask {
+ id: string;
+ blob: ArrayBufferLike;
+}
+
+export const migrateBlobDB = async (
+ oldWorkspaceId: string,
+ newWorkspaceId: string
+) => {
+ const oldDB = getDatabase('blob', oldWorkspaceId);
+ const oldPendingDB = getDatabase('pending', newWorkspaceId);
+
+ const newDB = getDatabase('blob', newWorkspaceId);
+ const newPendingDB = getDatabase('pending', newWorkspaceId);
+
+ const keys = await oldDB.keys();
+ const values = await oldDB.getMany(keys);
+ const entries = keys.map((key, index) => {
+ return [key, values[index]] as [string, ArrayBufferLike];
+ });
+ await newDB.setMany(entries);
+
+ const pendingEntries = entries.map(([id, blob]) => {
+ return [id, { id, blob }] as [string, PendingTask];
+ });
+ await newPendingDB.setMany(pendingEntries);
+
+ await oldDB.deleteDB();
+ await oldPendingDB.deleteDB();
+};
diff --git a/packages/i18n/src/resources/en.json b/packages/i18n/src/resources/en.json
index 9b543416dd..d7c00b1d30 100644
--- a/packages/i18n/src/resources/en.json
+++ b/packages/i18n/src/resources/en.json
@@ -69,7 +69,7 @@
"Remove from favourites": "Remove from favourites",
"Removed from Favourites": "Removed from Favourites",
"New Workspace": "New Workspace",
- "Workspace description": "Workspace is your virtual space to capture, create and plan as just one person or together as a team.",
+ "Workspace description": "A workspace is your virtual space to capture, create and plan as just one person or together as a team.",
"Create": "Create",
"Select": "Select",
"Text": "Text (coming soon)",
@@ -108,10 +108,10 @@
"emptyTrash": "Click Add to Trash and the page will appear here.",
"still designed": "(This page is still being designed.)",
"My Workspaces": "My Workspaces",
- "Create Or Import": "Create Or Import",
+ "Create Or Import": "Create or Import",
"Tips": "Tips: ",
"login success": "Login success",
- "Sign out": "Sign out of AFFiNE Cloud",
+ "Sign out": "Sign out",
"Delete Workspace": "Delete Workspace",
"Delete Workspace Description2": "Deleting (<1>{{workspace}}1>) will delete both local and cloud data, this operation cannot be undone, please proceed with caution.",
"Delete Workspace placeholder": "Please type “Delete” to confirm",
@@ -135,7 +135,7 @@
"Publishing Description": "After publishing to the web, everyone can view the content of this workspace through the link.",
"Stop publishing": "Stop publishing",
"Publish to web": "Publish to web",
- "Download data to device": "Download {{CoreOrAll}} data to device",
+ "Download data": "Download {{CoreOrAll}} data",
"General": "General",
"Sync": "Sync",
"Collaboration": "Collaboration",
@@ -143,11 +143,36 @@
"Workspace Settings": "Workspace Settings",
"Export Workspace": "Export Workspace <1>{{workspace}}1> is coming soon",
"Leave Workspace Description": "After you leave, you will no longer be able to access the contents of this workspace.",
- "Sign in": "Sign in to AFFiNE Cloud",
+ "Sign in": "Sign in AFFiNE Cloud",
"Sync Description": "{{workspaceName}} is a Local Workspace. All data is stored on the current device. You can enable AFFiNE Cloud for this workspace to keep data in sync with the cloud.",
"Sync Description2": "<1>{{workspaceName}}1> is a Cloud Workspace. All data will be synchronised and saved to AFFiNE Cloud.",
"Delete Workspace Description": "Deleting (<1>{{workspace}}1>) cannot be undone, please proceed with caution. All contents will be lost.",
"core": "core",
"all": "all",
- "A workspace is your virtual space to capture, create and plan as just one person or together as a team.": "A workspace is your virtual space to capture, create and plan as just one person or together as a team."
+ "Back Home": "Back Home",
+ "Set a Workspace name": "Set a Workspace name",
+ "Retain local cached data": "Retain local cached data",
+ "Wait for Sync": "Wait for Sync",
+ "Force Sign Out": "Force Sign Out",
+ "Local Workspace": "Local Workspace",
+ "Cloud Workspace": "Cloud Workspace",
+ "Joined Workspace": "Joined Workspace",
+ "Available Offline": "Available Offline",
+ "Published to Web": "Published to Web",
+ "Workspace Avatar": "Workspace Avatar",
+ "Owner": "Owner",
+ "Member": "Member",
+ "Delete Member?": "Delete Member?",
+ "will delete member": "will delete member",
+ "Member has been removed": "{{name}} has been removed",
+ "Failed to publish workspace": "Failed to publish workspace",
+ "Copied link to clipboard": "Copied link to clipboard",
+ "Published Description": " The current workspace has been published to the web, everyone can view the contents of this workspace through the link.",
+ "is a Local Workspace": "is a Local Workspace.",
+ "is a Cloud Workspace": "is a Cloud Workspace.",
+ "Local Workspace Description": "All data is stored on the current device. You can enable AFFiNE Cloud for this workspace to keep data in sync with the cloud.",
+ "Cloud Workspace Description": "All data will be synchronized and saved to the AFFiNE account <1>{{email}}1>",
+ "Download data Description1": "It takes up more space on your device.",
+ "Download data Description2": "It takes up little space on your device.",
+ "Enabled success": "Enabled success"
}