From 1c8f1a05d0e2a0c4932b80fbb169995849c81125 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Tue, 13 Jun 2023 14:55:23 +0800 Subject: [PATCH] fix: add @typescript-eslint/no-floating-promises rule (#2764) Co-authored-by: himself65 --- .eslintrc.js | 33 ++-- apps/electron/src/helper/dialog/dialog.ts | 4 +- apps/electron/src/helper/index.ts | 4 +- .../src/main/workers/plugin.worker.ts | 10 +- apps/electron/src/preload/bootstrap.ts | 4 +- apps/web/src/atoms/history.ts | 8 +- apps/web/src/atoms/index.ts | 29 +-- .../affine/create-workspace-modal/index.tsx | 15 +- .../panel/general/index.tsx | 177 +++++++++--------- .../header-right-items/language-menu.tsx | 4 +- .../blocksuite/workspace-header/header.tsx | 13 +- .../pure/quick-search-modal/footer.tsx | 4 +- .../src/components/root-app-sidebar/index.tsx | 4 +- apps/web/src/layouts/workspace-layout.tsx | 12 +- apps/web/src/pages/index.tsx | 18 +- .../pages/workspace/[workspaceId]/setting.tsx | 75 ++++---- .../app-updater-button/index.jotai.ts | 4 +- .../app-sidebar/app-updater-button/index.tsx | 5 +- .../operation-menu-items/copy-link.tsx | 11 +- .../page-list/operation-menu-items/export.tsx | 15 +- .../src/components/theme-provider/index.tsx | 6 +- packages/plugin-infra/src/manager.ts | 23 ++- packages/workspace/src/providers/index.ts | 6 +- plugins/copilot/src/UI/detail-content.tsx | 75 ++++---- plugins/copilot/src/core/hooks/index.ts | 22 ++- 25 files changed, 342 insertions(+), 239 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 7b71c40b83..84843c4265 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -152,6 +152,27 @@ const config = { '@typescript-eslint/no-var-requires': 0, }, }, + ...allPackages.map(pkg => ({ + files: [`${pkg}/src/**/*.ts`, `${pkg}/src/**/*.tsx`], + parserOptions: { + project: resolve(__dirname, './tsconfig.eslint.json'), + }, + rules: { + '@typescript-eslint/no-restricted-imports': [ + 'error', + { + patterns: createPattern(pkg), + }, + ], + '@typescript-eslint/no-floating-promises': [ + 'error', + { + ignoreVoid: false, + ignoreIIFE: false, + }, + ], + }, + })), { files: [ '**/__tests__/**/*', @@ -173,19 +194,9 @@ const config = { 'ts-check': false, }, ], + '@typescript-eslint/no-floating-promises': 0, }, }, - ...allPackages.map(pkg => ({ - files: [`${pkg}/src/**/*.ts`, `${pkg}/src/**/*.tsx`], - rules: { - '@typescript-eslint/no-restricted-imports': [ - 'error', - { - patterns: createPattern(pkg), - }, - ], - }, - })), ], }; diff --git a/apps/electron/src/helper/dialog/dialog.ts b/apps/electron/src/helper/dialog/dialog.ts index 93a8b0b4d7..6a6fd756ba 100644 --- a/apps/electron/src/helper/dialog/dialog.ts +++ b/apps/electron/src/helper/dialog/dialog.ts @@ -110,7 +110,9 @@ export async function saveDBFileAs( await fs.copyFile(db.path, filePath); logger.log('saved', filePath); - mainRPC.showItemInFolder(filePath); + mainRPC.showItemInFolder(filePath).catch(err => { + console.error(err); + }); return { filePath }; } catch (err) { logger.error('saveDBFileAs', err); diff --git a/apps/electron/src/helper/index.ts b/apps/electron/src/helper/index.ts index d38937b0c0..feeb7ba122 100644 --- a/apps/electron/src/helper/index.ts +++ b/apps/electron/src/helper/index.ts @@ -64,7 +64,9 @@ function setupRendererConnection(rendererPort: Electron.MessagePortMain) { for (const [key, eventRegister] of Object.entries(namespaceEvents)) { const subscription = eventRegister((...args: any[]) => { const chan = `${namespace}:${key}`; - rpc.postEvent(chan, ...args); + rpc.postEvent(chan, ...args).catch(err => { + console.error(err); + }); }); process.on('exit', () => { subscription(); diff --git a/apps/electron/src/main/workers/plugin.worker.ts b/apps/electron/src/main/workers/plugin.worker.ts index 456eb0334b..c5ef298fcb 100644 --- a/apps/electron/src/main/workers/plugin.worker.ts +++ b/apps/electron/src/main/workers/plugin.worker.ts @@ -15,8 +15,8 @@ AsyncCall(commandProxy, { channel: new MessageEventChannel(parentPort), }); -import('@toeverything/plugin-infra/manager').then( - ({ rootStore, affinePluginsAtom }) => { +import('@toeverything/plugin-infra/manager') + .then(({ rootStore, affinePluginsAtom }) => { const bookmarkPluginPath = join( process.env.PLUGIN_DIR ?? resolve(__dirname, '../plugins'), './bookmark-block/index.mjs' @@ -39,5 +39,7 @@ import('@toeverything/plugin-infra/manager').then( } }); }); - } -); + }) + .catch(err => { + console.error(err); + }); diff --git a/apps/electron/src/preload/bootstrap.ts b/apps/electron/src/preload/bootstrap.ts index f47dab0e93..9b5d4e315c 100644 --- a/apps/electron/src/preload/bootstrap.ts +++ b/apps/electron/src/preload/bootstrap.ts @@ -50,4 +50,6 @@ import { contextBridge, ipcRenderer } from 'electron'; } catch (error) { console.error('Failed to expose affine APIs to window object!', error); } -})(); +})().catch(err => { + console.error('Failed to bootstrap preload script!', err); +}); diff --git a/apps/web/src/atoms/history.ts b/apps/web/src/atoms/history.ts index 1af3d1043e..2defc880e9 100644 --- a/apps/web/src/atoms/history.ts +++ b/apps/web/src/atoms/history.ts @@ -75,7 +75,9 @@ export function useHistoryAtom() { if (forward) { const target = Math.min(prev.stack.length - 1, prev.current + 1); const url = prev.stack[target]; - void router.push(url); + router.push(url).catch(err => { + console.error(err); + }); return { ...prev, current: target, @@ -84,7 +86,9 @@ export function useHistoryAtom() { } else { const target = Math.max(0, prev.current - 1); const url = prev.stack[target]; - void router.push(url); + router.push(url).catch(err => { + console.error(err); + }); return { ...prev, current: target, diff --git a/apps/web/src/atoms/index.ts b/apps/web/src/atoms/index.ts index 32e7cd545b..ebbdb61b26 100644 --- a/apps/web/src/atoms/index.ts +++ b/apps/web/src/atoms/index.ts @@ -49,19 +49,24 @@ rootWorkspacesMetadataAtom.onMount = setAtom => { }, 0); if (environment.isDesktop) { - window.apis?.workspace.list().then(workspaceIDs => { - if (abortController.signal.aborted) return; - const newMetadata = workspaceIDs.map(w => ({ - id: w[0], - flavour: WorkspaceFlavour.LOCAL, - })); - setAtom(metadata => { - return [ - ...metadata, - ...newMetadata.filter(m => !metadata.find(m2 => m2.id === m.id)), - ]; + window.apis?.workspace + .list() + .then(workspaceIDs => { + if (abortController.signal.aborted) return; + const newMetadata = workspaceIDs.map(w => ({ + id: w[0], + flavour: WorkspaceFlavour.LOCAL, + })); + setAtom(metadata => { + return [ + ...metadata, + ...newMetadata.filter(m => !metadata.find(m2 => m2.id === m.id)), + ]; + }); + }) + .catch(err => { + console.error(err); }); - }); } return () => { diff --git a/apps/web/src/components/affine/create-workspace-modal/index.tsx b/apps/web/src/components/affine/create-workspace-modal/index.tsx index ad86ad9835..5f361f02c6 100644 --- a/apps/web/src/components/affine/create-workspace-modal/index.tsx +++ b/apps/web/src/components/affine/create-workspace-modal/index.tsx @@ -116,9 +116,14 @@ const useDefaultDBLocation = () => { const [defaultDBLocation, setDefaultDBLocation] = useState(''); useEffect(() => { - window.apis?.db.getDefaultStorageLocation().then(dir => { - setDefaultDBLocation(dir); - }); + window.apis?.db + .getDefaultStorageLocation() + .then(dir => { + setDefaultDBLocation(dir); + }) + .catch(err => { + console.error(err); + }); }, []); return defaultDBLocation; @@ -281,7 +286,9 @@ export const CreateWorkspaceModal = ({ } onClose(); } - })(); + })().catch(err => { + console.error(err); + }); } else if (mode === 'new') { setStep(environment.isDesktop ? 'set-db-location' : 'name-workspace'); } else { diff --git a/apps/web/src/components/affine/workspace-setting-detail/panel/general/index.tsx b/apps/web/src/components/affine/workspace-setting-detail/panel/general/index.tsx index b3f7a4bf85..fe3d68f3ad 100644 --- a/apps/web/src/components/affine/workspace-setting-detail/panel/general/index.tsx +++ b/apps/web/src/components/affine/workspace-setting-detail/panel/general/index.tsx @@ -12,7 +12,7 @@ import { useBlockSuiteWorkspaceAvatarUrl } from '@toeverything/hooks/use-block-s import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-workspace-name'; import clsx from 'clsx'; import type React from 'react'; -import { useEffect, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { useIsWorkspaceOwner } from '../../../../../hooks/affine/use-is-workspace-owner'; import { Upload } from '../../../../pure/file-upload'; @@ -27,9 +27,14 @@ const useShowOpenDBFile = (workspaceId: string) => { const [show, setShow] = useState(false); useEffect(() => { if (window.apis && window.events && environment.isDesktop) { - window.apis.workspace.getMeta(workspaceId).then(meta => { - setShow(!!meta.secondaryDBPath); - }); + window.apis.workspace + .getMeta(workspaceId) + .then(meta => { + setShow(!!meta.secondaryDBPath); + }) + .catch(err => { + console.error(err); + }); return window.events.workspace.onMetaChange((newMeta: any) => { if (newMeta.workspaceId === workspaceId) { const meta = newMeta.meta; @@ -54,35 +59,11 @@ export const GeneralPanel: React.FC = ({ const isOwner = useIsWorkspaceOwner(workspace); const t = useAFFiNEI18N(); - const showOpenFolder = useShowOpenDBFile(workspace.id); - const handleUpdateWorkspaceName = (name: string) => { setName(name); toast(t['Update workspace name success']()); }; - const [moveToInProgress, setMoveToInProgress] = useState(false); - - const handleMoveTo = async () => { - if (moveToInProgress) { - return; - } - try { - setMoveToInProgress(true); - const result = await window.apis?.dialog.moveDBFile(workspace.id); - if (!result?.error && !result?.canceled) { - toast(t['Move folder success']()); - } else if (result?.error) { - // @ts-expect-error: result.error is dynamic - toast(t[result.error]()); - } - } catch (err) { - toast(t['UNKNOWN_ERROR']()); - } finally { - setMoveToInProgress(false); - } - }; - const [, update] = useBlockSuiteWorkspaceAvatarUrl( workspace.blockSuiteWorkspace ); @@ -137,9 +118,7 @@ export const GeneralPanel: React.FC = ({ placeholder={t['Workspace Name']()} maxLength={64} minLength={0} - onChange={newName => { - setInput(newName); - }} + onChange={setInput} > @@ -158,63 +137,7 @@ export const GeneralPanel: React.FC = ({ - - {environment.isDesktop && ( -
-
-
- {t['Storage Folder']()} -
-
- {t['Storage Folder Hint']()} -
-
- -
- {showOpenFolder && ( -
{ - if (environment.isDesktop) { - window.apis?.dialog.revealDBFile(workspace.id); - } - }} - > - -
-
- {t['Open folder']()} -
-
- {t['Open folder hint']()} -
-
- -
- )} - -
- -
-
- {t['Move folder']()} -
-
- {t['Move folder hint']()} -
-
- -
-
-
-
- )} - +
@@ -273,3 +196,81 @@ export const GeneralPanel: React.FC = ({ ); }; + +function DesktopClientOnly({ workspaceId }: { workspaceId: string }) { + const t = useAFFiNEI18N(); + const showOpenFolder = useShowOpenDBFile(workspaceId); + const onRevealDBFile = useCallback(() => { + if (environment.isDesktop) { + window.apis?.dialog.revealDBFile(workspaceId).catch(err => { + console.error(err); + }); + } + }, [workspaceId]); + const [moveToInProgress, setMoveToInProgress] = useState(false); + const handleMoveTo = useCallback(() => { + if (moveToInProgress) { + return; + } + setMoveToInProgress(true); + window.apis?.dialog + .moveDBFile(workspaceId) + .then(result => { + if (!result?.error && !result?.canceled) { + toast(t['Move folder success']()); + } else if (result?.error) { + // @ts-expect-error: result.error is dynamic + toast(t[result.error]()); + } + }) + .catch(() => { + toast(t['UNKNOWN_ERROR']()); + }) + .finally(() => { + setMoveToInProgress(false); + }); + }, [moveToInProgress, t, workspaceId]); + const openFolderNode = showOpenFolder ? ( +
+ +
+
{t['Open folder']()}
+
+ {t['Open folder hint']()} +
+
+ +
+ ) : null; + return ( +
+
+
{t['Storage Folder']()}
+
+ {t['Storage Folder Hint']()} +
+
+ +
+ {openFolderNode} + +
+ +
+
{t['Move folder']()}
+
+ {t['Move folder hint']()} +
+
+ +
+
+
+
+ ); +} diff --git a/apps/web/src/components/blocksuite/workspace-header/header-right-items/language-menu.tsx b/apps/web/src/components/blocksuite/workspace-header/header-right-items/language-menu.tsx index a7001874d7..2fcc5171e0 100644 --- a/apps/web/src/components/blocksuite/workspace-header/header-right-items/language-menu.tsx +++ b/apps/web/src/components/blocksuite/workspace-header/header-right-items/language-menu.tsx @@ -9,7 +9,9 @@ const LanguageMenuContent: FC = () => { const i18n = useI18N(); const changeLanguage = useCallback( (event: string) => { - void i18n.changeLanguage(event); + i18n.changeLanguage(event).catch(err => { + console.error(err); + }); }, [i18n] ); diff --git a/apps/web/src/components/blocksuite/workspace-header/header.tsx b/apps/web/src/components/blocksuite/workspace-header/header.tsx index ae25b48522..2ccb380cb7 100644 --- a/apps/web/src/components/blocksuite/workspace-header/header.tsx +++ b/apps/web/src/components/blocksuite/workspace-header/header.tsx @@ -12,6 +12,7 @@ import type { PluginUIAdapter } from '@toeverything/plugin-infra/type'; import { useAtom, useAtomValue } from 'jotai'; import type { FC, HTMLAttributes, PropsWithChildren, ReactNode } from 'react'; import { forwardRef, memo, useEffect, useMemo, useState } from 'react'; +import { noop } from 'rxjs'; import { guideDownloadClientTipAtom } from '../../../atoms/guide'; import { contentLayoutAtom } from '../../../atoms/layout'; @@ -104,27 +105,21 @@ const HeaderRightItems: Record = { diff --git a/apps/web/src/components/pure/quick-search-modal/footer.tsx b/apps/web/src/components/pure/quick-search-modal/footer.tsx index 8a5dba24c1..1067bab40d 100644 --- a/apps/web/src/components/pure/quick-search-modal/footer.tsx +++ b/apps/web/src/components/pure/quick-search-modal/footer.tsx @@ -54,7 +54,9 @@ export const Footer: React.FC = ({ title: query, }); onClose(); - void jumpToPage(blockSuiteWorkspace.id, page.id); + jumpToPage(blockSuiteWorkspace.id, page.id).catch(err => { + console.error(err); + }); }, [blockSuiteWorkspace, createPage, jumpToPage, onClose, query])} > diff --git a/apps/web/src/components/root-app-sidebar/index.tsx b/apps/web/src/components/root-app-sidebar/index.tsx index d2a3820c67..f212eb67d2 100644 --- a/apps/web/src/components/root-app-sidebar/index.tsx +++ b/apps/web/src/components/root-app-sidebar/index.tsx @@ -107,7 +107,9 @@ export const RootAppSidebar = ({ const [sidebarOpen, setSidebarOpen] = useAtom(appSidebarOpenAtom); useEffect(() => { if (environment.isDesktop && typeof sidebarOpen === 'boolean') { - window.apis?.ui.handleSidebarVisibilityChange(sidebarOpen); + window.apis?.ui.handleSidebarVisibilityChange(sidebarOpen).catch(err => { + console.error(err); + }); } }, [sidebarOpen]); diff --git a/apps/web/src/layouts/workspace-layout.tsx b/apps/web/src/layouts/workspace-layout.tsx index 2c7c52578c..f9abddc27e 100644 --- a/apps/web/src/layouts/workspace-layout.tsx +++ b/apps/web/src/layouts/workspace-layout.tsx @@ -174,7 +174,9 @@ export const CurrentWorkspaceContext = ({ useEffect(() => { const id = setTimeout(() => { if (!exist) { - void push('/'); + push('/').catch(err => { + console.error(err); + }); globalThis.HALTING_PROBLEM_TIMEOUT <<= 1; } }, globalThis.HALTING_PROBLEM_TIMEOUT); @@ -319,7 +321,9 @@ export const WorkspaceLayoutInner: FC = ({ children }) => { } if (!router.query.pageId) { setCurrentPageId(pageId); - void jumpToPage(currentWorkspace.id, pageId); + jumpToPage(currentWorkspace.id, pageId).catch(err => { + console.error(err); + }); } } //#endregion @@ -353,7 +357,9 @@ export const WorkspaceLayoutInner: FC = ({ children }) => { } ); setCurrentPageId(currentPageId); - void jumpToPage(currentWorkspace.id, page.id); + jumpToPage(currentWorkspace.id, page.id).catch(err => { + console.error(err); + }); } }, [ currentPageId, diff --git a/apps/web/src/pages/index.tsx b/apps/web/src/pages/index.tsx index 739b4607bc..1664aa915f 100644 --- a/apps/web/src/pages/index.tsx +++ b/apps/web/src/pages/index.tsx @@ -39,21 +39,31 @@ const IndexPageInner = () => { nonTrashPages.at(0)?.id; if (pageId) { logger.debug('Found target workspace. Jump to page', pageId); - void jumpToPage(targetWorkspace.id, pageId, RouteLogic.REPLACE); + jumpToPage(targetWorkspace.id, pageId, RouteLogic.REPLACE).catch( + err => { + console.error(err); + } + ); } else { const clearId = setTimeout(() => { dispose.dispose(); logger.debug('Found target workspace. Jump to all pages'); - void jumpToSubPath( + jumpToSubPath( targetWorkspace.id, WorkspaceSubPath.ALL, RouteLogic.REPLACE - ); + ).catch(err => { + console.error(err); + }); }, 1000); const dispose = targetWorkspace.blockSuiteWorkspace.slots.pageAdded.once(pageId => { clearTimeout(clearId); - void jumpToPage(targetWorkspace.id, pageId, RouteLogic.REPLACE); + jumpToPage(targetWorkspace.id, pageId, RouteLogic.REPLACE).catch( + err => { + console.error(err); + } + ); }); return () => { clearTimeout(clearId); diff --git a/apps/web/src/pages/workspace/[workspaceId]/setting.tsx b/apps/web/src/pages/workspace/[workspaceId]/setting.tsx index a04727a2a8..a36cc87e91 100644 --- a/apps/web/src/pages/workspace/[workspaceId]/setting.tsx +++ b/apps/web/src/pages/workspace/[workspaceId]/setting.tsx @@ -11,7 +11,7 @@ import { atomWithStorage } from 'jotai/utils'; import Head from 'next/head'; import type { NextRouter } from 'next/router'; import { useRouter } from 'next/router'; -import React, { useCallback, useEffect } from 'react'; +import React, { useCallback } from 'react'; import { getUIAdapter } from '../../../adapters/workspace'; import { PageLoading } from '../../../components/pure/loading'; @@ -30,7 +30,7 @@ function useTabRouterSync( router: NextRouter, currentTab: SettingPanel, setCurrentTab: (tab: SettingPanel) => void -) { +): void { if (!router.isReady) { return; } @@ -43,33 +43,36 @@ function useTabRouterSync( settingPanelValues.indexOf(queryCurrentTab as SettingPanel) === -1 ) { setCurrentTab(settingPanel.General); - void router.replace({ - pathname: router.pathname, - query: { - ...router.query, - currentTab: settingPanel.General, - }, - }); - return; + router + .replace({ + pathname: router.pathname, + query: { + ...router.query, + currentTab: settingPanel.General, + }, + }) + .catch(console.error); } else if (settingPanelValues.indexOf(currentTab as SettingPanel) === -1) { setCurrentTab(settingPanel.General); - void router.replace({ - pathname: router.pathname, - query: { - ...router.query, - currentTab: settingPanel.General, - }, - }); - return; + router + .replace({ + pathname: router.pathname, + query: { + ...router.query, + currentTab: settingPanel.General, + }, + }) + .catch(console.error); } else if (queryCurrentTab !== currentTab) { - void router.replace({ - pathname: router.pathname, - query: { - ...router.query, - currentTab: currentTab, - }, - }); - return; + router + .replace({ + pathname: router.pathname, + query: { + ...router.query, + currentTab: currentTab, + }, + }) + .catch(console.error); } } @@ -78,20 +81,24 @@ const SettingPage: NextPageWithLayout = () => { const [currentWorkspace] = useCurrentWorkspace(); const t = useAFFiNEI18N(); const [currentTab, setCurrentTab] = useAtom(settingPanelAtom); - useEffect(() => {}); const onChangeTab = useCallback( (tab: SettingPanel) => { setCurrentTab(tab as SettingPanel); - void router.push({ - pathname: router.pathname, - query: { - ...router.query, - currentTab: tab, - }, - }); + router + .push({ + pathname: router.pathname, + query: { + ...router.query, + currentTab: tab, + }, + }) + .catch(err => { + console.error(err); + }); }, [router, setCurrentTab] ); + useTabRouterSync(router, currentTab, setCurrentTab); const helper = useAppHelper(); diff --git a/packages/component/src/components/app-sidebar/app-updater-button/index.jotai.ts b/packages/component/src/components/app-sidebar/app-updater-button/index.jotai.ts index eb89a2eae2..8558bb076e 100644 --- a/packages/component/src/components/app-sidebar/app-updater-button/index.jotai.ts +++ b/packages/component/src/components/app-sidebar/app-updater-button/index.jotai.ts @@ -49,7 +49,9 @@ export const updateAvailableAtom = atomWithObservable(() => { return rpcToObservable(null as any | null, { event: window.events?.updater.onUpdateAvailable, onSubscribe: () => { - window.apis?.updater.checkForUpdatesAndNotify(); + window.apis?.updater.checkForUpdatesAndNotify().catch(err => { + console.error(err); + }); }, }); }); diff --git a/packages/component/src/components/app-sidebar/app-updater-button/index.tsx b/packages/component/src/components/app-sidebar/app-updater-button/index.tsx index b58e51ea50..26f0f1ac5b 100644 --- a/packages/component/src/components/app-sidebar/app-updater-button/index.tsx +++ b/packages/component/src/components/app-sidebar/app-updater-button/index.tsx @@ -65,7 +65,10 @@ export function AppUpdaterButton({ className, style }: AddPageButtonProps) { }, [currentVersion, setChangelogCheckAtom]); const onClickUpdate = useCallback(() => { if (updateReady) { - window.apis?.updater.quitAndInstall(); + window.apis?.updater.quitAndInstall().catch(err => { + // TODO: add error toast here + console.error(err); + }); } else if (updateAvailable) { if (updateAvailable.allowAutoUpdate) { // wait for download to finish diff --git a/packages/component/src/components/page-list/operation-menu-items/copy-link.tsx b/packages/component/src/components/page-list/operation-menu-items/copy-link.tsx index 60022de360..6f5516a909 100644 --- a/packages/component/src/components/page-list/operation-menu-items/copy-link.tsx +++ b/packages/component/src/components/page-list/operation-menu-items/copy-link.tsx @@ -9,8 +9,15 @@ export const CopyLink = ({ onItemClick, onSelect }: CommonMenuItemProps) => { const t = useAFFiNEI18N(); const copyUrl = useCallback(() => { - navigator.clipboard.writeText(window.location.href); - toast(t['Copied link to clipboard']()); + navigator.clipboard + .writeText(window.location.href) + .then(() => { + toast(t['Copied link to clipboard']()); + }) + .catch(err => { + // TODO add error toast here + console.error(err); + }); }, [t]); return ( diff --git a/packages/component/src/components/page-list/operation-menu-items/export.tsx b/packages/component/src/components/page-list/operation-menu-items/export.tsx index 42606ea9ea..a89301b9b0 100644 --- a/packages/component/src/components/page-list/operation-menu-items/export.tsx +++ b/packages/component/src/components/page-list/operation-menu-items/export.tsx @@ -35,8 +35,13 @@ const ExportToPdfMenuItem = ({ if (result !== undefined) { return; } - contentParser.exportPdf(); + return contentParser.exportPdf(); + }) + .then(() => { onSelect?.({ type: 'pdf' }); + }) + .catch(err => { + console.error(err); }); }, [currentEditor, onSelect]); if (currentEditor && currentEditor.mode === 'page') { @@ -66,7 +71,9 @@ const ExportToHtmlMenuItem = ({ if (!contentParserRef.current) { contentParserRef.current = new ContentParser(currentEditor.page); } - contentParserRef.current.exportHtml(); + contentParserRef.current.exportHtml().catch(err => { + console.error(err); + }); onSelect?.({ type: 'html' }); }, [onSelect, currentEditor]); return ( @@ -123,7 +130,9 @@ const ExportToMarkdownMenuItem = ({ if (!contentParserRef.current) { contentParserRef.current = new ContentParser(currentEditor.page); } - contentParserRef.current.exportMarkdown(); + contentParserRef.current.exportMarkdown().catch(err => { + console.error(err); + }); onSelect?.({ type: 'markdown' }); }, [onSelect, currentEditor]); return ( diff --git a/packages/component/src/components/theme-provider/index.tsx b/packages/component/src/components/theme-provider/index.tsx index dd4770522b..097bafd2bb 100644 --- a/packages/component/src/components/theme-provider/index.tsx +++ b/packages/component/src/components/theme-provider/index.tsx @@ -10,7 +10,11 @@ const DesktopThemeSync = memo(function DesktopThemeSync() { const onceRef = useRef(false); if (lastThemeRef.current !== theme || !onceRef.current) { if (environment.isDesktop && theme) { - window.apis?.ui.handleThemeChange(theme as 'dark' | 'light' | 'system'); + window.apis?.ui + .handleThemeChange(theme as 'dark' | 'light' | 'system') + .catch(err => { + console.error(err); + }); } lastThemeRef.current = theme; onceRef.current = true; diff --git a/packages/plugin-infra/src/manager.ts b/packages/plugin-infra/src/manager.ts index 67d51d1b0a..d816b57ffb 100644 --- a/packages/plugin-infra/src/manager.ts +++ b/packages/plugin-infra/src/manager.ts @@ -32,15 +32,20 @@ export function definePlugin( if (isServer) { if (serverAdapter) { - serverAdapter.load().then(({ default: adapter }) => { - rootStore.set(affinePluginsAtom, plugins => ({ - ...plugins, - [definition.id]: { - ...basePlugin, - serverAdapter: adapter, - }, - })); - }); + serverAdapter + .load() + .then(({ default: adapter }) => { + rootStore.set(affinePluginsAtom, plugins => ({ + ...plugins, + [definition.id]: { + ...basePlugin, + serverAdapter: adapter, + }, + })); + }) + .catch(err => { + console.error(err); + }); } } else if (isClient) { if (blockSuiteAdapter) { diff --git a/packages/workspace/src/providers/index.ts b/packages/workspace/src/providers/index.ts index 82286eeb7e..baebed7cd1 100644 --- a/packages/workspace/src/providers/index.ts +++ b/packages/workspace/src/providers/index.ts @@ -171,7 +171,9 @@ const createSQLiteProvider = ( if (origin === sqliteOrigin) { return; } - apis.db.applyDocUpdate(blockSuiteWorkspace.id, update); + apis.db.applyDocUpdate(blockSuiteWorkspace.id, update).catch(err => { + console.error(err); + }); } let unsubscribe = () => {}; @@ -247,7 +249,7 @@ const createSQLiteDBDownloadProvider = ( const diff = Y.encodeStateAsUpdate(blockSuiteWorkspace.doc, updates); // also apply updates to sqlite - apis.db.applyDocUpdate(blockSuiteWorkspace.id, diff); + await apis.db.applyDocUpdate(blockSuiteWorkspace.id, diff); const bs = blockSuiteWorkspace.blobs; diff --git a/plugins/copilot/src/UI/detail-content.tsx b/plugins/copilot/src/UI/detail-content.tsx index 3540d1e9db..2ada4adf6d 100644 --- a/plugins/copilot/src/UI/detail-content.tsx +++ b/plugins/copilot/src/UI/detail-content.tsx @@ -12,47 +12,48 @@ import { openAIApiKeyAtom, useChatAtoms } from '../core/hooks'; import { detailContentActionsStyle, detailContentStyle } from './index.css'; if (typeof window === 'undefined') { - import('@blocksuite/blocks').then(({ FormatQuickBar }) => { - FormatQuickBar.customElements.push((_page, getSelection) => { - const div = document.createElement('div'); - const root = createRoot(div); + import('@blocksuite/blocks') + .then(({ FormatQuickBar }) => { + FormatQuickBar.customElements.push((_page, getSelection) => { + const div = document.createElement('div'); + const root = createRoot(div); - const AskAI = (): ReactElement => { - const { conversationAtom } = useChatAtoms(); - const call = useSetAtom(conversationAtom); + const AskAI = (): ReactElement => { + const { conversationAtom } = useChatAtoms(); + const call = useSetAtom(conversationAtom); + const onClickAskAI = useCallback(() => { + const selection = getSelection(); + if (selection != null) { + const text = selection.models + .map(model => { + return model.text?.toString(); + }) + .filter((v): v is string => Boolean(v)) + .join('\n'); + console.log('selected text:', text); + call( + `I selected some text from the document: \n"${text}."` + ).catch(err => { + console.error(err); + }); + } + }, [call]); - return ( -
{ - const selection = getSelection(); - if (selection != null) { - const text = selection.models - .map(model => { - return model.text?.toString(); - }) - .filter((v): v is string => Boolean(v)) - .join('\n'); - console.log('selected text:', text); - void call( - `I selected some text from the document: \n"${text}."` - ); - } - }} - > - Ask AI -
+ return
Ask AI
; + }; + root.render( + + + + + ); - }; - root.render( - - - - - - ); - return div; + return div; + }); + }) + .catch(error => { + console.error(error); }); - }); } const Actions = () => { diff --git a/plugins/copilot/src/core/hooks/index.ts b/plugins/copilot/src/core/hooks/index.ts index 02772d6e1c..8e21e4e718 100644 --- a/plugins/copilot/src/core/hooks/index.ts +++ b/plugins/copilot/src/core/hooks/index.ts @@ -49,9 +49,14 @@ const getConversationAtom = (chat: ConversationChain) => { throw new Error(); } const memory = chat.memory as BufferMemory; - void memory.chatHistory.getMessages().then(messages => { - setAtom(messages); - }); + memory.chatHistory + .getMessages() + .then(messages => { + setAtom(messages); + }) + .catch(err => { + console.error(err); + }); const llmStart = (): void => { setAtom(conversations => [...conversations, new AIChatMessage('')]); }; @@ -86,9 +91,14 @@ const getConversationAtom = (chat: ConversationChain) => { }); // refresh messages const memory = chat.memory as BufferMemory; - void memory.chatHistory.getMessages().then(messages => { - set(conversationBaseAtom, messages); - }); + memory.chatHistory + .getMessages() + .then(messages => { + set(conversationBaseAtom, messages); + }) + .catch(err => { + console.error(err); + }); } ); conversationWeakMap.set(chat, conversationAtom);