diff --git a/packages/frontend/core/src/blocksuite/presets/ai/ai-spec.ts b/packages/frontend/core/src/blocksuite/presets/ai/ai-spec.ts
index 76a0cbab5a..66c12f74ca 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/ai-spec.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/ai-spec.ts
@@ -26,15 +26,15 @@ import { assertInstanceOf } from '@blocksuite/global/utils';
import { literal, unsafeStatic } from 'lit/static-html.js';
import { buildAIPanelConfig } from './ai-panel';
-import { setupCodeToolbarEntry } from './entries/code-toolbar/setup-code-toolbar';
+import { setupCodeToolbarAIEntry } from './entries/code-toolbar/setup-code-toolbar';
import {
setupEdgelessCopilot,
- setupEdgelessElementToolbarEntry,
+ setupEdgelessElementToolbarAIEntry,
} from './entries/edgeless/index';
-import { setupFormatBarEntry } from './entries/format-bar/setup-format-bar';
-import { setupImageToolbarEntry } from './entries/image-toolbar/setup-image-toolbar';
-import { setupSlashMenuEntry } from './entries/slash-menu/setup-slash-menu';
-import { setupSpaceEntry } from './entries/space/setup-space';
+import { setupFormatBarAIEntry } from './entries/format-bar/setup-format-bar';
+import { setupImageToolbarAIEntry } from './entries/image-toolbar/setup-image-toolbar';
+import { setupSlashMenuAIEntry } from './entries/slash-menu/setup-slash-menu';
+import { setupSpaceAIEntry } from './entries/space/setup-space';
class AIPageRootWatcher extends BlockServiceWatcher {
static override readonly flavour = 'affine:page';
@@ -45,15 +45,15 @@ class AIPageRootWatcher extends BlockServiceWatcher {
if (view.component instanceof AffineAIPanelWidget) {
view.component.style.width = '630px';
view.component.config = buildAIPanelConfig(view.component);
- setupSpaceEntry(view.component);
+ setupSpaceAIEntry(view.component);
}
if (view.component instanceof AffineFormatBarWidget) {
- setupFormatBarEntry(view.component);
+ setupFormatBarAIEntry(view.component);
}
if (view.component instanceof AffineSlashMenuWidget) {
- setupSlashMenuEntry(view.component);
+ setupSlashMenuAIEntry(view.component);
}
});
}
@@ -85,7 +85,7 @@ class AIEdgelessRootWatcher extends BlockServiceWatcher {
if (view.component instanceof AffineAIPanelWidget) {
view.component.style.width = '430px';
view.component.config = buildAIPanelConfig(view.component);
- setupSpaceEntry(view.component);
+ setupSpaceAIEntry(view.component);
}
if (view.component instanceof EdgelessCopilotWidget) {
@@ -93,15 +93,15 @@ class AIEdgelessRootWatcher extends BlockServiceWatcher {
}
if (view.component instanceof EdgelessElementToolbarWidget) {
- setupEdgelessElementToolbarEntry(view.component);
+ setupEdgelessElementToolbarAIEntry(view.component);
}
if (view.component instanceof AffineFormatBarWidget) {
- setupFormatBarEntry(view.component);
+ setupFormatBarAIEntry(view.component);
}
if (view.component instanceof AffineSlashMenuWidget) {
- setupSlashMenuEntry(view.component);
+ setupSlashMenuAIEntry(view.component);
}
});
}
@@ -166,7 +166,7 @@ class AICodeBlockWatcher extends BlockServiceWatcher {
const service = this.blockService;
service.specSlots.widgetConnected.on(view => {
if (view.component instanceof AffineCodeToolbarWidget) {
- setupCodeToolbarEntry(view.component);
+ setupCodeToolbarAIEntry(view.component);
}
});
}
@@ -184,7 +184,7 @@ class AIImageBlockWatcher extends BlockServiceWatcher {
super.mounted();
this.blockService.specSlots.widgetConnected.on(view => {
if (view.component instanceof AffineImageToolbarWidget) {
- setupImageToolbarEntry(view.component);
+ setupImageToolbarAIEntry(view.component);
}
});
}
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/entries/code-toolbar/setup-code-toolbar.ts b/packages/frontend/core/src/blocksuite/presets/ai/entries/code-toolbar/setup-code-toolbar.ts
index 3e4a64e9ea..c531c547cf 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/entries/code-toolbar/setup-code-toolbar.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/entries/code-toolbar/setup-code-toolbar.ts
@@ -12,7 +12,7 @@ const buttonOptions: AskAIButtonOptions = {
import type { AskAIButtonOptions } from '../../_common/components/ask-ai-button';
import { buildAICodeItemGroups } from '../../_common/config';
-export function setupCodeToolbarEntry(codeToolbar: AffineCodeToolbarWidget) {
+export function setupCodeToolbarAIEntry(codeToolbar: AffineCodeToolbarWidget) {
codeToolbar.addPrimaryItems([
{
type: 'ask-ai',
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/entries/edgeless/index.ts b/packages/frontend/core/src/blocksuite/presets/ai/entries/edgeless/index.ts
index 1bc00b80b7..7cd5bb92bc 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/entries/edgeless/index.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/entries/edgeless/index.ts
@@ -17,7 +17,7 @@ export function setupEdgelessCopilot(widget: EdgelessCopilotWidget) {
widget.groups = edgelessActionGroups;
}
-export function setupEdgelessElementToolbarEntry(
+export function setupEdgelessElementToolbarAIEntry(
widget: EdgelessElementToolbarWidget
) {
widget.registerEntry({
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/entries/format-bar/setup-format-bar.ts b/packages/frontend/core/src/blocksuite/presets/ai/entries/format-bar/setup-format-bar.ts
index 90302086b4..9061f40c08 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/entries/format-bar/setup-format-bar.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/entries/format-bar/setup-format-bar.ts
@@ -8,7 +8,7 @@ import { html, type TemplateResult } from 'lit';
import { AIItemGroups } from '../../_common/config';
-export function setupFormatBarEntry(formatBar: AffineFormatBarWidget) {
+export function setupFormatBarAIEntry(formatBar: AffineFormatBarWidget) {
toolbarDefaultConfig(formatBar);
formatBar.addRawConfigItems(
[
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/entries/image-toolbar/setup-image-toolbar.ts b/packages/frontend/core/src/blocksuite/presets/ai/entries/image-toolbar/setup-image-toolbar.ts
index f59c97e1d8..54e219568d 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/entries/image-toolbar/setup-image-toolbar.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/entries/image-toolbar/setup-image-toolbar.ts
@@ -13,7 +13,9 @@ const buttonOptions: AskAIButtonOptions = {
panelWidth: 300,
};
-export function setupImageToolbarEntry(imageToolbar: AffineImageToolbarWidget) {
+export function setupImageToolbarAIEntry(
+ imageToolbar: AffineImageToolbarWidget
+) {
imageToolbar.addPrimaryItems(
[
{
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/entries/slash-menu/setup-slash-menu.ts b/packages/frontend/core/src/blocksuite/presets/ai/entries/slash-menu/setup-slash-menu.ts
index 501cdad470..a9a5bc5b8f 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/entries/slash-menu/setup-slash-menu.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/entries/slash-menu/setup-slash-menu.ts
@@ -20,7 +20,7 @@ import { AIItemGroups } from '../../_common/config';
import { handleInlineAskAIAction } from '../../actions/doc-handler';
import { AIProvider } from '../../provider';
-export function setupSlashMenuEntry(slashMenu: AffineSlashMenuWidget) {
+export function setupSlashMenuAIEntry(slashMenu: AffineSlashMenuWidget) {
const AIItems = AIItemGroups.map(group => group.items).flat();
const iconWrapper = (icon: AIItemConfig['icon']) => {
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/entries/space/setup-space.ts b/packages/frontend/core/src/blocksuite/presets/ai/entries/space/setup-space.ts
index 3f990f014e..e394a1b395 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/entries/space/setup-space.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/entries/space/setup-space.ts
@@ -3,7 +3,7 @@ import type { AffineAIPanelWidget } from '@blocksuite/blocks';
import { handleInlineAskAIAction } from '../../actions/doc-handler';
import { AIProvider } from '../../provider';
-export function setupSpaceEntry(panel: AffineAIPanelWidget) {
+export function setupSpaceAIEntry(panel: AffineAIPanelWidget) {
panel.handleEvent('keyDown', ctx => {
const host = panel.host;
const keyboardState = ctx.get('keyboardState');
diff --git a/packages/frontend/core/src/components/affine/ai-onboarding/index.tsx b/packages/frontend/core/src/components/affine/ai-onboarding/index.tsx
index 1dcd47b82e..429d9acb90 100644
--- a/packages/frontend/core/src/components/affine/ai-onboarding/index.tsx
+++ b/packages/frontend/core/src/components/affine/ai-onboarding/index.tsx
@@ -1,3 +1,5 @@
+import { EditorSettingService } from '@affine/core/modules/editor-settting';
+import { useLiveData, useService } from '@toeverything/infra';
import { Suspense, useCallback, useEffect, useState } from 'react';
import { AIOnboardingEdgeless } from './edgeless.dialog';
@@ -28,19 +30,29 @@ const useDismiss = (key: AIOnboardingType) => {
export const WorkspaceAIOnboarding = () => {
const [dismissGeneral] = useDismiss(AIOnboardingType.GENERAL);
const [dismissLocal] = useDismiss(AIOnboardingType.LOCAL);
+ const editorSettingService = useService(EditorSettingService);
+ const enableAI = useLiveData(
+ editorSettingService.editorSetting.settings$.map(s => s.enableAI)
+ );
return (
- {dismissGeneral ? null : }
- {dismissLocal ? null : }
+ {!enableAI || dismissGeneral ? null : }
+ {!enableAI || dismissLocal ? null : }
);
};
export const PageAIOnboarding = () => {
const [dismissEdgeless] = useDismiss(AIOnboardingType.EDGELESS);
+ const editorSettingService = useService(EditorSettingService);
+ const enableAI = useLiveData(
+ editorSettingService.editorSetting.settings$.map(s => s.enableAI)
+ );
return (
- {dismissEdgeless ? null : }
+
+ {!enableAI || dismissEdgeless ? null : }
+
);
};
diff --git a/packages/frontend/core/src/components/affine/setting-modal/general-setting/editor/general.tsx b/packages/frontend/core/src/components/affine/setting-modal/general-setting/editor/general.tsx
index 54f91ebc49..e772c7179d 100644
--- a/packages/frontend/core/src/components/affine/setting-modal/general-setting/editor/general.tsx
+++ b/packages/frontend/core/src/components/affine/setting-modal/general-setting/editor/general.tsx
@@ -8,6 +8,7 @@ import {
type RadioItem,
Scrollable,
Switch,
+ useConfirmModal,
} from '@affine/component';
import {
SettingRow,
@@ -393,16 +394,51 @@ export const SpellCheckSettings = () => {
);
};
+const AISettings = () => {
+ const t = useI18n();
+ const { openConfirmModal } = useConfirmModal();
+ const { editorSettingService } = useServices({ EditorSettingService });
+
+ const settings = useLiveData(editorSettingService.editorSetting.settings$);
+
+ const onAIChange = useCallback(
+ (checked: boolean) => {
+ editorSettingService.editorSetting.set('enableAI', checked);
+ },
+ [editorSettingService]
+ );
+ const onToggleAI = useCallback(
+ (checked: boolean) => {
+ openConfirmModal({
+ title: checked ? 'Enable AI?' : 'Disable AI?',
+ description: `Are you sure you want to ${checked ? 'enable' : 'disable'} AI?`,
+ confirmText: checked ? 'Enable' : 'Disable',
+ cancelText: 'Cancel',
+ onConfirm: () => onAIChange(checked),
+ confirmButtonOptions: {
+ variant: checked ? 'primary' : 'error',
+ },
+ });
+ },
+ [openConfirmModal, onAIChange]
+ );
+
+ return (
+
+
+
+ );
+};
+
export const General = () => {
const t = useI18n();
+
return (
-
-
-
+
diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/lit-adaper.tsx b/packages/frontend/core/src/components/blocksuite/block-suite-editor/lit-adaper.tsx
index 5e297e81c8..65cec65462 100644
--- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/lit-adaper.tsx
+++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/lit-adaper.tsx
@@ -15,6 +15,7 @@ import {
useFramework,
useLiveData,
useService,
+ useServices,
} from '@toeverything/infra';
import React, {
forwardRef,
@@ -65,9 +66,13 @@ interface BlocksuiteEditorProps {
const usePatchSpecs = (page: Doc, shared: boolean, mode: DocMode) => {
const [reactToLit, portals] = useLitPortalFactory();
- const peekViewService = useService(PeekViewService);
- const docService = useService(DocService);
- const docsService = useService(DocsService);
+ const { peekViewService, docService, docsService, editorSettingService } =
+ useServices({
+ PeekViewService,
+ DocService,
+ DocsService,
+ EditorSettingService,
+ });
const framework = useFramework();
const referenceRenderer: ReferenceReactRenderer = useMemo(() => {
return function customReference(reference) {
@@ -89,10 +94,12 @@ const usePatchSpecs = (page: Doc, shared: boolean, mode: DocMode) => {
}, [mode, page.collection]);
const specs = useMemo(() => {
+ const enableAI =
+ editorSettingService.editorSetting.settings$.value.enableAI;
return mode === 'edgeless'
- ? createEdgelessModeSpecs(framework)
- : createPageModeSpecs(framework);
- }, [mode, framework]);
+ ? createEdgelessModeSpecs(framework, enableAI)
+ : createPageModeSpecs(framework, enableAI);
+ }, [editorSettingService, mode, framework]);
const confirmModal = useConfirmModal();
const patchedSpecs = useMemo(() => {
diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/common.ts b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/common.ts
index 22c81e0157..420755201a 100644
--- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/common.ts
+++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/common.ts
@@ -6,6 +6,7 @@ import {
import type { ExtensionType } from '@blocksuite/block-std';
import {
BookmarkBlockSpec,
+ CodeBlockSpec,
DatabaseBlockSpec,
DataViewBlockSpec,
DividerBlockSpec,
@@ -16,12 +17,15 @@ import {
EmbedLoomBlockSpec,
EmbedSyncedDocBlockSpec,
EmbedYoutubeBlockSpec,
+ ImageBlockSpec,
ListBlockSpec,
+ ParagraphBlockSpec,
} from '@blocksuite/blocks';
+import { AIChatBlockSpec } from '@blocksuite/presets';
import { CustomAttachmentBlockSpec } from './custom/attachment-block';
-export const CommonBlockSpecs: ExtensionType[] = [
+const CommonBlockSpecs: ExtensionType[] = [
ListBlockSpec,
DatabaseBlockSpec,
DataViewBlockSpec,
@@ -36,7 +40,19 @@ export const CommonBlockSpecs: ExtensionType[] = [
EmbedLinkedDocBlockSpec,
// special
CustomAttachmentBlockSpec,
+].flat();
+
+export const DefaultBlockSpecs: ExtensionType[] = [
+ CodeBlockSpec,
+ ImageBlockSpec,
+ ParagraphBlockSpec,
+ ...CommonBlockSpecs,
+].flat();
+
+export const AIBlockSpecs: ExtensionType[] = [
AICodeBlockSpec,
AIImageBlockSpec,
AIParagraphBlockSpec,
+ AIChatBlockSpec,
+ ...CommonBlockSpecs,
].flat();
diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/root-block.ts b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/root-block.ts
index 9ec77759d9..c6d146e1eb 100644
--- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/root-block.ts
+++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/root-block.ts
@@ -14,7 +14,9 @@ import {
import type { RootService, TelemetryEventMap } from '@blocksuite/blocks';
import {
AffineCanvasTextFonts,
+ EdgelessRootBlockSpec,
EdgelessRootService,
+ PageRootBlockSpec,
PageRootService,
} from '@blocksuite/blocks';
import { type FrameworkProvider } from '@toeverything/infra';
@@ -55,11 +57,12 @@ function withAffineRootService(Service: typeof PageRootService) {
}
export function createPageRootBlockSpec(
- framework: FrameworkProvider
+ framework: FrameworkProvider,
+ enableAI: boolean
): ExtensionType[] {
const editorSettingService = framework.get(EditorSettingService);
return [
- ...AIPageRootBlockSpec,
+ ...(enableAI ? AIPageRootBlockSpec : PageRootBlockSpec),
{
setup: di => {
di.override(
@@ -79,11 +82,12 @@ export function createPageRootBlockSpec(
}
export function createEdgelessRootBlockSpec(
- framework: FrameworkProvider
+ framework: FrameworkProvider,
+ enableAI: boolean
): ExtensionType[] {
const editorSettingService = framework.get(EditorSettingService);
return [
- ...AIEdgelessRootBlockSpec,
+ ...(enableAI ? AIEdgelessRootBlockSpec : EdgelessRootBlockSpec),
{
setup: di => {
di.override(
diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/edgeless.ts b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/edgeless.ts
index 932262c1c8..61034af30d 100644
--- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/edgeless.ts
+++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/edgeless.ts
@@ -6,24 +6,23 @@ import {
EdgelessTextBlockSpec,
FrameBlockSpec,
} from '@blocksuite/blocks';
-import { AIChatBlockSpec } from '@blocksuite/presets';
import type { FrameworkProvider } from '@toeverything/infra';
-import { CommonBlockSpecs } from './common';
+import { AIBlockSpecs, DefaultBlockSpecs } from './common';
import { createEdgelessRootBlockSpec } from './custom/root-block';
export function createEdgelessModeSpecs(
- framework: FrameworkProvider
+ framework: FrameworkProvider,
+ enableAI: boolean
): ExtensionType[] {
return [
- ...CommonBlockSpecs,
+ ...(enableAI ? AIBlockSpecs : DefaultBlockSpecs),
EdgelessSurfaceBlockSpec,
EdgelessSurfaceRefBlockSpec,
FrameBlockSpec,
EdgelessTextBlockSpec,
EdgelessNoteBlockSpec,
- AIChatBlockSpec,
// special
- createEdgelessRootBlockSpec(framework),
+ createEdgelessRootBlockSpec(framework, enableAI),
].flat();
}
diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/page.ts b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/page.ts
index 4f9907badc..13f1864cd7 100644
--- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/page.ts
+++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/page.ts
@@ -4,22 +4,21 @@ import {
PageSurfaceBlockSpec,
PageSurfaceRefBlockSpec,
} from '@blocksuite/blocks';
-import { AIChatBlockSpec } from '@blocksuite/presets';
import { type FrameworkProvider } from '@toeverything/infra';
-import { CommonBlockSpecs } from './common';
+import { AIBlockSpecs, DefaultBlockSpecs } from './common';
import { createPageRootBlockSpec } from './custom/root-block';
export function createPageModeSpecs(
- framework: FrameworkProvider
+ framework: FrameworkProvider,
+ enableAI: boolean
): ExtensionType[] {
return [
- ...CommonBlockSpecs,
+ ...(enableAI ? AIBlockSpecs : DefaultBlockSpecs),
PageSurfaceBlockSpec,
PageSurfaceRefBlockSpec,
NoteBlockSpec,
- AIChatBlockSpec,
// special
- createPageRootBlockSpec(framework),
+ createPageRootBlockSpec(framework, enableAI),
].flat();
}
diff --git a/packages/frontend/core/src/modules/editor-settting/schema.ts b/packages/frontend/core/src/modules/editor-settting/schema.ts
index d6fd33f473..dadfa7a86e 100644
--- a/packages/frontend/core/src/modules/editor-settting/schema.ts
+++ b/packages/frontend/core/src/modules/editor-settting/schema.ts
@@ -29,6 +29,7 @@ export const fontStyleOptions = [
}[];
const AffineEditorSettingSchema = z.object({
+ enableAI: z.boolean().default(true),
fontFamily: z.enum(['Sans', 'Serif', 'Mono', 'Custom']).default('Sans'),
customFontFamily: z.string().default(''),
newDocDefaultMode: z.enum(['edgeless', 'page']).default('page'),
diff --git a/packages/frontend/core/src/pages/workspace/detail-page/detail-page.tsx b/packages/frontend/core/src/pages/workspace/detail-page/detail-page.tsx
index 0a793c027a..e9bc127f37 100644
--- a/packages/frontend/core/src/pages/workspace/detail-page/detail-page.tsx
+++ b/packages/frontend/core/src/pages/workspace/detail-page/detail-page.tsx
@@ -7,6 +7,7 @@ import { EditorOutlineViewer } from '@affine/core/components/blocksuite/outline-
import { useAppSettingHelper } from '@affine/core/hooks/affine/use-app-setting-helper';
import { useDocMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta';
import { EditorService } from '@affine/core/modules/editor';
+import { EditorSettingService } from '@affine/core/modules/editor-settting';
import { RecentDocsService } from '@affine/core/modules/quicksearch';
import { ViewService } from '@affine/core/modules/workbench/services/view';
import type { PageRootService } from '@blocksuite/blocks';
@@ -71,6 +72,7 @@ const DetailPageImpl = memo(function DetailPageImpl() {
docService,
workspaceService,
globalContextService,
+ editorSettingService,
} = useServices({
WorkbenchService,
ViewService,
@@ -78,6 +80,7 @@ const DetailPageImpl = memo(function DetailPageImpl() {
DocService,
WorkspaceService,
GlobalContextService,
+ EditorSettingService,
});
const workbench = workbenchService.workbench;
const editor = editorService.editor;
@@ -307,9 +310,15 @@ const DetailPageImpl = memo(function DetailPageImpl() {
- } unmountOnInactive={false}>
-
-
+ {editorSettingService.editorSetting.settings$.value.enableAI && (
+ }
+ unmountOnInactive={false}
+ >
+
+
+ )}
}>
diff --git a/packages/frontend/core/src/providers/modal-provider.tsx b/packages/frontend/core/src/providers/modal-provider.tsx
index 3c9bb28f6e..65636cbe8d 100644
--- a/packages/frontend/core/src/providers/modal-provider.tsx
+++ b/packages/frontend/core/src/providers/modal-provider.tsx
@@ -1,4 +1,4 @@
-import { NotificationCenter, notify } from '@affine/component';
+import { ConfirmModal, NotificationCenter, notify } from '@affine/component';
import { events } from '@affine/electron-api';
import { WorkspaceFlavour } from '@affine/env/workspace';
import {
@@ -10,7 +10,7 @@ import {
} from '@toeverything/infra';
import { useAtom } from 'jotai';
import type { ReactElement } from 'react';
-import { useCallback, useEffect } from 'react';
+import { useCallback, useEffect, useState } from 'react';
import type { SettingAtom } from '../atoms';
import { openSettingModalAtom, openSignOutModalAtom } from '../atoms';
@@ -31,6 +31,7 @@ import { useAsyncCallback } from '../hooks/affine-async-hooks';
import { useNavigateHelper } from '../hooks/use-navigate-helper';
import { AuthService } from '../modules/cloud/services/auth';
import { CreateWorkspaceDialogProvider } from '../modules/create-workspace';
+import { EditorSettingService } from '../modules/editor-settting';
import { FindInPageModal } from '../modules/find-in-page/view/find-in-page-modal';
import { ImportTemplateDialogProvider } from '../modules/import-template';
import { PeekViewManagerModal } from '../modules/peek-view';
@@ -183,6 +184,40 @@ export const SignOutConfirmModal = () => {
);
};
+export const AIReloadConfirmModal = () => {
+ const editorSettingService = useService(EditorSettingService);
+ const enableAI = useLiveData(
+ editorSettingService.editorSetting.settings$
+ ).enableAI;
+ const [aiState] = useState(enableAI);
+ const [open, setOpen] = useState(false);
+
+ useEffect(() => {
+ setOpen(enableAI !== aiState);
+ }, [aiState, enableAI]);
+
+ const onConfirm = useCallback(() => {
+ window.location.reload();
+ }, []);
+
+ return (
+
+ );
+};
+
export const AllWorkspaceModals = (): ReactElement => {
return (
<>
@@ -191,6 +226,7 @@ export const AllWorkspaceModals = (): ReactElement => {
+
>
);
};
diff --git a/packages/frontend/i18n/src/resources/en.json b/packages/frontend/i18n/src/resources/en.json
index d19dc32cf4..747ed87e20 100644
--- a/packages/frontend/i18n/src/resources/en.json
+++ b/packages/frontend/i18n/src/resources/en.json
@@ -1225,7 +1225,7 @@
"com.affine.settings.auto-check-description": "If enabled, it will automatically check for new versions at regular intervals.",
"com.affine.settings.auto-download-description": "If enabled, new versions will be automatically downloaded to the current device.",
"com.affine.settings.editorSettings": "Editor",
- "com.affine.settings.editorSettings.title": "Editor Settings",
+ "com.affine.settings.editorSettings.title": "Editor settings",
"com.affine.settings.editorSettings.subtitle": "Configure your own editor.",
"com.affine.settings.editorSettings.general": "General",
"com.affine.settings.editorSettings.general.ai.title": "AFFiNE AI",