mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 04:18:54 +00:00
refactor(electron): create electron api package (#5334)
This commit is contained in:
@@ -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:*",
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}, []);
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
{
|
||||
"path": "../../frontend/workspace"
|
||||
},
|
||||
{
|
||||
"path": "../../frontend/electron-api"
|
||||
},
|
||||
{
|
||||
"path": "../../common/debug"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user