diff --git a/README.md b/README.md index 7c8e544e5c..0be7a5b851 100644 --- a/README.md +++ b/README.md @@ -196,27 +196,24 @@ Thanks a lot to the community for providing such powerful and simple libraries, ## Self-Host -Get started with Docker and deploy your own feature-rich, restriction-free deployment of AFFiNE - check the [latest packages](https://github.com/toeverything/AFFiNE/pkgs/container/affine-self-hosted). +Get started with Docker and deploy your own feature-rich, restriction-free deployment of AFFiNE - check the [latest packages](https://github.com/toeverything/AFFiNE/pkgs/container/affine-self-hosted). ## Hiring Some amazing companies including AFFiNE are looking for developers! Are you interested in helping build with AFFiNE and/or its partners? Check out some of the latest [jobs available](./docs/jobs/summary.md). - ## Upgrading For upgrading information please see our [update page](https://affine.pro/blog?tag=Release%20Note). - ## Feature Request -For feature request please see https://community.affine.pro/c/feature-requests/ +For feature request please see https://community.affine.pro/c/feature-requests/ ## Is it awesome? [These people](https://twitter.com/AffineOfficial/followers) seem to like it. - ## License See [LICENSE](/LICENSE) for details. diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 3cb668b373..fa4a4f4d77 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -13,7 +13,7 @@ Use the table of contents icon on the top left corner of this document to get to Currently we have two versions of AFFiNE: - [AFFiNE Pre-Alpha](https://livedemo.affine.pro/). This version users the branch `Pre-Alpha`, it is no longer actively developed but contains some different functions and features. -- [AFFiNE Alpha](https://pathfinder.affine.pro/). This version uses the `master` branch, this is the latest version under active development. +- [AFFiNE Alpha](https://pathfinder.affine.pro/). This version uses the `master` branch, this is the latest version under active development. To get an overview of the project, read the [README](../README.md). Here are some resources to help you get started with open source contributions: diff --git a/package.json b/package.json index 24a82b0310..967a98bfa4 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ }, "devDependencies": { "@changesets/cli": "^2.26.0", + "@jest/globals": "^29.3.1", "@playwright/test": "^1.29.1", "@types/eslint": "^8.4.10", "@types/node": "^18.11.17", @@ -37,8 +38,10 @@ "eslint-config-next": "12.3.1", "eslint-config-prettier": "^8.5.0", "eslint-plugin-prettier": "^4.2.1", + "fake-indexeddb": "4.0.1", "got": "^12.5.3", "husky": "^8.0.2", + "jest": "^29.3.1", "lint-staged": "^13.1.0", "prettier": "^2.7.1", "typescript": "^4.9.3" @@ -65,7 +68,8 @@ "reportUnusedDisableDirectives": true, "ignorePatterns": [ "src/**/*.test.ts", - "package/**/dist/*" + "package/**/dist/*", + "package/**/sync.js" ] } } diff --git a/packages/app/next.config.js b/packages/app/next.config.js index 478bbfa12e..4e0f129d51 100644 --- a/packages/app/next.config.js +++ b/packages/app/next.config.js @@ -12,6 +12,9 @@ const EDITOR_VERSION = enableDebugLocal const profileTarget = { ac: '100.85.73.88:12001', dev: '100.77.180.48:11001', + test: '100.85.73.88:12001', + stage: '', + pro: 'http://pathfinder.affine.pro', local: '127.0.0.1:3000', }; diff --git a/packages/app/package.json b/packages/app/package.json index ad13d1da75..7a3a4f6ce8 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -11,10 +11,10 @@ "dependencies": { "@affine/datacenter": "workspace:*", "@affine/i18n": "workspace:*", - "@blocksuite/blocks": "0.4.0-20230113023110-28a7fdc", - "@blocksuite/editor": "0.4.0-20230113023110-28a7fdc", + "@blocksuite/blocks": "0.4.0-20230201063624-4e0463b", + "@blocksuite/editor": "0.4.0-20230201063624-4e0463b", "@blocksuite/icons": "^2.0.2", - "@blocksuite/store": "0.4.0-20230113023110-28a7fdc", + "@blocksuite/store": "0.4.0-20230201063624-4e0463b", "@emotion/css": "^11.10.0", "@emotion/react": "^11.10.4", "@emotion/server": "^11.10.0", diff --git a/packages/app/public/globals.css b/packages/app/public/globals.css index aa58d38563..ca43c3fec8 100644 --- a/packages/app/public/globals.css +++ b/packages/app/public/globals.css @@ -166,9 +166,9 @@ a:visited { input { border: none; -moz-appearance: none; - -webkit-appearance: none; /*解决ios上按钮的圆角问题*/ - border-radius: 0; /*解决ios上输入框圆角问题*/ - outline: medium; /*去掉鼠标点击的默认黄色边框*/ + -webkit-appearance: none; /*Solve the rounded corners of buttons on ios*/ + border-radius: 0; /*Solve the problem of rounded corners of the input box on ios*/ + outline: medium; /*Remove the default yellow border on mouse click*/ background-color: transparent; } diff --git a/packages/app/src/components/404/index.tsx b/packages/app/src/components/404/index.tsx index 8ed4232807..0a06467afa 100644 --- a/packages/app/src/components/404/index.tsx +++ b/packages/app/src/components/404/index.tsx @@ -1,10 +1,24 @@ import { NotFoundTitle, PageContainer } from './styles'; import { useTranslation } from '@affine/i18n'; +import { Button } from '@/ui/button'; +import { useRouter } from 'next/router'; export const NotfoundPage = () => { const { t } = useTranslation(); + const router = useRouter(); return ( - {t('404 - Page Not Found')} + + {t('404 - Page Not Found')} +

+ +

