diff --git a/packages/app/package.json b/packages/app/package.json index bb66467183..a8c7dc3388 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -9,10 +9,10 @@ "lint": "next lint" }, "dependencies": { - "@blocksuite/blocks": "0.3.0-alpha.5", - "@blocksuite/editor": "0.3.0-alpha.5", + "@blocksuite/blocks": "0.3.0-alpha.6", + "@blocksuite/editor": "0.3.0-alpha.6", "@blocksuite/icons": "^1.0.5", - "@blocksuite/store": "0.3.0-alpha.5", + "@blocksuite/store": "0.3.0-alpha.6", "@emotion/css": "^11.10.0", "@emotion/react": "^11.10.4", "@emotion/server": "^11.10.0", diff --git a/packages/app/src/components/editor.tsx b/packages/app/src/components/editor.tsx index 2c37676351..dfb2a924c5 100644 --- a/packages/app/src/components/editor.tsx +++ b/packages/app/src/components/editor.tsx @@ -12,7 +12,7 @@ export const Editor = () => { editorContainer.current?.appendChild(editor); - initDefaultContent(editor); + // initDefaultContent(editor); } }, [editor]); diff --git a/packages/app/src/components/workspace-slider-bar/index.tsx b/packages/app/src/components/workspace-slider-bar/index.tsx index c2a43673b5..f4236be9f6 100644 --- a/packages/app/src/components/workspace-slider-bar/index.tsx +++ b/packages/app/src/components/workspace-slider-bar/index.tsx @@ -9,8 +9,10 @@ import { } from './style'; import { Arrow } from './icons'; import Link from 'next/link'; +import { useEditor } from '@/providers/editor-provider'; export const WorkSpaceSliderBar = () => { const [show, setShow] = useState(false); + const { createPage } = useEditor(); const router = useRouter(); return ( <> @@ -29,11 +31,9 @@ export const WorkSpaceSliderBar = () => { > Back to Doc - - - All pages - - + + All pages + Favourites document 1, this is a paper icondocument 1 @@ -43,7 +43,13 @@ export const WorkSpaceSliderBar = () => { Import Bin - New Page + { + createPage(); + }} + > + New Page + { return { @@ -14,19 +21,87 @@ const StyledTableContainer = styled.div(() => { overflowY: 'auto', }; }); +const StyledTitleWrapper = styled.div(({ theme }) => { + return { + ...displayFlex('flex-start', 'center'), + 'favorite-heart': {}, + }; +}); +const StyledTitleContent = styled.div(({ theme }) => { + return { + maxWidth: '90%', + marginRight: '18px', + ...textEllipsis(1), + }; +}); +const StyledFavoriteButton = styled.button<{ favorite: boolean }>( + ({ theme, favorite }) => { + return { + width: '32px', + height: '32px', + justifyContent: 'center', + alignItems: 'center', + display: 'none', + color: favorite ? theme.colors.primaryColor : theme.colors.iconColor, + '&:hover': { + color: theme.colors.primaryColor, + }, + }; + } +); +const StyledTableRow = styled(TableRow)(({ theme }) => { + return { + '&:hover': { + '.favorite-button': { + display: 'flex', + }, + }, + }; +}); -const OperationMenu = () => { - return ( +const OperationArea = ({ pageMeta }: { pageMeta: PageMeta }) => { + const { id, favorite } = pageMeta; + const { openPage, toggleFavoritePage, toggleDeletePage } = useEditor(); + + const OperationMenu = ( <> - Add to favourites - Open in new tab - Delete + { + toggleFavoritePage(id); + }} + > + {favorite ? 'Remove' : 'Add'} to favourites + + { + openPage(id); + }} + > + Open in new tab + + { + toggleDeletePage(id); + }} + > + Delete + ); + return ( + + + + + + + + ); }; export const AllPage = () => { const { confirm } = useConfirm(); + const { pageList, toggleFavoritePage } = useEditor(); return ( <>
@@ -53,27 +128,35 @@ export const AllPage = () => { - {new Array(100).fill(0).map((_, index) => { + {pageList.map((pageMeta, index) => { return ( - - - This is a long, very long, extremely long, incredibly long, - exceedingly long, very long document title - - 2022-11-02 18:30 - 2022-11-02 18:30 + - } - placement="bottom-end" - disablePortal={true} - > - - - - + + + {pageMeta.title || pageMeta.id} + + { + toggleFavoritePage(pageMeta.id); + }} + > + {pageMeta.favorite ? ( + + ) : ( + + )} + + - + {pageMeta.createDate} + {pageMeta.createDate} + + + + ); })} diff --git a/packages/app/src/providers/editor-provider/editor-provider.tsx b/packages/app/src/providers/editor-provider/editor-provider.tsx index ea57ac736e..1690dad88e 100644 --- a/packages/app/src/providers/editor-provider/editor-provider.tsx +++ b/packages/app/src/providers/editor-provider/editor-provider.tsx @@ -6,7 +6,14 @@ import Loading from './loading'; import { Page, Workspace } from '@blocksuite/store'; import { BlockSchema } from '@blocksuite/editor/dist/block-loader'; import { useRouter } from 'next/router'; - +export interface PageMeta { + id: string; + title: string; + favorite: boolean; + trash: boolean; + createDate: number; + trashDate: number | null; +} // Blocksuite has to be imported dynamically since it has a lot of effects const DynamicEditor = dynamic(() => import('./initial-editor'), { ssr: false, @@ -17,23 +24,41 @@ type EditorContextValue = { setMode: (mode: EditorContainer['mode']) => void; currentPage: Page | null; editor: EditorContainer | null; -}; + pageList: PageMeta[]; +} & EditorHandlers; -// type EditorHandlers = { -// createPage: (props: { pageId?: string; title?: '' }) => void; -// openPage: (props: { -// pageId: string; -// query?: { [key: string]: string }; -// }) => Promise; -// }; +type EditorHandlers = { + createPage: (pageId?: string) => void; + openPage: ( + pageId: string, + query?: { [key: string]: string } + ) => Promise; + deletePage: (pageId: string) => void; + recyclePage: (pageId: string) => void; + toggleDeletePage: (pageId: string) => void; + favoritePage: (pageId: string) => void; + unFavoritePage: (pageId: string) => void; + toggleFavoritePage: (pageId: string) => void; +}; type EditorContextProps = PropsWithChildren<{}>; export const EditorContext = createContext({ mode: 'page', setMode: () => {}, + pageList: [], currentPage: null, editor: null, + createPage: () => {}, + openPage: async () => { + return false; + }, + deletePage: () => {}, + recyclePage: () => {}, + toggleDeletePage: () => {}, + favoritePage: () => {}, + unFavoritePage: () => {}, + toggleFavoritePage: () => {}, }); export const useEditor = () => useContext(EditorContext); @@ -45,6 +70,7 @@ export const EditorProvider = ({ const blockSchemaRef = useRef(null); const [workspace, setWorkspace] = useState(null); const [currentPage, setCurrentPage] = useState(null); + const [pageList, setPageList] = useState([]); const [editor, setEditor] = useState(null); const [mode, setMode] = useState('page'); @@ -53,18 +79,26 @@ export const EditorProvider = ({ window.dispatchEvent(event); }, [mode]); - const editorHandler = { - createPage: ({ - pageId = new Date().getTime().toString(), - title, - }: { - pageId?: string; - title?: ''; - }) => { + useEffect(() => { + if (!workspace) { + return; + } + setPageList(workspace.meta.pages as PageMeta[]); + workspace.meta.pagesUpdated.on(res => { + setPageList(workspace.meta.pages as PageMeta[]); + }); + return () => { + // TODO: Does it need to be removed? + workspace.meta.pagesUpdated.dispose(); + }; + }, [workspace]); + + const editorHandler: EditorHandlers = { + createPage: (pageId = new Date().getTime().toString()) => { blockSchemaRef.current && - workspace?.createPage(pageId, title).register(blockSchemaRef.current); + workspace?.createPage(pageId).register(blockSchemaRef.current); }, - openPage: (pageId: string, query: { [key: string]: string } = {}) => { + openPage: (pageId, query = {}) => { return router.push({ pathname: '/', query: { @@ -73,25 +107,36 @@ export const EditorProvider = ({ }, }); }, - getPageList: () => { - return workspace?.meta.pages; - }, - deletePage: (pageId: string) => { + deletePage: pageId => { workspace?.setPage(pageId, { trash: true }); }, - recyclePage: (pageId: string) => { + recyclePage: pageId => { workspace?.setPage(pageId, { trash: false }); }, - favoritePage: (pageId: string) => { + toggleDeletePage: pageId => { + const pageMeta = workspace?.meta.pages.find(p => p.id === pageId); + if (pageMeta) { + workspace?.setPage(pageId, { trash: !pageMeta.trash }); + } + }, + favoritePage: pageId => { workspace?.setPage(pageId, { favorite: true }); }, - unFavoritePage: (pageId: string) => { - workspace?.setPage(pageId, { favorite: true }); + unFavoritePage: pageId => { + workspace?.setPageMeta(pageId, { favorite: true }); + }, + toggleFavoritePage: pageId => { + const pageMeta = workspace?.meta.pages.find(p => p.id === pageId); + if (pageMeta) { + workspace?.setPageMeta(pageId, { favorite: !pageMeta.favorite }); + } }, }; return ( - + p.id === (router.query.pageId as string)) + // ?.id ?? + // workspace.meta.pages[0]?.id ?? + // 'page0'; + + const initialPageId = + workspace.meta.pages.find(p => p.id === (router.query.pageId as string)) + ?.id ?? 'page0'; + console.log('initialPageId', initialPageId); + + const initialPage = workspace + .createPage(initialPageId) + .register(BlockSchema); setCurrentPage(initialPage); }, [workspace, router.query.pageId, setCurrentPage]); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 804e7981ef..00d0ab795f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,10 +22,10 @@ importers: packages/app: specifiers: - '@blocksuite/blocks': 0.3.0-alpha.5 - '@blocksuite/editor': 0.3.0-alpha.5 + '@blocksuite/blocks': 0.3.0-alpha.6 + '@blocksuite/editor': 0.3.0-alpha.6 '@blocksuite/icons': ^1.0.5 - '@blocksuite/store': 0.3.0-alpha.5 + '@blocksuite/store': 0.3.0-alpha.6 '@emotion/css': ^11.10.0 '@emotion/react': ^11.10.4 '@emotion/server': ^11.10.0 @@ -53,10 +53,10 @@ importers: react-dom: 18.2.0 typescript: 4.8.3 dependencies: - '@blocksuite/blocks': 0.3.0-alpha.5 - '@blocksuite/editor': 0.3.0-alpha.5 + '@blocksuite/blocks': 0.3.0-alpha.6 + '@blocksuite/editor': 0.3.0-alpha.6 '@blocksuite/icons': 1.0.5_w5j4k42lgipnm43s3brx6h3c34 - '@blocksuite/store': 0.3.0-alpha.5 + '@blocksuite/store': 0.3.0-alpha.6 '@emotion/css': 11.10.0 '@emotion/react': 11.10.4_w5j4k42lgipnm43s3brx6h3c34 '@emotion/server': 11.10.0_@emotion+css@11.10.0 @@ -172,10 +172,10 @@ packages: to-fast-properties: 2.0.0 dev: false - /@blocksuite/blocks/0.3.0-alpha.5: - resolution: {integrity: sha512-jZy1mXaC2s/b227Yf/wNPRwMAFGa1USH/Q0OJ6KAcmY8YQdeGXKAoNTz4p7K5rMJgtE1t17/Mzwo5+exCRbIkg==} + /@blocksuite/blocks/0.3.0-alpha.6: + resolution: {integrity: sha512-pa8wP0hRIDlufae+ABAQFLW8TNOGsfh8AqyTKF/+LVYFCGr+9tlW55X3OlWtU51vFxawst1Wd3FnjCAW6XiaKQ==} dependencies: - '@blocksuite/store': 0.3.0-alpha.5 + '@blocksuite/store': 0.3.0-alpha.6 hotkeys-js: 3.10.0 lit: 2.4.0 quill: 1.3.7 @@ -186,11 +186,11 @@ packages: - utf-8-validate dev: false - /@blocksuite/editor/0.3.0-alpha.5: - resolution: {integrity: sha512-H7RZkG3ptyzLs0+6YgwQnp6H8hByfWRSjDi388ZIz3/exgliyBz2QkQwY4Tj2nlAYSq/U5/8hdDMjw4a092Ivw==} + /@blocksuite/editor/0.3.0-alpha.6: + resolution: {integrity: sha512-2wFkOlCKqC4BrfCIzuxjUyVnE/mmGOyUnqVTQNmHrToDS81RLIq0r+lj1IrzLv+LZQCfTyhoAlJyaxUNrUw3sw==} dependencies: - '@blocksuite/blocks': 0.3.0-alpha.5 - '@blocksuite/store': 0.3.0-alpha.5 + '@blocksuite/blocks': 0.3.0-alpha.6 + '@blocksuite/store': 0.3.0-alpha.6 lit: 2.4.0 marked: 4.1.1 turndown: 7.1.1 @@ -210,8 +210,8 @@ packages: react: 18.2.0 dev: false - /@blocksuite/store/0.3.0-alpha.5: - resolution: {integrity: sha512-pkbSrwB7KTfW56iH4ZFPkrS6shIU8QpmJlZmKVY95Gp5QSISW2ffKUsFrrHVHT+GoOV7+RPZQrphUnC57grPNg==} + /@blocksuite/store/0.3.0-alpha.6: + resolution: {integrity: sha512-rI7cUVSqoMh1bsNLwL8MAgyaUq0Ix+SRBqweYwVjeDoqFIbHjnRSwkVw48K/FgxN6ekN96HLSf3Sj/HK1ivPpw==} dependencies: buffer: 6.0.3 flexsearch: 0.7.21