refactor(electron): create electron api package (#5334)

This commit is contained in:
EYHN
2023-12-27 06:38:37 +00:00
parent ce17daba42
commit 4e861d8118
53 changed files with 307 additions and 690 deletions

View File

@@ -20,6 +20,7 @@
"@affine/cmdk": "workspace:*",
"@affine/component": "workspace:*",
"@affine/debug": "workspace:*",
"@affine/electron-api": "workspace:*",
"@affine/env": "workspace:*",
"@affine/graphql": "workspace:*",
"@affine/i18n": "workspace:*",

View File

@@ -1,3 +1,4 @@
import { apis } from '@affine/electron-api';
import type { useAFFiNEI18N } from '@affine/i18n/hooks';
import { ResetIcon } from '@blocksuite/icons';
import { updateReadyAtom } from '@toeverything/hooks/use-app-updater';
@@ -21,7 +22,7 @@ export function registerAffineUpdatesCommands({
label: t['com.affine.cmdk.affine.restart-to-upgrade'](),
preconditionStrategy: () => !!store.get(updateReadyAtom),
run() {
window.apis?.updater.quitAndInstall().catch(err => {
apis?.updater.quitAndInstall().catch(err => {
// TODO: add error toast here
console.error(err);
});

View File

@@ -1,3 +1,4 @@
import { apis } from '@affine/electron-api';
import { fetchWithTraceReport } from '@affine/graphql';
import { Turnstile } from '@marsidev/react-turnstile';
import { atom, useAtom, useSetAtom } from 'jotai';
@@ -32,7 +33,7 @@ const generateChallengeResponse = async (challenge: string) => {
return undefined;
}
return await window.apis?.ui?.getChallengeResponse(challenge);
return await apis?.ui?.getChallengeResponse(challenge);
};
const captchaAtom = atom<string | undefined>(undefined);

View File

@@ -5,6 +5,7 @@ import {
Modal,
} from '@affine/component/ui/modal';
import { DebugLogger } from '@affine/debug';
import { apis } from '@affine/electron-api';
import { WorkspaceFlavour } from '@affine/env/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { workspaceManagerAtom } from '@affine/workspace/atom';
@@ -14,7 +15,6 @@ import {
buildShowcaseWorkspace,
initEmptyPage,
} from '@toeverything/infra/blocksuite';
import type { LoadDBFileResult } from '@toeverything/infra/type';
import { useAtomValue } from 'jotai';
import type { KeyboardEvent } from 'react';
import { useLayoutEffect } from 'react';
@@ -112,12 +112,12 @@ export const CreateWorkspaceModal = ({
// after it is done, it will effectively add a new workspace to app-data folder
// so after that, we will be able to load it via importLocalWorkspace
(async () => {
if (!window.apis) {
if (!apis) {
return;
}
logger.info('load db file');
setStep(undefined);
const result: LoadDBFileResult = await window.apis.dialog.loadDBFile();
const result = await apis.dialog.loadDBFile();
if (result.workspaceId && !canceled) {
workspaceManager._addLocalWorkspace(result.workspaceId);
onCreate(result.workspaceId);

View File

@@ -1,10 +1,10 @@
import { pushNotificationAtom } from '@affine/component/notification-center';
import { SettingRow } from '@affine/component/setting-components';
import { Button } from '@affine/component/ui/button';
import { apis } from '@affine/electron-api';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { Workspace, WorkspaceMetadata } from '@affine/workspace';
import { useAsyncCallback } from '@toeverything/hooks/affine-async-hooks';
import type { SaveDBFileResult } from '@toeverything/infra/type';
import { useSetAtom } from 'jotai';
import { useState } from 'react';
@@ -30,8 +30,7 @@ export const ExportPanel = ({
try {
await workspace.engine.sync.waitForSynced();
await workspace.engine.blob.sync();
const result: SaveDBFileResult =
await window.apis?.dialog.saveDBFileAs(workspaceId);
const result = await apis?.dialog.saveDBFileAs(workspaceId);
if (result?.error) {
throw new Error(result.error);
} else if (!result?.canceled) {

View File

@@ -2,17 +2,17 @@ import { FlexWrapper, toast } from '@affine/component';
import { SettingRow } from '@affine/component/setting-components';
import { Button } from '@affine/component/ui/button';
import { Tooltip } from '@affine/component/ui/tooltip';
import { apis, events } from '@affine/electron-api';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { WorkspaceMetadata } from '@affine/workspace/metadata';
import type { MoveDBFileResult } from '@toeverything/infra/type';
import { useMemo } from 'react';
import { useCallback, useEffect, useState } from 'react';
const useDBFileSecondaryPath = (workspaceId: string) => {
const [path, setPath] = useState<string | undefined>(undefined);
useEffect(() => {
if (window.apis && window.events && environment.isDesktop) {
window.apis?.workspace
if (apis && events && environment.isDesktop) {
apis?.workspace
.getMeta(workspaceId)
.then(meta => {
setPath(meta.secondaryDBPath);
@@ -20,7 +20,7 @@ const useDBFileSecondaryPath = (workspaceId: string) => {
.catch(err => {
console.error(err);
});
return window.events.workspace.onMetaChange((newMeta: any) => {
return events.workspace.onMetaChange((newMeta: any) => {
if (newMeta.workspaceId === workspaceId) {
const meta = newMeta.meta;
setPath(meta.secondaryDBPath);
@@ -43,7 +43,7 @@ export const StoragePanel = ({ workspaceMetadata }: StoragePanelProps) => {
const [moveToInProgress, setMoveToInProgress] = useState<boolean>(false);
const onRevealDBFile = useCallback(() => {
window.apis?.dialog.revealDBFile(workspaceId).catch(err => {
apis?.dialog.revealDBFile(workspaceId).catch(err => {
console.error(err);
});
}, [workspaceId]);
@@ -53,9 +53,9 @@ export const StoragePanel = ({ workspaceMetadata }: StoragePanelProps) => {
return;
}
setMoveToInProgress(true);
window.apis?.dialog
apis?.dialog
.moveDBFile(workspaceId)
.then((result: MoveDBFileResult) => {
.then(result => {
if (!result?.error && !result?.canceled) {
toast(t['Move folder success']());
} else if (result?.error) {

View File

@@ -1,3 +1,4 @@
import { apis, events } from '@affine/electron-api';
import { useAtomValue } from 'jotai';
import { atomWithObservable } from 'jotai/utils';
import { useCallback } from 'react';
@@ -8,7 +9,7 @@ import * as style from './style.css';
const maximizedAtom = atomWithObservable(() => {
return new Observable<boolean>(subscriber => {
subscriber.next(false);
return window.events?.ui.onMaximized(maximized => {
return events?.ui.onMaximized(maximized => {
return subscriber.next(maximized);
});
});
@@ -76,17 +77,17 @@ const unmaximizedSVG = (
export const WindowsAppControls = () => {
const handleMinimizeApp = useCallback(() => {
window.apis?.ui.handleMinimizeApp().catch(err => {
apis?.ui.handleMinimizeApp().catch(err => {
console.error(err);
});
}, []);
const handleMaximizeApp = useCallback(() => {
window.apis?.ui.handleMaximizeApp().catch(err => {
apis?.ui.handleMaximizeApp().catch(err => {
console.error(err);
});
}, []);
const handleCloseApp = useCallback(() => {
window.apis?.ui.handleCloseApp().catch(err => {
apis?.ui.handleCloseApp().catch(err => {
console.error(err);
});
}, []);

View File

@@ -20,6 +20,7 @@ import {
} from '@affine/component/page-list';
import { Menu } from '@affine/component/ui/menu';
import { collectionsCRUDAtom } from '@affine/core/atoms/collections';
import { apis, events } from '@affine/electron-api';
import { WorkspaceSubPath } from '@affine/env/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { Workspace } from '@affine/workspace';
@@ -141,7 +142,7 @@ export const RootAppSidebar = ({
// Listen to the "New Page" action from the menu
useEffect(() => {
if (environment.isDesktop) {
return window.events?.applicationMenu.onNewPageAction(onClickNewPage);
return events?.applicationMenu.onNewPageAction(onClickNewPage);
}
return;
}, [onClickNewPage]);
@@ -149,7 +150,7 @@ export const RootAppSidebar = ({
const sidebarOpen = useAtomValue(appSidebarOpenAtom);
useEffect(() => {
if (environment.isDesktop) {
window.apis?.ui.handleSidebarVisibilityChange(sidebarOpen).catch(err => {
apis?.ui.handleSidebarVisibilityChange(sidebarOpen).catch(err => {
console.error(err);
});
}

View File

@@ -3,6 +3,7 @@ import {
resolveGlobalLoadingEventAtom,
} from '@affine/component/global-loading';
import { pushNotificationAtom } from '@affine/component/notification-center';
import { apis } from '@affine/electron-api';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import {
HtmlTransformer,
@@ -49,7 +50,7 @@ async function exportHandler({ page, type }: ExportHandlerOptions) {
break;
case 'pdf':
if (environment.isDesktop && page.meta.mode === 'page') {
await window.apis?.export.savePDFFileAs(
await apis?.export.savePDFFileAs(
(page.root as PageBlockModel).title.toString()
);
} else {

View File

@@ -1,3 +1,5 @@
import { apis } from '@affine/electron-api';
import { assertExists } from '@blocksuite/global/utils';
import {
type AppConfigSchema,
AppConfigStorage,
@@ -13,11 +15,13 @@ class AppConfigProxy {
value: AppConfigSchema = defaultAppConfig;
async getSync(): Promise<AppConfigSchema> {
return (this.value = await window.apis.configStorage.get());
assertExists(apis);
return (this.value = await apis.configStorage.get());
}
async setSync(): Promise<void> {
await window.apis.configStorage.set(this.value);
assertExists(apis);
await apis.configStorage.set(this.value);
}
get(): AppConfigSchema {

View File

@@ -1,3 +1,5 @@
import { apis } from '@affine/electron-api';
import { assertExists } from '@blocksuite/global/utils';
import { useCallback } from 'react';
import { redirect } from 'react-router-dom';
@@ -23,7 +25,8 @@ export const Component = () => {
const openApp = useCallback(() => {
if (environment.isDesktop) {
window.apis.ui.handleOpenMainApp().catch(err => {
assertExists(apis);
apis.ui.handleOpenMainApp().catch(err => {
console.log('failed to open main app', err);
});
} else {

View File

@@ -23,6 +23,9 @@
{
"path": "../../frontend/workspace"
},
{
"path": "../../frontend/electron-api"
},
{
"path": "../../common/debug"
},