+
); }; diff --git a/packages/app/src/components/contact-modal/index.tsx b/packages/app/src/components/contact-modal/index.tsx index 6ec64fc144..d22b2ea6c4 100644 --- a/packages/app/src/components/contact-modal/index.tsx +++ b/packages/app/src/components/contact-modal/index.tsx @@ -91,8 +91,6 @@ export const ContactModal = ({ Alpha { onClose(); }} diff --git a/packages/app/src/components/create-workspace/index.tsx b/packages/app/src/components/create-workspace/index.tsx new file mode 100644 index 0000000000..11aa3de52b --- /dev/null +++ b/packages/app/src/components/create-workspace/index.tsx @@ -0,0 +1,121 @@ +import { styled } from '@/styles'; +import { Modal, ModalWrapper, ModalCloseButton } from '@/ui/modal'; +import { Button } from '@/ui/button'; +import { useState } from 'react'; +import Input from '@/ui/input'; +import { KeyboardEvent } from 'react'; +import { useTranslation } from '@affine/i18n'; +import { useWorkspaceHelper } from '@/hooks/use-workspace-helper'; +import { useRouter } from 'next/router'; +import { toast } from '@/ui/toast'; + +interface ModalProps { + open: boolean; + onClose: () => void; +} + +export const CreateWorkspaceModal = ({ open, onClose }: ModalProps) => { + const [workspaceName, setWorkspaceName] = useState(''); + const [loading, setLoading] = useState(false); + const { createWorkspace } = useWorkspaceHelper(); + const router = useRouter(); + const handleCreateWorkspace = async () => { + setLoading(true); + const workspace = await createWorkspace(workspaceName); + + if (workspace && workspace.id) { + setLoading(false); + router.replace(`/workspace/${workspace.id}`); + onClose(); + } else { + toast('create error'); + } + }; + const handleKeyDown = (event: KeyboardEvent) => { + if (event.key === 'Enter') { + // 👇 Get input value + handleCreateWorkspace(); + } + }; + const { t } = useTranslation(); + return ( +
+ + +
+ { + onClose(); + }} + /> +
+ + {t('New Workspace')} +

{t('Workspace description')}

+ { + setWorkspaceName(value); + }} + > + +
+
+
+
+ ); +}; + +const Header = styled('div')({ + position: 'relative', + height: '44px', +}); + +const Content = styled('div')(({ theme }) => { + return { + padding: '0 84px', + textAlign: 'center', + fontSize: '18px', + lineHeight: '26px', + color: theme.colors.inputColor, + p: { + marginTop: '12px', + marginBottom: '16px', + }, + }; +}); + +const ContentTitle = styled('div')(() => { + return { + fontSize: '20px', + lineHeight: '28px', + fontWeight: 600, + textAlign: 'center', + paddingBottom: '16px', + }; +}); + +// const Footer = styled('div')({ +// height: '70px', +// paddingLeft: '24px', +// marginTop: '32px', +// textAlign: 'center', +// }); diff --git a/packages/app/src/components/delete-workspace/index.tsx b/packages/app/src/components/delete-workspace/index.tsx index 5cceb487a2..cead4b135e 100644 --- a/packages/app/src/components/delete-workspace/index.tsx +++ b/packages/app/src/components/delete-workspace/index.tsx @@ -29,8 +29,6 @@ export const DeleteModal = ({
{ onClose(); }} diff --git a/packages/app/src/components/edgeless-toolbar/index.tsx b/packages/app/src/components/edgeless-toolbar/index.tsx index c6f880146d..e261899860 100644 --- a/packages/app/src/components/edgeless-toolbar/index.tsx +++ b/packages/app/src/components/edgeless-toolbar/index.tsx @@ -14,78 +14,82 @@ import { UndoIcon, RedoIcon, } from './Icons'; +import { MuiSlide } from '@/ui/mui'; import { Tooltip } from '@/ui/tooltip'; -import Slide from '@mui/material/Slide'; import useCurrentPageMeta from '@/hooks/use-current-page-meta'; import { useAppState } from '@/providers/app-state-provider'; import useHistoryUpdated from '@/hooks/use-history-update'; +import { useTranslation } from '@affine/i18n'; -const toolbarList1 = [ - { - flavor: 'select', - icon: , - toolTip: 'Select', - disable: false, - callback: () => { - window.dispatchEvent( - new CustomEvent('affine.switch-mouse-mode', { - detail: { - type: 'default', - }, - }) - ); +const useToolbarList1 = () => { + const { t } = useTranslation(); + return [ + { + flavor: 'select', + icon: , + toolTip: t('Select'), + disable: false, + callback: () => { + window.dispatchEvent( + new CustomEvent('affine.switch-mouse-mode', { + detail: { + type: 'default', + }, + }) + ); + }, }, - }, - { - flavor: 'text', - icon: , - toolTip: 'Text (coming soon)', - disable: true, - }, - { - flavor: 'shape', - icon: , - toolTip: 'Shape', - disable: false, - callback: () => { - window.dispatchEvent( - new CustomEvent('affine.switch-mouse-mode', { - detail: { - type: 'shape', - color: 'black', - shape: 'rectangle', - }, - }) - ); + { + flavor: 'text', + icon: , + toolTip: t('Text'), + disable: true, + }, + { + flavor: 'shape', + icon: , + toolTip: t('Shape'), + disable: false, + callback: () => { + window.dispatchEvent( + new CustomEvent('affine.switch-mouse-mode', { + detail: { + type: 'shape', + color: 'black', + shape: 'rectangle', + }, + }) + ); + }, + }, + { + flavor: 'sticky', + icon: , + toolTip: t('Sticky'), + disable: true, + }, + { + flavor: 'pen', + icon: , + toolTip: t('Pen'), + disable: true, }, - }, - { - flavor: 'sticky', - icon: , - toolTip: 'Sticky (coming soon)', - disable: true, - }, - { - flavor: 'pen', - icon: , - toolTip: 'Pen (coming soon)', - disable: true, - }, - { - flavor: 'connector', - icon: , - toolTip: 'Connector (coming soon)', - disable: true, - }, -]; + { + flavor: 'connector', + icon: , + toolTip: t('Connector'), + disable: true, + }, + ]; +}; const UndoRedo = () => { const [canUndo, setCanUndo] = useState(false); const [canRedo, setCanRedo] = useState(false); const { currentPage } = useAppState(); const onHistoryUpdated = useHistoryUpdated(); - + const { t } = useTranslation(); useEffect(() => { onHistoryUpdated(page => { setCanUndo(page.canUndo); @@ -95,7 +99,7 @@ const UndoRedo = () => { return ( - + { @@ -105,7 +109,7 @@ const UndoRedo = () => { - + { @@ -123,7 +127,7 @@ export const EdgelessToolbar = () => { const { mode } = useCurrentPageMeta() || {}; return ( - { > - {toolbarList1.map( + {useToolbarList1().map( ({ icon, toolTip, flavor, disable, callback }, index) => { return ( @@ -151,7 +155,7 @@ export const EdgelessToolbar = () => { - + ); }; diff --git a/packages/app/src/components/edgeless-toolbar/reply.svg b/packages/app/src/components/edgeless-toolbar/reply.svg index bfe127a193..7b9f8f2a2e 100644 --- a/packages/app/src/components/edgeless-toolbar/reply.svg +++ b/packages/app/src/components/edgeless-toolbar/reply.svg @@ -1,3 +1,3 @@ - + diff --git a/packages/app/src/components/editor/index.tsx b/packages/app/src/components/editor/index.tsx new file mode 100644 index 0000000000..b6cc8aa076 --- /dev/null +++ b/packages/app/src/components/editor/index.tsx @@ -0,0 +1,69 @@ +import { useEffect, useRef } from 'react'; +import type { Page, Workspace } from '@blocksuite/store'; +import '@blocksuite/blocks'; +import { EditorContainer } from '@blocksuite/editor'; +import exampleMarkdown from '@/templates/Welcome-to-AFFiNE-Alpha-Downhill.md'; +import { styled } from '@/styles'; + +const StyledEditorContainer = styled('div')(() => { + return { + height: 'calc(100vh - 60px)', + padding: '0 32px', + }; +}); + +type Props = { + page: Page; + workspace: Workspace; + setEditor: (editor: EditorContainer) => void; +}; + +export const Editor = ({ page, workspace, setEditor }: Props) => { + const editorContainer = useRef(null); + // const { currentWorkspace, currentPage, setEditor } = useAppState(); + useEffect(() => { + const ret = () => { + const node = editorContainer.current; + while (node?.firstChild) { + node.removeChild(node.firstChild); + } + }; + + const editor = new EditorContainer(); + editor.page = page; + editorContainer.current?.appendChild(editor); + if (page.isEmpty) { + const isFirstPage = workspace?.meta.pageMetas.length === 1; + // Can not use useCurrentPageMeta to get new title, cause meta title will trigger rerender, but the second time can not remove title + const { title: metaTitle } = page.meta; + const title = metaTitle + ? metaTitle + : isFirstPage + ? 'Welcome to AFFiNE Alpha "Downhill"' + : ''; + workspace?.setPageMeta(page.id, { title }); + const pageBlockId = page.addBlockByFlavour('affine:page', { title }); + page.addBlockByFlavour('affine:surface', {}, null); + // Add frame block inside page block + const frameId = page.addBlockByFlavour('affine:frame', {}, pageBlockId); + // Add paragraph block inside frame block + // If this is a first page in workspace, init an introduction markdown + if (isFirstPage) { + editor.clipboard.importMarkdown(exampleMarkdown, frameId); + workspace.setPageMeta(page.id, { title }); + page.resetHistory(); + } else { + page.addBlockByFlavour('affine:paragraph', {}, frameId); + } + page.resetHistory(); + } + + setEditor(editor); + document.title = page.meta.title || 'Untitled'; + return ret; + }, [workspace, page, setEditor]); + + return ; +}; + +export default Editor; diff --git a/packages/app/src/components/enable-workspace/index.tsx b/packages/app/src/components/enable-workspace/index.tsx new file mode 100644 index 0000000000..3cc28b25d4 --- /dev/null +++ b/packages/app/src/components/enable-workspace/index.tsx @@ -0,0 +1,24 @@ +import { useWorkspaceHelper } from '@/hooks/use-workspace-helper'; +import { Button } from '@/ui/button'; +import { useTranslation } from '@affine/i18n'; +import { useState } from 'react'; + +export const EnableWorkspaceButton = () => { + const { t } = useTranslation(); + const { enableWorkspace } = useWorkspaceHelper(); + const [loading, setLoading] = useState(false); + return ( + + ); +}; diff --git a/packages/app/src/components/file-upload/index.tsx b/packages/app/src/components/file-upload/index.tsx index 25d91fb06d..80b089c35f 100644 --- a/packages/app/src/components/file-upload/index.tsx +++ b/packages/app/src/components/file-upload/index.tsx @@ -1,6 +1,7 @@ import { Button } from '@/ui/button'; import { FC, useRef, ChangeEvent, ReactElement } from 'react'; import { styled } from '@/styles'; +import { useTranslation } from '@affine/i18n'; interface Props { uploadType?: string; children?: ReactElement; @@ -9,6 +10,7 @@ interface Props { } export const Upload: FC = props => { const { fileChange, accept } = props; + const { t } = useTranslation(); const input_ref = useRef(null); const _chooseFile = () => { if (input_ref.current) { @@ -28,7 +30,7 @@ export const Upload: FC = props => { }; return ( - {props.children ?? } + {props.children ?? } { const [title, setTitle] = useState(''); diff --git a/packages/app/src/components/header/Header.tsx b/packages/app/src/components/header/Header.tsx index 4b7a6fcf73..1226f91561 100644 --- a/packages/app/src/components/header/Header.tsx +++ b/packages/app/src/components/header/Header.tsx @@ -6,11 +6,12 @@ import { StyledBrowserWarning, StyledCloseButton, } from './styles'; -import CloseIcon from '@mui/icons-material/Close'; -import { getWarningMessage, shouldShowWarning } from './utils'; +import { CloseIcon } from '@blocksuite/icons'; +import { useWarningMessage, shouldShowWarning } from './utils'; import EditorOptionMenu from './header-right-items/EditorOptionMenu'; import TrashButtonGroup from './header-right-items/TrashButtonGroup'; import ThemeModeSwitch from './header-right-items/theme-mode-switch'; +import SyncUser from './header-right-items/SyncUser'; const BrowserWarning = ({ show, @@ -21,7 +22,7 @@ const BrowserWarning = ({ }) => { return ( - {getWarningMessage()} + {useWarningMessage()} @@ -39,11 +40,11 @@ const HeaderRightItems: Record = { editorOptionMenu: , trashButtonGroup: , themeModeSwitch: , - syncUser: null, //, + syncUser: , }; export const Header = ({ - rightItems = ['syncUser'], + rightItems = ['syncUser', 'themeModeSwitch'], children, }: PropsWithChildren<{ rightItems?: HeaderRightItemNames[] }>) => { const [showWarning, setShowWarning] = useState(shouldShowWarning()); diff --git a/packages/app/src/components/header/PageListHeader.tsx b/packages/app/src/components/header/PageListHeader.tsx index 43a1c976b9..99efff25de 100644 --- a/packages/app/src/components/header/PageListHeader.tsx +++ b/packages/app/src/components/header/PageListHeader.tsx @@ -1,7 +1,7 @@ import { PropsWithChildren, ReactNode } from 'react'; import Header from './Header'; import { StyledPageListTittleWrapper } from './styles'; -import QuickSearchButton from './QuickSearchButton'; +// import QuickSearchButton from './QuickSearchButton'; export type PageListHeaderProps = PropsWithChildren<{ icon?: ReactNode; @@ -12,7 +12,7 @@ export const PageListHeader = ({ icon, children }: PageListHeaderProps) => { {icon} {children} - + {/* */}
); diff --git a/packages/app/src/components/header/QuickSearchButton.tsx b/packages/app/src/components/header/QuickSearchButton.tsx index 64e3657448..dfc00eef14 100644 --- a/packages/app/src/components/header/QuickSearchButton.tsx +++ b/packages/app/src/components/header/QuickSearchButton.tsx @@ -2,13 +2,30 @@ import React from 'react'; import { IconButton, IconButtonProps } from '@/ui/button'; import { ArrowDownIcon } from '@blocksuite/icons'; import { useModal } from '@/providers/GlobalModalProvider'; +import { styled } from '@/styles'; + +const StyledIconButtonWithAnimate = styled(IconButton)(({ theme }) => { + return { + svg: { + transition: 'transform 0.15s ease-in-out', + }, + ':hover': { + svg: { + transform: 'translateY(3px)', + }, + '::after': { + background: theme.colors.pageBackground, + }, + }, + }; +}); export const QuickSearchButton = ({ onClick, ...props }: Omit) => { const { triggerQuickSearchModal } = useModal(); return ( - { @@ -17,7 +34,7 @@ export const QuickSearchButton = ({ }} > - + ); }; diff --git a/packages/app/src/components/header/header-right-items/SyncUser.tsx b/packages/app/src/components/header/header-right-items/SyncUser.tsx index 86c85926bf..60af1b461a 100644 --- a/packages/app/src/components/header/header-right-items/SyncUser.tsx +++ b/packages/app/src/components/header/header-right-items/SyncUser.tsx @@ -1,6 +1,6 @@ import { CloudUnsyncedIcon, CloudInsyncIcon } from '@blocksuite/icons'; import { useModal } from '@/providers/GlobalModalProvider'; -import { useAppState } from '@/providers/app-state-provider/context'; +import { useAppState } from '@/providers/app-state-provider'; import { IconButton } from '@/ui/button'; export const SyncUser = () => { diff --git a/packages/app/src/components/header/header-right-items/TrashButtonGroup.tsx b/packages/app/src/components/header/header-right-items/TrashButtonGroup.tsx index df12327131..af0a12a8d4 100644 --- a/packages/app/src/components/header/header-right-items/TrashButtonGroup.tsx +++ b/packages/app/src/components/header/header-right-items/TrashButtonGroup.tsx @@ -4,15 +4,16 @@ import { useAppState } from '@/providers/app-state-provider'; import { useConfirm } from '@/providers/ConfirmProvider'; import { useRouter } from 'next/router'; import useCurrentPageMeta from '@/hooks/use-current-page-meta'; +import { useTranslation } from '@affine/i18n'; export const TrashButtonGroup = () => { const { permanentlyDeletePage } = usePageHelper(); - const { currentWorkspaceId } = useAppState(); + const { currentWorkspace } = useAppState(); const { toggleDeletePage } = usePageHelper(); const { confirm } = useConfirm(); const router = useRouter(); const { id = '' } = useCurrentPageMeta() || {}; - + const { t } = useTranslation(); return ( <> ); diff --git a/packages/app/src/components/header/styles.ts b/packages/app/src/components/header/styles.ts index 1deb826faa..146164eebd 100644 --- a/packages/app/src/components/header/styles.ts +++ b/packages/app/src/components/header/styles.ts @@ -3,35 +3,25 @@ import { displayFlex, styled } from '@/styles'; export const StyledHeaderContainer = styled.div<{ hasWarning: boolean }>( ({ hasWarning }) => { return { - position: 'relative', height: hasWarning ? '96px' : '60px', }; } ); -export const StyledHeader = styled.div<{ hasWarning: boolean }>( - ({ hasWarning }) => { - return { - height: '60px', - width: '100%', - ...displayFlex('flex-end', 'center'), - background: 'var(--affine-page-background)', - transition: 'background-color 0.5s', - position: 'absolute', - left: '0', - top: hasWarning ? '36px' : '0', - padding: '0 22px', - zIndex: 99, - }; - } -); +export const StyledHeader = styled.div<{ hasWarning: boolean }>(() => { + return { + height: '60px', + width: '100%', + ...displayFlex('flex-end', 'center'), + background: 'var(--affine-page-background)', + transition: 'background-color 0.5s', + zIndex: 99, + }; +}); export const StyledTitle = styled('div')(({ theme }) => ({ width: '720px', height: '100%', - position: 'absolute', - left: 0, - right: 0, - top: 0, + margin: 'auto', ...displayFlex('center', 'center'), diff --git a/packages/app/src/components/header/utils.tsx b/packages/app/src/components/header/utils.tsx index dd9ff50127..1bf0fc88f6 100644 --- a/packages/app/src/components/header/utils.tsx +++ b/packages/app/src/components/header/utils.tsx @@ -1,4 +1,5 @@ import getIsMobile from '@/utils/get-is-mobile'; +import { Trans, useTranslation } from '@affine/i18n'; // Inspire by https://stackoverflow.com/a/4900484/8415727 const getChromeVersion = () => { const raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./); @@ -19,20 +20,20 @@ export const shouldShowWarning = () => { ); }; -export const getWarningMessage = () => { +export const useWarningMessage = () => { + const { t } = useTranslation(); if (!getIsChrome()) { return ( - We recommend the Chrome browser for optimal experience. + + We recommend the Chrome browser for optimal + experience. + ); } if (getChromeVersion() < minimumChromeVersion) { - return ( - - Please upgrade to the latest version of Chrome for the best experience. - - ); + return {t('upgradeBrowser')}; } return ''; }; diff --git a/packages/app/src/components/help-island/index.tsx b/packages/app/src/components/help-island/index.tsx index d6aad0c891..9fb883481d 100644 --- a/packages/app/src/components/help-island/index.tsx +++ b/packages/app/src/components/help-island/index.tsx @@ -6,7 +6,7 @@ import { StyledTransformIcon, } from './style'; import { CloseIcon, ContactIcon, HelpIcon, KeyboardIcon } from './Icons'; -import Grow from '@mui/material/Grow'; +import { MuiGrow } from '@/ui/mui'; import { Tooltip } from '@/ui/tooltip'; import { useTranslation } from '@affine/i18n'; import { useModal } from '@/providers/GlobalModalProvider'; @@ -35,7 +35,7 @@ export const HelpIsland = ({ setShowContent(false); }} > - + {showList.includes('contact') && ( @@ -66,7 +66,7 @@ export const HelpIsland = ({ )} - +
{ const { currentWorkspace } = useAppState(); const { t } = useTranslation(); const _applyTemplate = function (pageId: string, template: Template) { - const page = currentWorkspace?.getPage(pageId); + const page = currentWorkspace?.blocksuiteWorkspace?.getPage(pageId); const title = template.name; if (page) { - currentWorkspace?.setPageMeta(page.id, { title }); + currentWorkspace?.blocksuiteWorkspace?.setPageMeta(page.id, { title }); if (page && page.root === null) { setTimeout(() => { - const editor = document.querySelector('editor-container'); - if (editor) { - page.addBlock({ flavour: 'affine:surface' }, null); - const frameId = page.addBlock({ flavour: 'affine:frame' }, pageId); - // TODO blocksuite should offer a method to import markdown from store - editor.clipboard.importMarkdown(template.source, `${frameId}`); - page.resetHistory(); - editor.requestUpdate(); + try { + const editor = document.querySelector('editor-container'); + if (editor) { + page.addBlock({ flavour: 'affine:surface' }, null); + const frameId = page.addBlock( + { flavour: 'affine:frame' }, + pageId + ); + // TODO blocksuite should offer a method to import markdown from store + editor.clipboard.importMarkdown(template.source, `${frameId}`); + page.resetHistory(); + editor.requestUpdate(); + } + } catch (e) { + console.error(e); } }, 300); } @@ -98,18 +105,18 @@ export const ImportModal = ({ open, onClose }: ImportModalProps) => { > Markdown - {/* */} + )} {status === 'importing' && ( - { OOOOPS! Sorry forgot to remind you that we are working on the import function - + )} diff --git a/packages/app/src/components/loading/PageLoading.tsx b/packages/app/src/components/loading/PageLoading.tsx index 025eba7687..ef853c4d61 100644 --- a/packages/app/src/components/loading/PageLoading.tsx +++ b/packages/app/src/components/loading/PageLoading.tsx @@ -1,5 +1,6 @@ import { styled } from '@/styles'; import Loading from './Loading'; +import { useTranslation } from '@affine/i18n'; // Used for the full page loading const StyledLoadingContainer = styled('div')(() => { @@ -17,12 +18,13 @@ const StyledLoadingContainer = styled('div')(() => { }; }); -export const PageLoading = ({ text = 'Loading...' }: { text?: string }) => { +export const PageLoading = ({ text }: { text?: string }) => { + const { t } = useTranslation(); return (
-

{text}

+

{text ? text : t('Loading')}

); diff --git a/packages/app/src/components/loading/styled.ts b/packages/app/src/components/loading/styled.ts index b98a8bfaa5..31906e1b7b 100644 --- a/packages/app/src/components/loading/styled.ts +++ b/packages/app/src/components/loading/styled.ts @@ -1,19 +1,22 @@ import { styled } from '@/styles'; // Inspired by https://codepen.io/graphilla/pen/rNvBMYY -export const StyledLoadingWrapper = styled.div<{ size?: number }>( - ({ size = 40 }) => { - return { - width: size * 4, - height: size * 4, - position: 'relative', - }; - } -); +export const StyledLoadingWrapper = styled('div', { + shouldForwardProp: prop => { + return !['size'].includes(prop); + }, +})<{ size?: number }>(({ size = 40 }) => { + return { + width: size * 4, + height: size * 4, + position: 'relative', + }; +}); export const StyledLoading = styled.div` position: absolute; left: 25%; - top: 25%; + top: 50%; + transform: rotateX(55deg) rotateZ(-45deg); @keyframes slide { 0% { transform: translate(var(--sx), var(--sy)); diff --git a/packages/app/src/components/login-modal/Icons.tsx b/packages/app/src/components/login-modal/Icons.tsx index a6c694c876..12356f60d3 100644 --- a/packages/app/src/components/login-modal/Icons.tsx +++ b/packages/app/src/components/login-modal/Icons.tsx @@ -13,8 +13,6 @@ export const GoogleIcon = () => { }; const GoogleIconWrapper = styled('div')(({ theme }) => ({ - width: '48px', - height: '48px', background: theme.colors.pageBackground, display: 'flex', alignItems: 'center', diff --git a/packages/app/src/components/login-modal/LoginOptionButton.tsx b/packages/app/src/components/login-modal/LoginOptionButton.tsx index 48c19b0fb5..f104efc58b 100644 --- a/packages/app/src/components/login-modal/LoginOptionButton.tsx +++ b/packages/app/src/components/login-modal/LoginOptionButton.tsx @@ -1,38 +1,24 @@ -import { getDataCenter } from '@affine/datacenter'; import { styled } from '@/styles'; import { Button } from '@/ui/button'; -import { useModal } from '@/providers/GlobalModalProvider'; import { GoogleIcon, StayLogOutIcon } from './Icons'; - +import { useTranslation } from '@affine/i18n'; export const GoogleLoginButton = () => { - const { triggerLoginModal } = useModal(); + const { t } = useTranslation(); + return ( - { - getDataCenter() - .then(dc => dc.apis.signInWithGoogle?.()) - .then(() => { - triggerLoginModal(); - }) - .catch(error => { - console.log('sign google error', error); - }); - }} - > + - - Continue with Google - Set up an AFFiNE account to sync data - + {t('Continue with Google')} ); }; export const StayLogOutButton = () => { + const { t } = useTranslation(); return ( @@ -40,29 +26,26 @@ export const StayLogOutButton = () => { - Stay logged out - All changes are saved locally + {t('Stay logged out')} + {t('All changes are saved locally')} ); }; -const StyledGoogleButton = styled(Button)(() => { +const StyledGoogleButton = styled('div')(({ theme }) => { return { - width: '361px', - height: '56px', - padding: '4px', - background: '#6880FF', - color: '#fff', - - '& > span': { - marginLeft: 0, - }, - + width: '284px', + height: '40px', + marginTop: '30px', + fontSize: '16px', + cursor: 'pointer', + borderRadius: '40px', + border: `1px solid ${theme.colors.iconColor}`, + overflow: 'hidden', ':hover': { - background: '#516BF4', - color: '#fff', + border: `1px solid ${theme.colors.primaryColor}`, }, }; }); @@ -72,11 +55,6 @@ const StyledStayLogOutButton = styled(Button)(() => { width: '361px', height: '56px', padding: '4px', - - '& > span': { - marginLeft: 0, - }, - ':hover': { borderColor: '#6880FF', }, @@ -86,20 +64,22 @@ const StyledStayLogOutButton = styled(Button)(() => { const ButtonWrapper = styled('div')({ display: 'flex', flexDirection: 'row', + width: '100%', }); const IconWrapper = styled('div')({ - width: '48px', - height: '48px', flex: '0 48px', borderRadius: '5px', overflow: 'hidden', marginRight: '12px', + marginTop: '8px', }); const TextWrapper = styled('div')({ flex: 1, textAlign: 'left', + height: '40px', + lineHeight: '40px', }); const Title = styled('h1')(() => { diff --git a/packages/app/src/components/login-modal/index.tsx b/packages/app/src/components/login-modal/index.tsx index f398383196..8c15c24417 100644 --- a/packages/app/src/components/login-modal/index.tsx +++ b/packages/app/src/components/login-modal/index.tsx @@ -1,35 +1,38 @@ -import { ResetIcon } from '@blocksuite/icons'; import { styled } from '@/styles'; import { Modal, ModalWrapper, ModalCloseButton } from '@/ui/modal'; -import { TextButton } from '@/ui/button'; -import { GoogleLoginButton, StayLogOutButton } from './LoginOptionButton'; - +import { GoogleLoginButton } from './LoginOptionButton'; +import { useAppState } from '@/providers/app-state-provider'; +import { useTranslation } from '@affine/i18n'; interface LoginModalProps { open: boolean; onClose: () => void; } export const LoginModal = ({ open, onClose }: LoginModalProps) => { + const { login } = useAppState(); + const { t } = useTranslation(); return ( - +
{ onClose(); }} />
- Currently not logged in - - + {t('Sign in')} + {t('Set up an AFFiNE account to sync data')} + { + await login(); + onClose(); + }} + > + + -
- }>Clear local data -
); @@ -55,14 +58,10 @@ const ContentTitle = styled('h1')({ paddingBottom: '16px', }); -const Footer = styled('div')({ - height: '70px', - paddingLeft: '24px', - marginTop: '32px', -}); - -const StyledResetIcon = styled(ResetIcon)({ - marginRight: '12px', - width: '20px', - height: '20px', +const SignDes = styled('div')(({ theme }) => { + return { + fontWeight: 400, + color: theme.colors.textColor, + fontSize: '16px', + }; }); diff --git a/packages/app/src/components/logout-modal/icon.tsx b/packages/app/src/components/logout-modal/icon.tsx new file mode 100644 index 0000000000..afca63f57f --- /dev/null +++ b/packages/app/src/components/logout-modal/icon.tsx @@ -0,0 +1,48 @@ +export const Check = () => { + return ( + + + + + + + + + + + + + ); +}; + +export const UnCheck = () => { + return ( + + + + + + ); +}; diff --git a/packages/app/src/components/logout-modal/index.tsx b/packages/app/src/components/logout-modal/index.tsx new file mode 100644 index 0000000000..b317f1183c --- /dev/null +++ b/packages/app/src/components/logout-modal/index.tsx @@ -0,0 +1,118 @@ +import { styled } from '@/styles'; +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; +} + +export const LogoutModal = ({ open, onClose }: LoginModalProps) => { + const [localCache, setLocalCache] = useState(false); + const { t } = useTranslation(); + return ( + + +
+ { + onClose(true); + }} + /> +
+ + {t('Sign out')}? + {t('Set up an AFFiNE account to sync data')} + + {localCache ? ( + { + setLocalCache(false); + }} + > + + + ) : ( + { + setLocalCache(true); + }} + > + + + )} + {t('Retain local cached data')} + +
+ + +
+
+
+
+ ); +}; + +const Header = styled('div')({ + position: 'relative', + height: '44px', +}); + +const Content = styled('div')({ + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + gap: '16px', +}); + +const ContentTitle = styled('h1')({ + fontSize: '20px', + lineHeight: '28px', + fontWeight: 600, + textAlign: 'center', + paddingBottom: '16px', +}); + +const SignDes = styled('div')(({ theme }) => { + return { + fontWeight: 400, + color: theme.colors.textColor, + fontSize: '16px', + }; +}); + +const StyleCheck = styled('span')(() => { + return { + display: 'inline-block', + cursor: 'pointer', + + svg: { + verticalAlign: 'sub', + marginRight: '8px', + }, + }; +}); + +const StyleTips = styled('span')(() => { + return { + userSelect: 'none', + }; +}); diff --git a/packages/app/src/components/mobile-modal/index.tsx b/packages/app/src/components/mobile-modal/index.tsx index ff9796359b..b568c2697d 100644 --- a/packages/app/src/components/mobile-modal/index.tsx +++ b/packages/app/src/components/mobile-modal/index.tsx @@ -3,8 +3,10 @@ import Modal, { ModalCloseButton, ModalWrapper } from '@/ui/modal'; import getIsMobile from '@/utils/get-is-mobile'; import { StyledButton, StyledContent, StyledTitle } from './styles'; import bg from './bg.png'; +import { useTranslation } from '@affine/i18n'; export const MobileModal = () => { const [showModal, setShowModal] = useState(getIsMobile()); + const { t } = useTranslation(); return ( { }} /> - Ooops! + {t('Ooops!')} -

Looks like you are browsing on a mobile device.

-

- We are still working on mobile support and recommend you use a - desktop device. -

+

{t('mobile device')}

+

{t('mobile device description')}

{ setShowModal(false); }} > - Got it + {t('Got it')}
diff --git a/packages/app/src/components/page-list/Empty.tsx b/packages/app/src/components/page-list/Empty.tsx index ef13e1b117..4430b8f1a9 100644 --- a/packages/app/src/components/page-list/Empty.tsx +++ b/packages/app/src/components/page-list/Empty.tsx @@ -1,6 +1,9 @@ import React from 'react'; import { Empty } from '@/ui/empty'; -export const PageListEmpty = () => { +import { useTranslation } from '@affine/i18n'; +export const PageListEmpty = (props: { listType?: string }) => { + const { listType } = props; + const { t } = useTranslation(); return (
{ height={300} sx={{ marginTop: '100px', marginBottom: '30px' }} /> -

Tips: Click Add to Favourites/Trash and the page will appear here.

-

(Designer is grappling with designing)

+ {listType === 'all' &&

{t('emptyAllPages')}

} + {listType === 'favorite' &&

{t('emptyFavourite')}

} + {listType === 'trash' &&

{t('emptyTrash')}

} +

{t('still designed')}

); }; 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/page-list/index.tsx b/packages/app/src/components/page-list/index.tsx index dca0e15cac..7623eb4895 100644 --- a/packages/app/src/components/page-list/index.tsx +++ b/packages/app/src/components/page-list/index.tsx @@ -20,7 +20,7 @@ import DateCell from '@/components/page-list/DateCell'; import { IconButton } from '@/ui/button'; import { Tooltip } from '@/ui/tooltip'; import { useRouter } from 'next/router'; -import { useAppState } from '@/providers/app-state-provider/context'; +import { useAppState } from '@/providers/app-state-provider'; import { toast } from '@/ui/toast'; import { usePageHelper } from '@/hooks/use-page-helper'; import { useTheme } from '@/providers/ThemeProvider'; @@ -51,7 +51,7 @@ const FavoriteTag = ({ style={{ color: favorite ? theme.colors.primaryColor : theme.colors.iconColor, }} - className="favorite-button" + className={favorite ? '' : 'favorite-button'} > {favorite ? ( @@ -67,16 +67,20 @@ export const PageList = ({ pageList, showFavoriteTag = false, isTrash = false, + isPublic = false, + listType, }: { pageList: PageMeta[]; showFavoriteTag?: boolean; isTrash?: boolean; + isPublic?: boolean; + listType?: 'all' | 'trash' | 'favorite'; }) => { const router = useRouter(); - const { currentWorkspaceId } = useAppState(); + const { currentWorkspace } = useAppState(); const { t } = useTranslation(); if (pageList.length === 0) { - return ; + return ; } return ( @@ -98,9 +102,15 @@ export const PageList = ({ { - router.push( - `/workspace/${currentWorkspaceId}/${pageMeta.id}` - ); + if (isPublic) { + router.push( + `/public-workspace/${router.query.workspaceId}/${pageMeta.id}` + ); + } else { + router.push( + `/workspace/${currentWorkspace?.id}/${pageMeta.id}` + ); + } }} > @@ -124,19 +134,21 @@ export const PageList = ({ dateKey={isTrash ? 'trashDate' : 'updatedDate'} backupKey={isTrash ? 'trashDate' : 'createDate'} /> - { - e.stopPropagation(); - }} - > - {isTrash ? ( - - ) : ( - - )} - + {!isPublic ? ( + { + e.stopPropagation(); + }} + > + {isTrash ? ( + + ) : ( + + )} + + ) : null} ); })} diff --git a/packages/app/src/components/quick-search/Input.tsx b/packages/app/src/components/quick-search/Input.tsx index a3897675fb..e39d92e6b9 100644 --- a/packages/app/src/components/quick-search/Input.tsx +++ b/packages/app/src/components/quick-search/Input.tsx @@ -8,20 +8,18 @@ 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 { currentWorkspaceId, workspacesMeta, currentWorkspace } = - useAppState(); - const isPublic = workspacesMeta.find( - meta => String(meta.id) === String(currentWorkspaceId) - )?.public; + const { t } = useTranslation(); useEffect(() => { inputRef.current?.addEventListener( 'blur', @@ -80,9 +78,11 @@ export const Input = (props: { } }} placeholder={ - isPublic - ? `Search in ${currentWorkspace?.meta.name}` - : 'Quick Search...' + props.isPublic + ? t('Quick search placeholder2', { + 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..d0564b4cd7 --- /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.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/Results.tsx b/packages/app/src/components/quick-search/Results.tsx index e0821e7365..9e23c5f7c6 100644 --- a/packages/app/src/components/quick-search/Results.tsx +++ b/packages/app/src/components/quick-search/Results.tsx @@ -9,7 +9,6 @@ import { useSwitchToConfig } from './config'; import { NoResultSVG } from './NoResultSVG'; import { useTranslation } from '@affine/i18n'; import usePageHelper from '@/hooks/use-page-helper'; -import usePageMetaList from '@/hooks/use-page-meta-list'; export const Results = (props: { query: string; loading: boolean; @@ -21,12 +20,11 @@ export const Results = (props: { const setLoading = props.setLoading; const setShowCreatePage = props.setShowCreatePage; const { triggerQuickSearchModal } = useModal(); - const pageMetaList = usePageMetaList(); const { openPage } = usePageHelper(); const router = useRouter(); - const { currentWorkspaceId } = useAppState(); + const { currentWorkspace, pageList } = useAppState(); const { search } = usePageHelper(); - const List = useSwitchToConfig(currentWorkspaceId); + const List = useSwitchToConfig(currentWorkspace?.id); const [results, setResults] = useState(new Map()); const { t } = useTranslation(); useEffect(() => { @@ -37,12 +35,12 @@ export const Results = (props: { }, [query, setResults, setLoading]); const pageIds = [...results.values()]; - const resultsPageMeta = pageMetaList.filter( + const resultsPageMeta = pageList.filter( page => pageIds.indexOf(page.id) > -1 && !page.trash ); useEffect(() => { - setShowCreatePage(resultsPageMeta.length ? false : true); + setShowCreatePage(!resultsPageMeta.length); //Determine whether to display the ‘+ New page’ }, [resultsPageMeta, setShowCreatePage]); return loading ? null : ( diff --git a/packages/app/src/components/quick-search/config.ts b/packages/app/src/components/quick-search/config.ts index ce99ad5627..4738e93554 100644 --- a/packages/app/src/components/quick-search/config.ts +++ b/packages/app/src/components/quick-search/config.ts @@ -1,15 +1,16 @@ +import { FC, SVGProps } from 'react'; import { AllPagesIcon, FavouritesIcon, TrashIcon } from '@blocksuite/icons'; import { useTranslation } from '@affine/i18n'; export const useSwitchToConfig = ( - currentWorkspaceId: string + currentWorkspaceId?: string ): { title: string; href: string; - icon: React.FC>; + icon: FC>; }[] => { const { t } = useTranslation(); - const List = [ + return [ { title: t('All pages'), href: currentWorkspaceId ? `/workspace/${currentWorkspaceId}/all` : '', @@ -28,5 +29,4 @@ export const useSwitchToConfig = ( icon: TrashIcon, }, ]; - return List; }; diff --git a/packages/app/src/components/quick-search/index.tsx b/packages/app/src/components/quick-search/index.tsx index b08f69196e..7c24f0b970 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,16 +23,13 @@ const isMac = () => { return getUaHelper().isMacOs; }; export const QuickSearch = ({ open, onClose }: TransitionsModalProps) => { + 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(); - const { currentWorkspaceId, workspacesMeta } = useAppState(); - - const currentWorkspace = workspacesMeta.find( - meta => String(meta.id) === String(currentWorkspaceId) - ); - const isPublic = currentWorkspace?.public; // Add ‘⌘+K’ shortcut keys as switches useEffect(() => { @@ -55,6 +53,14 @@ export const QuickSearch = ({ open, onClose }: TransitionsModalProps) => { document.removeEventListener('keydown', down, { capture: true }); }, [open, triggerQuickSearchModal]); + useEffect(() => { + if (router.pathname.startsWith('/public-workspace')) { + return setIsPublic(true); + } else { + return setIsPublic(false); + } + }, [router]); + return ( { }} > - + {isMac() ? '⌘ + K' : 'Ctrl + K'} - + {!isPublic ? ( + + ) : ( + + )} - {isPublic ? ( - <> - ) : showCreatePage ? ( - <> - - -