From 743c7212fe659a37ee0a1efe86165b01cd479649 Mon Sep 17 00:00:00 2001
From: JimmFly
Date: Mon, 16 Jan 2023 17:40:14 +0800
Subject: [PATCH 01/14] feat: adapt the quick search to the public page
---
.../app/src/components/quick-search/Input.tsx | 8 +-
.../quick-search/PublishedResults.tsx | 95 +++++++++++++++++++
.../app/src/components/quick-search/index.tsx | 67 +++++++++----
packages/app/src/hooks/use-page-helper.ts | 20 +++-
4 files changed, 162 insertions(+), 28 deletions(-)
create mode 100644 packages/app/src/components/quick-search/PublishedResults.tsx
diff --git a/packages/app/src/components/quick-search/Input.tsx b/packages/app/src/components/quick-search/Input.tsx
index 6d96d239b0..e39d92e6b9 100644
--- a/packages/app/src/components/quick-search/Input.tsx
+++ b/packages/app/src/components/quick-search/Input.tsx
@@ -8,17 +8,17 @@ import React, {
import { SearchIcon } from '@blocksuite/icons';
import { StyledInputContent, StyledLabel } from './style';
import { Command } from 'cmdk';
-import { useAppState } from '@/providers/app-state-provider';
import { useTranslation } from '@affine/i18n';
export const Input = (props: {
query: string;
setQuery: Dispatch>;
setLoading: Dispatch>;
+ isPublic: boolean;
+ publishWorkspaceName: string | undefined;
}) => {
const [isComposition, setIsComposition] = useState(false);
const [inputValue, setInputValue] = useState('');
const inputRef = useRef(null);
- const { currentWorkspace } = useAppState();
const { t } = useTranslation();
useEffect(() => {
inputRef.current?.addEventListener(
@@ -78,9 +78,9 @@ export const Input = (props: {
}
}}
placeholder={
- currentWorkspace?.isPublish
+ props.isPublic
? t('Quick search placeholder2', {
- workspace: currentWorkspace?.blocksuiteWorkspace?.meta.name,
+ workspace: props.publishWorkspaceName,
})
: t('Quick search placeholder')
}
diff --git a/packages/app/src/components/quick-search/PublishedResults.tsx b/packages/app/src/components/quick-search/PublishedResults.tsx
new file mode 100644
index 0000000000..2a99737110
--- /dev/null
+++ b/packages/app/src/components/quick-search/PublishedResults.tsx
@@ -0,0 +1,95 @@
+import { Command } from 'cmdk';
+import { StyledListItem, StyledNotFound } from './style';
+import { PaperIcon, EdgelessIcon } from '@blocksuite/icons';
+import { Dispatch, SetStateAction, useEffect, useState } from 'react';
+import { useAppState, PageMeta } from '@/providers/app-state-provider';
+import { useRouter } from 'next/router';
+import { NoResultSVG } from './NoResultSVG';
+import { useTranslation } from '@affine/i18n';
+import usePageHelper from '@/hooks/use-page-helper';
+import { Workspace } from '@blocksuite/store';
+
+export const PublishedResults = (props: {
+ query: string;
+ loading: boolean;
+ setLoading: Dispatch>;
+ setPublishWorkspaceName: Dispatch>;
+ onClose: () => void;
+}) => {
+ const [workspace, setWorkspace] = useState();
+ const { query, loading, setLoading, onClose, setPublishWorkspaceName } =
+ props;
+ const { search } = usePageHelper();
+ const [results, setResults] = useState(new Map());
+ const { dataCenter } = useAppState();
+ const router = useRouter();
+ const [pageList, setPageList] = useState([]);
+ useEffect(() => {
+ dataCenter
+ .loadPublicWorkspace(router.query.workspaceId as string)
+ .then(data => {
+ setPageList(data.blocksuiteWorkspace?.meta.pageMetas as PageMeta[]);
+ if (data && data.blocksuiteWorkspace) {
+ setWorkspace(data.blocksuiteWorkspace);
+ setPublishWorkspaceName(data.blocksuiteWorkspace.meta.name);
+ }
+ })
+ .catch(() => {
+ router.push('/404');
+ });
+ }, [router, dataCenter, setPublishWorkspaceName]);
+ const { t } = useTranslation();
+ useEffect(() => {
+ setResults(search(query, workspace));
+ setLoading(false);
+ //Save the Map obtained from the search as state
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [query, setResults, setLoading]);
+ const pageIds = [...results.values()];
+ const resultsPageMeta = pageList.filter(
+ page => pageIds.indexOf(page.id) > -1 && !page.trash
+ );
+
+ return loading ? null : (
+ <>
+ {query ? (
+ resultsPageMeta.length ? (
+
+ {resultsPageMeta.map(result => {
+ return (
+ {
+ router.push(
+ `/public-workspace/${router.query.workspaceId}/${result.id}`
+ );
+ onClose();
+ }}
+ value={result.id}
+ >
+
+ {result.mode === 'edgeless' ? (
+
+ ) : (
+
+ )}
+ {result.title}
+
+
+ );
+ })}
+
+ ) : (
+
+ {t('Find 0 result')}
+
+
+ )
+ ) : (
+ <>>
+ )}
+ >
+ );
+};
diff --git a/packages/app/src/components/quick-search/index.tsx b/packages/app/src/components/quick-search/index.tsx
index 9d6e477968..9400f72031 100644
--- a/packages/app/src/components/quick-search/index.tsx
+++ b/packages/app/src/components/quick-search/index.tsx
@@ -13,7 +13,8 @@ import { Command } from 'cmdk';
import { useEffect, useState } from 'react';
import { useModal } from '@/providers/GlobalModalProvider';
import { getUaHelper } from '@/utils';
-import { useAppState } from '@/providers/app-state-provider';
+import { useRouter } from 'next/router';
+import { PublishedResults } from './PublishedResults';
type TransitionsModalProps = {
open: boolean;
onClose: () => void;
@@ -22,10 +23,11 @@ const isMac = () => {
return getUaHelper().isMacOs;
};
export const QuickSearch = ({ open, onClose }: TransitionsModalProps) => {
- const { currentWorkspace } = useAppState();
-
+ const router = useRouter();
const [query, setQuery] = useState('');
const [loading, setLoading] = useState(true);
+ const [isPublic, setIsPublic] = useState(false);
+ const [publishWorkspaceName, setPublishWorkspaceName] = useState('');
const [showCreatePage, setShowCreatePage] = useState(true);
const { triggerQuickSearchModal } = useModal();
@@ -51,6 +53,17 @@ export const QuickSearch = ({ open, onClose }: TransitionsModalProps) => {
document.removeEventListener('keydown', down, { capture: true });
}, [open, triggerQuickSearchModal]);
+ useEffect(() => {
+ if (
+ router.pathname === '/public-workspace/[workspaceId]/[pageId]' ||
+ router.pathname === '/public-workspace/[workspaceId]'
+ ) {
+ return setIsPublic(true);
+ } else {
+ return setIsPublic(false);
+ }
+ }, [router]);
+
return (
{
}}
>
-
+
{isMac() ? '⌘ + K' : 'Ctrl + K'}
-
+ {!isPublic ? (
+
+ ) : (
+
+ )}
- {currentWorkspace?.published ? (
- <>>
- ) : showCreatePage ? (
- <>
-
-
-
-
- >
+ {!isPublic ? (
+ showCreatePage ? (
+ <>
+
+
+
+
+ >
+ ) : null
) : null}
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);
From d9ad8ee6086c7792197928c62ac11b814dba97bf Mon Sep 17 00:00:00 2001
From: JimmFly
Date: Mon, 16 Jan 2023 17:43:37 +0800
Subject: [PATCH 02/14] fix: deepScan warning
---
packages/app/src/components/quick-search/PublishedResults.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/app/src/components/quick-search/PublishedResults.tsx b/packages/app/src/components/quick-search/PublishedResults.tsx
index 2a99737110..d0564b4cd7 100644
--- a/packages/app/src/components/quick-search/PublishedResults.tsx
+++ b/packages/app/src/components/quick-search/PublishedResults.tsx
@@ -29,7 +29,7 @@ export const PublishedResults = (props: {
.loadPublicWorkspace(router.query.workspaceId as string)
.then(data => {
setPageList(data.blocksuiteWorkspace?.meta.pageMetas as PageMeta[]);
- if (data && data.blocksuiteWorkspace) {
+ if (data.blocksuiteWorkspace) {
setWorkspace(data.blocksuiteWorkspace);
setPublishWorkspaceName(data.blocksuiteWorkspace.meta.name);
}
From 21f9f87cb2e4353d4dc27bf0d70862d408ffffae Mon Sep 17 00:00:00 2001
From: JimmFly
Date: Tue, 17 Jan 2023 10:41:53 +0800
Subject: [PATCH 03/14] chore: optimize code
---
packages/app/src/components/quick-search/index.tsx | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/packages/app/src/components/quick-search/index.tsx b/packages/app/src/components/quick-search/index.tsx
index 9400f72031..7c24f0b970 100644
--- a/packages/app/src/components/quick-search/index.tsx
+++ b/packages/app/src/components/quick-search/index.tsx
@@ -54,10 +54,7 @@ export const QuickSearch = ({ open, onClose }: TransitionsModalProps) => {
}, [open, triggerQuickSearchModal]);
useEffect(() => {
- if (
- router.pathname === '/public-workspace/[workspaceId]/[pageId]' ||
- router.pathname === '/public-workspace/[workspaceId]'
- ) {
+ if (router.pathname.startsWith('/public-workspace')) {
return setIsPublic(true);
} else {
return setIsPublic(false);
From 8574ba596b2c7380a436dc786e5e4b3f64ccee0a Mon Sep 17 00:00:00 2001
From: JimmFly
Date: Mon, 30 Jan 2023 14:49:09 +0800
Subject: [PATCH 04/14] feat: add breadcrumb ui component
---
packages/app/src/ui/breadcrumbs/index.ts | 2 ++
1 file changed, 2 insertions(+)
create mode 100644 packages/app/src/ui/breadcrumbs/index.ts
diff --git a/packages/app/src/ui/breadcrumbs/index.ts b/packages/app/src/ui/breadcrumbs/index.ts
new file mode 100644
index 0000000000..82fda906d5
--- /dev/null
+++ b/packages/app/src/ui/breadcrumbs/index.ts
@@ -0,0 +1,2 @@
+import MuiBreadcrumbs from '@mui/material/Breadcrumbs';
+export { MuiBreadcrumbs };
From fec1944fa9b7fc822e64ef124069631274237c8f Mon Sep 17 00:00:00 2001
From: JimmFly
Date: Mon, 30 Jan 2023 19:03:52 +0800
Subject: [PATCH 05/14] chore: modify the breadcrumb style
---
packages/app/src/ui/breadcrumbs/index.ts | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/packages/app/src/ui/breadcrumbs/index.ts b/packages/app/src/ui/breadcrumbs/index.ts
index 82fda906d5..007554be72 100644
--- a/packages/app/src/ui/breadcrumbs/index.ts
+++ b/packages/app/src/ui/breadcrumbs/index.ts
@@ -1,2 +1,8 @@
import MuiBreadcrumbs from '@mui/material/Breadcrumbs';
-export { MuiBreadcrumbs };
+import { styled } from '@/styles';
+
+export const Breadcrumbs = styled(MuiBreadcrumbs)(({ theme }) => {
+ return {
+ color: theme.colors.popoverColor,
+ };
+});
From 5bd95f68c263c1a8a519ae37f84fa40bbfa6557a Mon Sep 17 00:00:00 2001
From: JimmFly
Date: Mon, 30 Jan 2023 19:04:36 +0800
Subject: [PATCH 06/14] feat: add public page navigation bar
---
.../[workspaceId]/[pageId].tsx | 75 ++++++++++++++++++-
.../public-workspace/[workspaceId]/index.tsx | 31 +++++++-
2 files changed, 102 insertions(+), 4 deletions(-)
diff --git a/packages/app/src/pages/public-workspace/[workspaceId]/[pageId].tsx b/packages/app/src/pages/public-workspace/[workspaceId]/[pageId].tsx
index 4993246384..598028f5a5 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,11 +22,15 @@ 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 => {
+ setWorkspaceName(data.blocksuiteWorkspace?.meta.name as string);
if (data && data.blocksuiteWorkspace) {
setWorkspace(data.blocksuiteWorkspace);
if (
@@ -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}
From 9ee78221a7d3d5eaed2b06d9f7e82b8bd52db03d Mon Sep 17 00:00:00 2001
From: JimmFly
Date: Mon, 30 Jan 2023 19:06:52 +0800
Subject: [PATCH 07/14] chore: fix deepScan warning
---
.../app/src/pages/public-workspace/[workspaceId]/[pageId].tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/app/src/pages/public-workspace/[workspaceId]/[pageId].tsx b/packages/app/src/pages/public-workspace/[workspaceId]/[pageId].tsx
index 598028f5a5..7fb0efc002 100644
--- a/packages/app/src/pages/public-workspace/[workspaceId]/[pageId].tsx
+++ b/packages/app/src/pages/public-workspace/[workspaceId]/[pageId].tsx
@@ -31,7 +31,7 @@ const Page: NextPageWithLayout = () => {
.loadPublicWorkspace(router.query.workspaceId as string)
.then(data => {
setWorkspaceName(data.blocksuiteWorkspace?.meta.name as string);
- if (data && data.blocksuiteWorkspace) {
+ if (data.blocksuiteWorkspace) {
setWorkspace(data.blocksuiteWorkspace);
if (
router.query.pageId &&
From 65f4f05c04a94c4b5e43b5e4535049f8520d8edd Mon Sep 17 00:00:00 2001
From: JimmFly
Date: Tue, 31 Jan 2023 15:29:04 +0800
Subject: [PATCH 08/14] chore: add translation function
---
packages/app/src/components/404/index.tsx | 2 +-
.../app/src/components/create-workspace/index.tsx | 7 ++-----
packages/app/src/components/login-modal/index.tsx | 6 ++++--
packages/app/src/components/logout-modal/index.tsx | 12 +++++++-----
.../app/src/components/workspace-modal/index.tsx | 8 +++-----
5 files changed, 17 insertions(+), 18 deletions(-)
diff --git a/packages/app/src/components/404/index.tsx b/packages/app/src/components/404/index.tsx
index 36f1b90a34..0a06467afa 100644
--- a/packages/app/src/components/404/index.tsx
+++ b/packages/app/src/components/404/index.tsx
@@ -15,7 +15,7 @@ export const NotfoundPage = () => {
router.push('/workspace');
}}
>
- Back Home
+ {t('Back Home')}
diff --git a/packages/app/src/components/create-workspace/index.tsx b/packages/app/src/components/create-workspace/index.tsx
index 9a26b56863..11aa3de52b 100644
--- a/packages/app/src/components/create-workspace/index.tsx
+++ b/packages/app/src/components/create-workspace/index.tsx
@@ -53,13 +53,10 @@ export const CreateWorkspaceModal = ({ open, onClose }: ModalProps) => {
{t('New Workspace')}
-
- Workspace is your virtual space to capture, create and plan as
- just one person or together as a team.
-
+ {t('Workspace description')}
{
setWorkspaceName(value);
}}
diff --git a/packages/app/src/components/login-modal/index.tsx b/packages/app/src/components/login-modal/index.tsx
index f6dedd7cd8..8c15c24417 100644
--- a/packages/app/src/components/login-modal/index.tsx
+++ b/packages/app/src/components/login-modal/index.tsx
@@ -2,6 +2,7 @@ import { styled } from '@/styles';
import { Modal, ModalWrapper, ModalCloseButton } from '@/ui/modal';
import { GoogleLoginButton } from './LoginOptionButton';
import { useAppState } from '@/providers/app-state-provider';
+import { useTranslation } from '@affine/i18n';
interface LoginModalProps {
open: boolean;
onClose: () => void;
@@ -9,6 +10,7 @@ interface LoginModalProps {
export const LoginModal = ({ open, onClose }: LoginModalProps) => {
const { login } = useAppState();
+ const { t } = useTranslation();
return (
@@ -20,8 +22,8 @@ export const LoginModal = ({ open, onClose }: LoginModalProps) => {
/>
- {'Sign in'}
- Set up an AFFINE account to sync data
+ {t('Sign in')}
+ {t('Set up an AFFiNE account to sync data')}
{
await login();
diff --git a/packages/app/src/components/logout-modal/index.tsx b/packages/app/src/components/logout-modal/index.tsx
index 0aaee3968e..b317f1183c 100644
--- a/packages/app/src/components/logout-modal/index.tsx
+++ b/packages/app/src/components/logout-modal/index.tsx
@@ -3,6 +3,7 @@ import { Modal, ModalWrapper, ModalCloseButton } from '@/ui/modal';
import { Button } from '@/ui/button';
import { Check, UnCheck } from './icon';
import { useState } from 'react';
+import { useTranslation } from '@affine/i18n';
interface LoginModalProps {
open: boolean;
onClose: (wait: boolean) => void;
@@ -10,6 +11,7 @@ interface LoginModalProps {
export const LogoutModal = ({ open, onClose }: LoginModalProps) => {
const [localCache, setLocalCache] = useState(false);
+ const { t } = useTranslation();
return (
@@ -21,8 +23,8 @@ export const LogoutModal = ({ open, onClose }: LoginModalProps) => {
/>
- {'Sign out?'}
- Set up an AFFINE account to sync data
+ {t('Sign out')}?
+ {t('Set up an AFFiNE account to sync data')}
{localCache ? (
{
)}
- Retain local cached data
+ {t('Retain local cached data')}
{
onClose(true);
}}
>
- Wait for Sync
+ {t('Wait for Sync')}
{
onClose(false);
}}
>
- Force Sign Out
+ {t('Force Sign Out')}
diff --git a/packages/app/src/components/workspace-modal/index.tsx b/packages/app/src/components/workspace-modal/index.tsx
index 93b1bb7279..4ebce59edf 100644
--- a/packages/app/src/components/workspace-modal/index.tsx
+++ b/packages/app/src/components/workspace-modal/index.tsx
@@ -59,9 +59,7 @@ export const WorkspaceModal = ({ open, onClose }: WorkspaceModalProps) => {
{t('My Workspaces')}
@@ -108,8 +106,8 @@ export const WorkspaceModal = ({ open, onClose }: WorkspaceModalProps) => {
- New workspace
- Crete or import
+ {t('New Workspace')}
+ {t('Create Or Import')}
From e501026d28f7c00ec120239d90a7faffaecee78d Mon Sep 17 00:00:00 2001
From: JimmFly
Date: Tue, 31 Jan 2023 15:29:35 +0800
Subject: [PATCH 09/14] feat: update i18n keys
---
packages/i18n/src/resources/en.json | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/packages/i18n/src/resources/en.json b/packages/i18n/src/resources/en.json
index 9b543416dd..e01cdc7b49 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",
@@ -143,11 +143,15 @@
"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"
}
From a9bbaed22cbb165a748678a0ac378b088a2dbc8b Mon Sep 17 00:00:00 2001
From: JimmFly
Date: Tue, 31 Jan 2023 18:34:18 +0800
Subject: [PATCH 10/14] chore: add translation function
---
.../src/components/workspace-modal/Footer.tsx | 4 +-
.../workspace-modal/WorkspaceCard.tsx | 14 ++--
.../workspace-setting/PublishPage.tsx | 15 ++--
.../components/workspace-setting/SyncPage.tsx | 51 +++++++------
.../workspace-setting/general/General.tsx | 8 +--
.../workspace-setting/member/MembersPage.tsx | 20 +++---
.../src/components/workspace-setting/style.ts | 30 ++++----
.../app/src/hooks/use-workspace-helper.ts | 12 ++--
.../pages/workspace/[workspaceId]/setting.tsx | 72 ++++++++++---------
9 files changed, 123 insertions(+), 103 deletions(-)
diff --git a/packages/app/src/components/workspace-modal/Footer.tsx b/packages/app/src/components/workspace-modal/Footer.tsx
index ea38de2a9c..c27b004e8b 100644
--- a/packages/app/src/components/workspace-modal/Footer.tsx
+++ b/packages/app/src/components/workspace-modal/Footer.tsx
@@ -4,6 +4,7 @@ import { WorkspaceAvatar } from '@/components/workspace-avatar';
import { IconButton } from '@/ui/button';
import { useAppState } from '@/providers/app-state-provider';
import { StyledFooter, StyleUserInfo, StyleSignIn } from './styles';
+import { useTranslation } from '@affine/i18n';
export const Footer = ({
onLogin,
@@ -13,6 +14,7 @@ export const Footer = ({
onLogout: () => void;
}) => {
const { user } = useAppState();
+ const { t } = useTranslation();
return (
@@ -48,7 +50,7 @@ export const Footer = ({
- Sign in to sync with AFFINE Cloud
+ {t('Sign in')}
)}
diff --git a/packages/app/src/components/workspace-modal/WorkspaceCard.tsx b/packages/app/src/components/workspace-modal/WorkspaceCard.tsx
index 1a6032d65f..9bc523e2fb 100644
--- a/packages/app/src/components/workspace-modal/WorkspaceCard.tsx
+++ b/packages/app/src/components/workspace-modal/WorkspaceCard.tsx
@@ -9,6 +9,7 @@ import { WorkspaceUnit } from '@affine/datacenter';
import { useAppState } from '@/providers/app-state-provider';
import { StyleWorkspaceInfo, StyleWorkspaceTitle, StyledCard } from './styles';
import { Wrapper } from '@/ui/layout';
+import { useTranslation } from '@affine/i18n';
export const WorkspaceCard = ({
workspaceData,
@@ -18,7 +19,7 @@ export const WorkspaceCard = ({
onClick: (data: WorkspaceUnit) => void;
}) => {
const { currentWorkspace, isOwner } = useAppState();
-
+ const { t } = useTranslation();
return (
{
@@ -38,29 +39,30 @@ export const WorkspaceCard = ({
workspaceData.provider === 'local' ? (
- Local Workspace
+ {t('Local Workspace')}
) : (
- Cloud Workspace
+ {t('Cloud Workspace')}
)
) : (
- Joined Workspace
+ {t('Joined Workspace')}
)}
{workspaceData.provider === 'local' && (
- All data can be accessed offline
+ {t('Available Offline')}
)}
{workspaceData.published && (
- Published to Web
+
+ {t('Published to Web')}
)}
diff --git a/packages/app/src/components/workspace-setting/PublishPage.tsx b/packages/app/src/components/workspace-setting/PublishPage.tsx
index a30b72bdf7..677b8a4909 100644
--- a/packages/app/src/components/workspace-setting/PublishPage.tsx
+++ b/packages/app/src/components/workspace-setting/PublishPage.tsx
@@ -1,5 +1,5 @@
import {
- StyledCopyButtonContainer,
+ StyledButtonContainer,
StyledPublishContent,
StyledPublishCopyContainer,
StyledPublishExplanation,
@@ -24,13 +24,13 @@ export const PublishPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
try {
await publishWorkspace(workspace.id.toString(), flag);
} catch (e) {
- toast('Failed to publish workspace');
+ toast(t('Failed to publish workspace'));
}
};
const copyUrl = () => {
navigator.clipboard.writeText(shareUrl);
- toast('Copied url to clipboard');
+ toast(t('Copied link to clipboard'));
};
return (
@@ -43,8 +43,7 @@ export const PublishPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
{workspace.published ? (
<>
- The current workspace has been published to the web, everyone
- can view the contents of this workspace through the link.
+ {t('Published Description')}
@@ -52,11 +51,11 @@ export const PublishPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
{t('Share with link')}
-
+
{t('Copy Link')}
-
+
>
) : (
@@ -103,7 +102,7 @@ export const PublishPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
<>
- Publishing to web requires AFFiNE Cloud service.
+ {t('Publishing')}
diff --git a/packages/app/src/components/workspace-setting/SyncPage.tsx b/packages/app/src/components/workspace-setting/SyncPage.tsx
index 6969461a38..0632b304c0 100644
--- a/packages/app/src/components/workspace-setting/SyncPage.tsx
+++ b/packages/app/src/components/workspace-setting/SyncPage.tsx
@@ -1,9 +1,9 @@
import {
- StyleAsync,
+ StyledButtonContainer,
StyledPublishContent,
StyledPublishExplanation,
StyledWorkspaceName,
- StyledWorkspaceType,
+ StyledEmail,
} from './style';
import { DownloadIcon } from '@blocksuite/icons';
import { Button } from '@/ui/button';
@@ -26,27 +26,38 @@ 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')}
+
-
+
>
) : (
<>
-
- {{ workspaceName: workspace.name ?? 'Affine' }}
- is Cloud Workspace. All data will be synchronised and saved to
- the AFFiNE
-
+
+ {workspace.name}
+ {t('is a Cloud Workspace')}
-
+
+
+ All data will be synchronised and saved to the AFFiNE account
+
+ {{
+ email: '{' + workspace.owner?.email + '}.',
+ }}
+
+
+
+
+
@@ -56,7 +67,7 @@ export const SyncPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
}}
icon={ }
>
- {t('Download data to device', { CoreOrAll: 'core' })}
+ {t('Download data', { CoreOrAll: t('core') })}
{
@@ -64,7 +75,7 @@ export const SyncPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
}}
icon={ }
>
- {t('Download data to device', { CoreOrAll: 'all' })}
+ {t('Download data', { CoreOrAll: t('all') })}
>
}
@@ -72,10 +83,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 b1b64ffa0e..73405599b9 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 dcde665f31..eafcd415d2 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,21 +130,23 @@ 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',
- };
-});
-
-export const StyleAsync = styled('div')(() => {
- return {
- marginTop: '64px',
+ fontSize: theme.font.base,
+ lineHeight: theme.font.lineHeightBase,
};
});
diff --git a/packages/app/src/hooks/use-workspace-helper.ts b/packages/app/src/hooks/use-workspace-helper.ts
index 2a1977f968..44124ae615 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/workspace/[workspaceId]/setting.tsx b/packages/app/src/pages/workspace/[workspaceId]/setting.tsx
index 11de4aa598..bd80a4ecfe 100644
--- a/packages/app/src/pages/workspace/[workspaceId]/setting.tsx
+++ b/packages/app/src/pages/workspace/[workspaceId]/setting.tsx
@@ -20,41 +20,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 => ,
- },
-
- {
- name: 'Export',
- panelRender: workspace => ,
- },
-];
-
-const WorkspaceSetting = () => {
+const useTabMap = () => {
const { t } = useTranslation();
- const { currentWorkspace, isOwner } = useAppState();
+ 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 => ,
+ },
- const [activeTab, setActiveTab] = useState(tabMap[0].name);
- const handleTabChange = (tab: TabNames) => {
+ {
+ name: t('Export'),
+ panelRender: workspace => ,
+ },
+ ];
+ const [activeTab, setActiveTab] = useState(tabMap[0].name);
+ const handleTabChange = (tab: string) => {
setActiveTab(tab);
};
@@ -62,7 +58,7 @@ const WorkspaceSetting = () => {
tab => tab.name === activeTab
)?.panelRender;
let tableArr: {
- name: TabNames;
+ name: string;
panelRender: (workspace: WorkspaceUnit) => ReactNode;
}[] = tabMap;
if (!isOwner) {
@@ -73,6 +69,14 @@ const WorkspaceSetting = () => {
},
];
}
+ return { activeTabPanelRender, tableArr, handleTabChange, activeTab };
+};
+
+const WorkspaceSetting = () => {
+ const { t } = useTranslation();
+ const { currentWorkspace } = useAppState();
+ const { activeTabPanelRender, tableArr, handleTabChange, activeTab } =
+ useTabMap();
return (
<>
From 08ce7d5322216f879e494b34b9016e8550e0f1f7 Mon Sep 17 00:00:00 2001
From: JimmFly
Date: Tue, 31 Jan 2023 18:34:50 +0800
Subject: [PATCH 11/14] feat: update i18n keys
---
packages/i18n/src/resources/en.json | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/packages/i18n/src/resources/en.json b/packages/i18n/src/resources/en.json
index e01cdc7b49..d7c00b1d30 100644
--- a/packages/i18n/src/resources/en.json
+++ b/packages/i18n/src/resources/en.json
@@ -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",
@@ -153,5 +153,26 @@
"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"
+ "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"
}
From 20ffbe348a4fabd1cd26523f1998dd6218d52053 Mon Sep 17 00:00:00 2001
From: JimmFly
Date: Wed, 1 Feb 2023 10:37:30 +0800
Subject: [PATCH 12/14] fix: closeButton not work
---
packages/app/src/ui/modal/ModalCloseButton.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/app/src/ui/modal/ModalCloseButton.tsx b/packages/app/src/ui/modal/ModalCloseButton.tsx
index b42d687ca7..f5e4eaf079 100644
--- a/packages/app/src/ui/modal/ModalCloseButton.tsx
+++ b/packages/app/src/ui/modal/ModalCloseButton.tsx
@@ -28,7 +28,7 @@ export const ModalCloseButton = ({
) : (
-
+
);
From 01310e1650c12f4146163de644565ea3dbdeabbc Mon Sep 17 00:00:00 2001
From: Qi <474021214@qq.com>
Date: Wed, 1 Feb 2023 10:46:59 +0800
Subject: [PATCH 13/14] Feat/UI (#751)
---
packages/app/src/components/import/index.tsx | 6 +--
.../components/page-list/OperationCell.tsx | 10 ++--
.../src/components/workspace-modal/Footer.tsx | 6 +--
.../workspace-modal/WorkspaceCard.tsx | 6 +--
.../src/components/workspace-modal/index.tsx | 6 +--
.../src/components/workspace-modal/styles.ts | 3 +-
.../workspace-setting/member/MembersPage.tsx | 6 +--
packages/app/src/styles/helper.ts | 4 +-
packages/app/src/ui/layout/Content.tsx | 17 ++++++-
packages/app/src/ui/layout/Wrapper.tsx | 49 +++++++++++++++----
.../app/src/ui/modal/ModalCloseButton.tsx | 2 +-
11 files changed, 80 insertions(+), 35 deletions(-)
diff --git a/packages/app/src/components/import/index.tsx b/packages/app/src/components/import/index.tsx
index a594b08e35..d8eaa2ffd5 100644
--- a/packages/app/src/components/import/index.tsx
+++ b/packages/app/src/components/import/index.tsx
@@ -1,7 +1,7 @@
import { Modal, ModalWrapper, ModalCloseButton } from '@/ui/modal';
import { StyledButtonWrapper, StyledTitle } from './styles';
import { Button } from '@/ui/button';
-import { Wrapper, Content } from '@/ui/layout';
+import { Content, FlexWrapper } from '@/ui/layout';
import Loading from '@/components/loading';
import { usePageHelper } from '@/hooks/use-page-helper';
import { useAppState } from '@/providers/app-state-provider';
@@ -116,7 +116,7 @@ export const ImportModal = ({ open, onClose }: ImportModalProps) => {
)}
{status === 'importing' && (
- {
OOOOPS! Sorry forgot to remind you that we are working on the
import function
-
+
)}
diff --git a/packages/app/src/components/page-list/OperationCell.tsx b/packages/app/src/components/page-list/OperationCell.tsx
index ca59efa60a..a9efc634c4 100644
--- a/packages/app/src/components/page-list/OperationCell.tsx
+++ b/packages/app/src/components/page-list/OperationCell.tsx
@@ -1,7 +1,7 @@
import { useConfirm } from '@/providers/ConfirmProvider';
import { PageMeta } from '@/providers/app-state-provider';
import { Menu, MenuItem } from '@/ui/menu';
-import { Wrapper } from '@/ui/layout';
+import { FlexWrapper } from '@/ui/layout';
import { IconButton } from '@/ui/button';
import {
MoreVerticalIcon,
@@ -63,13 +63,13 @@ export const OperationCell = ({ pageMeta }: { pageMeta: PageMeta }) => {
>
);
return (
-
+
-
+
);
};
@@ -80,7 +80,7 @@ export const TrashOperationCell = ({ pageMeta }: { pageMeta: PageMeta }) => {
const { confirm } = useConfirm();
const { t } = useTranslation();
return (
-
+
{
>
-
+
);
};
diff --git a/packages/app/src/components/workspace-modal/Footer.tsx b/packages/app/src/components/workspace-modal/Footer.tsx
index ea38de2a9c..0aef077900 100644
--- a/packages/app/src/components/workspace-modal/Footer.tsx
+++ b/packages/app/src/components/workspace-modal/Footer.tsx
@@ -1,5 +1,5 @@
import { CloudInsyncIcon, LogOutIcon } from '@blocksuite/icons';
-import { Wrapper } from '@/ui/layout';
+import { FlexWrapper } from '@/ui/layout';
import { WorkspaceAvatar } from '@/components/workspace-avatar';
import { IconButton } from '@/ui/button';
import { useAppState } from '@/providers/app-state-provider';
@@ -18,7 +18,7 @@ export const Footer = ({
{user && (
<>
-
+
{user.name}
{user.email}
-
+
{
onLogout();
diff --git a/packages/app/src/components/workspace-modal/WorkspaceCard.tsx b/packages/app/src/components/workspace-modal/WorkspaceCard.tsx
index 1a6032d65f..f3177fbafe 100644
--- a/packages/app/src/components/workspace-modal/WorkspaceCard.tsx
+++ b/packages/app/src/components/workspace-modal/WorkspaceCard.tsx
@@ -8,7 +8,7 @@ import { PublishIcon, UsersIcon } from '@blocksuite/icons';
import { WorkspaceUnit } from '@affine/datacenter';
import { useAppState } from '@/providers/app-state-provider';
import { StyleWorkspaceInfo, StyleWorkspaceTitle, StyledCard } from './styles';
-import { Wrapper } from '@/ui/layout';
+import { FlexWrapper } from '@/ui/layout';
export const WorkspaceCard = ({
workspaceData,
@@ -26,9 +26,9 @@ export const WorkspaceCard = ({
}}
active={workspaceData.id === currentWorkspace?.id}
>
-
+
-
+
diff --git a/packages/app/src/components/workspace-modal/index.tsx b/packages/app/src/components/workspace-modal/index.tsx
index 6799ad5e78..f29c1a1896 100644
--- a/packages/app/src/components/workspace-modal/index.tsx
+++ b/packages/app/src/components/workspace-modal/index.tsx
@@ -1,5 +1,5 @@
import { Modal, ModalWrapper, ModalCloseButton } from '@/ui/modal';
-import { Wrapper } from '@/ui/layout';
+import { FlexWrapper } from '@/ui/layout';
import { useState } from 'react';
import { CreateWorkspaceModal } from '../create-workspace';
@@ -99,11 +99,11 @@ export const WorkspaceModal = ({ open, onClose }: WorkspaceModalProps) => {
setCreateWorkspaceOpen(true);
}}
>
-
+
-
+
New workspace
diff --git a/packages/app/src/components/workspace-modal/styles.ts b/packages/app/src/components/workspace-modal/styles.ts
index 57146afbdf..6796c3a57b 100644
--- a/packages/app/src/components/workspace-modal/styles.ts
+++ b/packages/app/src/components/workspace-modal/styles.ts
@@ -45,6 +45,7 @@ export const StyledCard = styled.div<{
borderRadius: '12px',
border: `1px solid ${borderColor}`,
...displayFlex('flex-start', 'flex-start'),
+ marginBottom: '24px',
':hover': {
background: theme.colors.hoverBackground,
'.add-icon': {
@@ -125,7 +126,7 @@ export const StyledModalContent = styled('div')({
padding: '8px 40px',
marginTop: '72px',
overflow: 'auto',
- ...displayFlex('space-between', 'flex-start', 'column'),
+ ...displayFlex('space-between', 'flex-start', 'flex-start'),
flexWrap: 'wrap',
});
export const StyledOperationWrapper = styled.div(() => {
diff --git a/packages/app/src/components/workspace-setting/member/MembersPage.tsx b/packages/app/src/components/workspace-setting/member/MembersPage.tsx
index b1b64ffa0e..986853652f 100644
--- a/packages/app/src/components/workspace-setting/member/MembersPage.tsx
+++ b/packages/app/src/components/workspace-setting/member/MembersPage.tsx
@@ -25,7 +25,7 @@ import { useConfirm } from '@/providers/ConfirmProvider';
import { toast } from '@/ui/toast';
import useMembers from '@/hooks/use-members';
import Loading from '@/components/loading';
-import { Wrapper } from '@/ui/layout';
+import { FlexWrapper } from '@/ui/layout';
import { useTranslation } from '@affine/i18n';
import { EnableWorkspaceButton } from '@/components/enable-workspace';
@@ -41,9 +41,9 @@ export const MembersPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
{!loaded && (
-
+
-
+
)}
{loaded && members.length === 0 && (
diff --git a/packages/app/src/styles/helper.ts b/packages/app/src/styles/helper.ts
index 3e5949ae3e..20e397f741 100644
--- a/packages/app/src/styles/helper.ts
+++ b/packages/app/src/styles/helper.ts
@@ -2,12 +2,12 @@ import type { CSSProperties } from 'react';
export const displayFlex = (
justifyContent: CSSProperties['justifyContent'] = 'unset',
- alignItems: CSSProperties['alignContent'] = 'unset',
+ alignItems: CSSProperties['alignItems'] = 'unset',
alignContent: CSSProperties['alignContent'] = 'unset'
): {
display: CSSProperties['display'];
justifyContent: CSSProperties['justifyContent'];
- alignItems: CSSProperties['alignContent'];
+ alignItems: CSSProperties['alignItems'];
alignContent: CSSProperties['alignContent'];
} => {
return {
diff --git a/packages/app/src/ui/layout/Content.tsx b/packages/app/src/ui/layout/Content.tsx
index 510f3886a6..38d13251e5 100644
--- a/packages/app/src/ui/layout/Content.tsx
+++ b/packages/app/src/ui/layout/Content.tsx
@@ -14,8 +14,21 @@ export type ContentProps = {
lineNum?: number;
children: string;
};
-
-export const Content = styled.div(
+export const Content = styled('div', {
+ shouldForwardProp: prop => {
+ return ![
+ 'color',
+ 'fontSize',
+ 'weight',
+ 'lineHeight',
+ 'ellipsis',
+ 'lineNum',
+ 'width',
+ 'maxWidth',
+ 'align',
+ ].includes(prop);
+ },
+})(
({
theme,
color,
diff --git a/packages/app/src/ui/layout/Wrapper.tsx b/packages/app/src/ui/layout/Wrapper.tsx
index 00584b20f0..a463312abf 100644
--- a/packages/app/src/ui/layout/Wrapper.tsx
+++ b/packages/app/src/ui/layout/Wrapper.tsx
@@ -2,6 +2,14 @@ import type { CSSProperties } from 'react';
import { styled } from '@/styles';
export type WrapperProps = {
+ display?: CSSProperties['display'];
+ width?: CSSProperties['width'];
+ height?: CSSProperties['height'];
+ padding?: CSSProperties['padding'];
+ margin?: CSSProperties['margin'];
+};
+
+export type FlexWrapperProps = {
display?: CSSProperties['display'];
flexDirection?: CSSProperties['flexDirection'];
justifyContent?: CSSProperties['justifyContent'];
@@ -13,9 +21,22 @@ export type WrapperProps = {
// Sometimes we just want to wrap a component with a div to set flex or other styles, but we don't want to create a new component for it.
export const Wrapper = styled('div', {
+ shouldForwardProp: prop => {
+ return !['display', 'width', 'height', 'padding', 'margin'].includes(prop);
+ },
+})(({ display, width, height, padding, margin }) => {
+ return {
+ display,
+ width,
+ height,
+ padding,
+ margin,
+ };
+});
+
+export const FlexWrapper = styled(Wrapper, {
shouldForwardProp: prop => {
return ![
- 'display',
'justifyContent',
'alignItems',
'wrap',
@@ -24,18 +45,17 @@ export const Wrapper = styled('div', {
'flexGrow',
].includes(prop);
},
-})(
+})(
({
- display = 'flex',
- justifyContent = 'flex-start',
- alignItems = 'center',
+ justifyContent,
+ alignItems,
wrap = false,
- flexDirection = 'row',
- flexShrink = '0',
- flexGrow = '0',
+ flexDirection,
+ flexShrink,
+ flexGrow,
}) => {
return {
- display,
+ display: 'flex',
justifyContent,
alignItems,
flexWrap: wrap ? 'wrap' : 'nowrap',
@@ -46,4 +66,15 @@ export const Wrapper = styled('div', {
}
);
+// TODO: Complete me
+export const GridWrapper = styled(Wrapper, {
+ shouldForwardProp: prop => {
+ return ![''].includes(prop);
+ },
+})(() => {
+ return {
+ display: 'grid',
+ };
+});
+
export default Wrapper;
diff --git a/packages/app/src/ui/modal/ModalCloseButton.tsx b/packages/app/src/ui/modal/ModalCloseButton.tsx
index b42d687ca7..f5e4eaf079 100644
--- a/packages/app/src/ui/modal/ModalCloseButton.tsx
+++ b/packages/app/src/ui/modal/ModalCloseButton.tsx
@@ -28,7 +28,7 @@ export const ModalCloseButton = ({
) : (
-
+
);
From 2a400a103abb47bd970e13651fe1a9b6f9c13061 Mon Sep 17 00:00:00 2001
From: zuomeng wang
Date: Wed, 1 Feb 2023 13:27:24 +0800
Subject: [PATCH 14/14] fix: after enabled cloud sync, we should migrate blob
db (#757)
---
.../data-center/src/provider/affine/affine.ts | 8 ++++-
.../data-center/src/provider/affine/idb-kv.ts | 23 +++++++++++++
.../data-center/src/provider/affine/utils.ts | 32 +++++++++++++++++++
3 files changed, 62 insertions(+), 1 deletion(-)
create mode 100644 packages/data-center/src/provider/affine/idb-kv.ts
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();
+};