mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 04:18:54 +00:00
feat(core): move enable ai to feature flag (#8195)
This commit is contained in:
@@ -5,6 +5,14 @@ const isDesktopEnvironment = environment.isElectron;
|
|||||||
const isCanaryBuild = runtimeConfig.appBuildType === 'canary';
|
const isCanaryBuild = runtimeConfig.appBuildType === 'canary';
|
||||||
|
|
||||||
export const AFFINE_FLAGS = {
|
export const AFFINE_FLAGS = {
|
||||||
|
enable_ai: {
|
||||||
|
category: 'affine',
|
||||||
|
displayName: 'Enable AI',
|
||||||
|
description: 'Enable or disable ALL AI features.',
|
||||||
|
hide: true,
|
||||||
|
configurable: true,
|
||||||
|
defaultState: true,
|
||||||
|
},
|
||||||
enable_database_attachment_note: {
|
enable_database_attachment_note: {
|
||||||
category: 'blocksuite',
|
category: 'blocksuite',
|
||||||
bsFlag: 'enable_database_attachment_note',
|
bsFlag: 'enable_database_attachment_note',
|
||||||
|
|||||||
@@ -29,12 +29,17 @@ export class Flags extends Entity {
|
|||||||
const configurable = flag.configurable ?? true;
|
const configurable = flag.configurable ?? true;
|
||||||
const defaultState =
|
const defaultState =
|
||||||
'defaultState' in flag ? flag.defaultState : undefined;
|
'defaultState' in flag ? flag.defaultState : undefined;
|
||||||
|
const getValue = () => {
|
||||||
|
return configurable
|
||||||
|
? (this.globalState.get<boolean>(FLAG_PREFIX + flagKey) ??
|
||||||
|
defaultState)
|
||||||
|
: defaultState;
|
||||||
|
};
|
||||||
const item = {
|
const item = {
|
||||||
...flag,
|
...flag,
|
||||||
value: configurable
|
get value() {
|
||||||
? (this.globalState.get<boolean>(FLAG_PREFIX + flagKey) ??
|
return getValue();
|
||||||
defaultState)
|
},
|
||||||
: defaultState,
|
|
||||||
set: (value: boolean) => {
|
set: (value: boolean) => {
|
||||||
if (!configurable) {
|
if (!configurable) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
|
import { distinctUntilChanged, skip } from 'rxjs';
|
||||||
|
|
||||||
import { OnEvent, Service } from '../../../framework';
|
import { OnEvent, Service } from '../../../framework';
|
||||||
|
import { ApplicationStarted } from '../../lifecycle';
|
||||||
import type { Workspace } from '../../workspace';
|
import type { Workspace } from '../../workspace';
|
||||||
import { WorkspaceInitialized } from '../../workspace/events';
|
import { WorkspaceInitialized } from '../../workspace/events';
|
||||||
import { AFFINE_FLAGS } from '../constant';
|
import { AFFINE_FLAGS } from '../constant';
|
||||||
import { Flags, type FlagsExt } from '../entities/flags';
|
import { Flags, type FlagsExt } from '../entities/flags';
|
||||||
|
|
||||||
@OnEvent(WorkspaceInitialized, e => e.setupBlocksuiteEditorFlags)
|
@OnEvent(WorkspaceInitialized, e => e.setupBlocksuiteEditorFlags)
|
||||||
|
@OnEvent(ApplicationStarted, e => e.setupRestartListener)
|
||||||
export class FeatureFlagService extends Service {
|
export class FeatureFlagService extends Service {
|
||||||
flags = this.framework.createEntity(Flags) as FlagsExt;
|
flags = this.framework.createEntity(Flags) as FlagsExt;
|
||||||
|
|
||||||
@@ -18,4 +22,13 @@ export class FeatureFlagService extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setupRestartListener() {
|
||||||
|
this.flags.enable_ai.$.pipe(distinctUntilChanged(), skip(1)).subscribe(
|
||||||
|
() => {
|
||||||
|
// when enable_ai flag changes, reload the page.
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,10 @@ export type FlagInfo = {
|
|||||||
description?: string;
|
description?: string;
|
||||||
configurable?: boolean;
|
configurable?: boolean;
|
||||||
defaultState?: boolean; // default to open and not controlled by user
|
defaultState?: boolean; // default to open and not controlled by user
|
||||||
|
/**
|
||||||
|
* hide in the feature flag settings, but still can be controlled by the code
|
||||||
|
*/
|
||||||
|
hide?: boolean;
|
||||||
feedbackType?: FeedbackType;
|
feedbackType?: FeedbackType;
|
||||||
feedbackLink?: string;
|
feedbackLink?: string;
|
||||||
} & (
|
} & (
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { EditorSettingService } from '@affine/core/modules/editor-settting';
|
import { FeatureFlagService, useService } from '@toeverything/infra';
|
||||||
import { useLiveData, useService } from '@toeverything/infra';
|
|
||||||
import { Suspense, useCallback, useEffect, useState } from 'react';
|
import { Suspense, useCallback, useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { AIOnboardingEdgeless } from './edgeless.dialog';
|
import { AIOnboardingEdgeless } from './edgeless.dialog';
|
||||||
@@ -30,10 +29,8 @@ const useDismiss = (key: AIOnboardingType) => {
|
|||||||
export const WorkspaceAIOnboarding = () => {
|
export const WorkspaceAIOnboarding = () => {
|
||||||
const [dismissGeneral] = useDismiss(AIOnboardingType.GENERAL);
|
const [dismissGeneral] = useDismiss(AIOnboardingType.GENERAL);
|
||||||
const [dismissLocal] = useDismiss(AIOnboardingType.LOCAL);
|
const [dismissLocal] = useDismiss(AIOnboardingType.LOCAL);
|
||||||
const editorSettingService = useService(EditorSettingService);
|
const featureFlagService = useService(FeatureFlagService);
|
||||||
const enableAI = useLiveData(
|
const enableAI = featureFlagService.flags.enable_ai.value;
|
||||||
editorSettingService.editorSetting.settings$.map(s => s.enableAI)
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Suspense>
|
<Suspense>
|
||||||
@@ -45,10 +42,8 @@ export const WorkspaceAIOnboarding = () => {
|
|||||||
|
|
||||||
export const PageAIOnboarding = () => {
|
export const PageAIOnboarding = () => {
|
||||||
const [dismissEdgeless] = useDismiss(AIOnboardingType.EDGELESS);
|
const [dismissEdgeless] = useDismiss(AIOnboardingType.EDGELESS);
|
||||||
const editorSettingService = useService(EditorSettingService);
|
const featureFlagService = useService(FeatureFlagService);
|
||||||
const enableAI = useLiveData(
|
const enableAI = featureFlagService.flags.enable_ai.value;
|
||||||
editorSettingService.editorSetting.settings$.map(s => s.enableAI)
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Suspense>
|
<Suspense>
|
||||||
|
|||||||
@@ -26,7 +26,11 @@ import {
|
|||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
import type { DocMode } from '@blocksuite/blocks';
|
import type { DocMode } from '@blocksuite/blocks';
|
||||||
import { DoneIcon, SearchIcon } from '@blocksuite/icons/rc';
|
import { DoneIcon, SearchIcon } from '@blocksuite/icons/rc';
|
||||||
import { useLiveData, useServices } from '@toeverything/infra';
|
import {
|
||||||
|
FeatureFlagService,
|
||||||
|
useLiveData,
|
||||||
|
useServices,
|
||||||
|
} from '@toeverything/infra';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import {
|
import {
|
||||||
type ChangeEvent,
|
type ChangeEvent,
|
||||||
@@ -398,15 +402,15 @@ export const SpellCheckSettings = () => {
|
|||||||
const AISettings = () => {
|
const AISettings = () => {
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
const { openConfirmModal } = useConfirmModal();
|
const { openConfirmModal } = useConfirmModal();
|
||||||
const { editorSettingService } = useServices({ EditorSettingService });
|
const { featureFlagService } = useServices({ FeatureFlagService });
|
||||||
|
|
||||||
const settings = useLiveData(editorSettingService.editorSetting.settings$);
|
const enableAI = useLiveData(featureFlagService.flags.enable_ai.$);
|
||||||
|
|
||||||
const onAIChange = useCallback(
|
const onAIChange = useCallback(
|
||||||
(checked: boolean) => {
|
(checked: boolean) => {
|
||||||
editorSettingService.editorSetting.set('enableAI', checked);
|
featureFlagService.flags.enable_ai.set(checked); // this will trigger page reload, see `FeatureFlagService`
|
||||||
},
|
},
|
||||||
[editorSettingService]
|
[featureFlagService]
|
||||||
);
|
);
|
||||||
const onToggleAI = useCallback(
|
const onToggleAI = useCallback(
|
||||||
(checked: boolean) => {
|
(checked: boolean) => {
|
||||||
@@ -421,7 +425,11 @@ const AISettings = () => {
|
|||||||
: t[
|
: t[
|
||||||
'com.affine.settings.editorSettings.general.ai.disable.description'
|
'com.affine.settings.editorSettings.general.ai.disable.description'
|
||||||
](),
|
](),
|
||||||
confirmText: checked ? t['Enable']() : t['Disable'](),
|
confirmText: checked
|
||||||
|
? t['com.affine.settings.editorSettings.general.ai.enable.confirm']()
|
||||||
|
: t[
|
||||||
|
'com.affine.settings.editorSettings.general.ai.disable.confirm'
|
||||||
|
](),
|
||||||
cancelText: t['Cancel'](),
|
cancelText: t['Cancel'](),
|
||||||
onConfirm: () => onAIChange(checked),
|
onConfirm: () => onAIChange(checked),
|
||||||
confirmButtonOptions: {
|
confirmButtonOptions: {
|
||||||
@@ -437,7 +445,7 @@ const AISettings = () => {
|
|||||||
name={t['com.affine.settings.editorSettings.general.ai.title']()}
|
name={t['com.affine.settings.editorSettings.general.ai.title']()}
|
||||||
desc={t['com.affine.settings.editorSettings.general.ai.description']()}
|
desc={t['com.affine.settings.editorSettings.general.ai.description']()}
|
||||||
>
|
>
|
||||||
<Switch checked={settings.enableAI} onChange={onToggleAI} />
|
<Switch checked={enableAI} onChange={onToggleAI} />
|
||||||
</SettingRow>
|
</SettingRow>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ const ExperimentalFeaturesItem = ({ flag }: { flag: Flag }) => {
|
|||||||
: feedbackLink[flag.feedbackType]
|
: feedbackLink[flag.feedbackType]
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
if (flag.configurable === false) {
|
if (flag.configurable === false || flag.hide) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import type { Doc } from '@blocksuite/store';
|
|||||||
import {
|
import {
|
||||||
DocService,
|
DocService,
|
||||||
DocsService,
|
DocsService,
|
||||||
|
FeatureFlagService,
|
||||||
useFramework,
|
useFramework,
|
||||||
useLiveData,
|
useLiveData,
|
||||||
useService,
|
useService,
|
||||||
@@ -71,14 +72,14 @@ const usePatchSpecs = (page: Doc, shared: boolean, mode: DocMode) => {
|
|||||||
peekViewService,
|
peekViewService,
|
||||||
docService,
|
docService,
|
||||||
docsService,
|
docsService,
|
||||||
editorSettingService,
|
|
||||||
editorService,
|
editorService,
|
||||||
|
featureFlagService,
|
||||||
} = useServices({
|
} = useServices({
|
||||||
PeekViewService,
|
PeekViewService,
|
||||||
DocService,
|
DocService,
|
||||||
DocsService,
|
DocsService,
|
||||||
EditorSettingService,
|
|
||||||
EditorService,
|
EditorService,
|
||||||
|
FeatureFlagService,
|
||||||
});
|
});
|
||||||
const framework = useFramework();
|
const framework = useFramework();
|
||||||
const referenceRenderer: ReferenceReactRenderer = useMemo(() => {
|
const referenceRenderer: ReferenceReactRenderer = useMemo(() => {
|
||||||
@@ -101,12 +102,11 @@ const usePatchSpecs = (page: Doc, shared: boolean, mode: DocMode) => {
|
|||||||
}, [mode, page.collection]);
|
}, [mode, page.collection]);
|
||||||
|
|
||||||
const specs = useMemo(() => {
|
const specs = useMemo(() => {
|
||||||
const enableAI =
|
const enableAI = featureFlagService.flags.enable_ai.value;
|
||||||
editorSettingService.editorSetting.settings$.value.enableAI;
|
|
||||||
return mode === 'edgeless'
|
return mode === 'edgeless'
|
||||||
? createEdgelessModeSpecs(framework, enableAI)
|
? createEdgelessModeSpecs(framework, enableAI)
|
||||||
: createPageModeSpecs(framework, enableAI);
|
: createPageModeSpecs(framework, enableAI);
|
||||||
}, [editorSettingService, mode, framework]);
|
}, [featureFlagService, mode, framework]);
|
||||||
|
|
||||||
const confirmModal = useConfirmModal();
|
const confirmModal = useConfirmModal();
|
||||||
const patchedSpecs = useMemo(() => {
|
const patchedSpecs = useMemo(() => {
|
||||||
|
|||||||
@@ -11,6 +11,13 @@ import { map } from 'rxjs';
|
|||||||
import type { EditorSettingProvider } from '../provider/editor-setting-provider';
|
import type { EditorSettingProvider } from '../provider/editor-setting-provider';
|
||||||
import { EditorSettingSchema } from '../schema';
|
import { EditorSettingSchema } from '../schema';
|
||||||
|
|
||||||
|
type SettingItem<T> = {
|
||||||
|
readonly value: T;
|
||||||
|
set: (value: T) => void;
|
||||||
|
// eslint-disable-next-line rxjs/finnish
|
||||||
|
$: T;
|
||||||
|
};
|
||||||
|
|
||||||
export class EditorSetting extends Entity {
|
export class EditorSetting extends Entity {
|
||||||
constructor(public readonly provider: EditorSettingProvider) {
|
constructor(public readonly provider: EditorSettingProvider) {
|
||||||
super();
|
super();
|
||||||
@@ -20,6 +27,27 @@ export class EditorSetting extends Entity {
|
|||||||
>(this.settings$, {});
|
>(this.settings$, {});
|
||||||
this.settingSignal = signal;
|
this.settingSignal = signal;
|
||||||
this.disposables.push(cleanup);
|
this.disposables.push(cleanup);
|
||||||
|
|
||||||
|
Object.entries(EditorSettingSchema.shape).forEach(([flagKey, flag]) => {
|
||||||
|
const livedata$ = this.settings$.selector(
|
||||||
|
s => s[flagKey as keyof EditorSettingSchema]
|
||||||
|
);
|
||||||
|
const item = {
|
||||||
|
...flag,
|
||||||
|
get value() {
|
||||||
|
return livedata$.value;
|
||||||
|
},
|
||||||
|
set: (value: any) => {
|
||||||
|
this.set(flagKey as keyof EditorSettingSchema, value);
|
||||||
|
},
|
||||||
|
$: livedata$,
|
||||||
|
} as SettingItem<unknown>;
|
||||||
|
Object.defineProperty(this, flagKey, {
|
||||||
|
get: () => {
|
||||||
|
return item;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
settings$ = LiveData.from<EditorSettingSchema>(this.watchAll(), null as any);
|
settings$ = LiveData.from<EditorSettingSchema>(this.watchAll(), null as any);
|
||||||
@@ -61,3 +89,7 @@ export class EditorSetting extends Entity {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type EditorSettingExt = EditorSetting & {
|
||||||
|
[K in keyof EditorSettingSchema]: SettingItem<EditorSettingSchema[K]>;
|
||||||
|
};
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ export const fontStyleOptions = [
|
|||||||
}[];
|
}[];
|
||||||
|
|
||||||
const AffineEditorSettingSchema = z.object({
|
const AffineEditorSettingSchema = z.object({
|
||||||
enableAI: z.boolean().default(true),
|
|
||||||
fontFamily: z.enum(['Sans', 'Serif', 'Mono', 'Custom']).default('Sans'),
|
fontFamily: z.enum(['Sans', 'Serif', 'Mono', 'Custom']).default('Sans'),
|
||||||
customFontFamily: z.string().default(''),
|
customFontFamily: z.string().default(''),
|
||||||
newDocDefaultMode: z.enum(['edgeless', 'page']).default('page'),
|
newDocDefaultMode: z.enum(['edgeless', 'page']).default('page'),
|
||||||
|
|||||||
@@ -6,11 +6,16 @@ import {
|
|||||||
WorkspaceInitialized,
|
WorkspaceInitialized,
|
||||||
} from '@toeverything/infra';
|
} from '@toeverything/infra';
|
||||||
|
|
||||||
import { EditorSetting } from '../entities/editor-setting';
|
import {
|
||||||
|
EditorSetting,
|
||||||
|
type EditorSettingExt,
|
||||||
|
} from '../entities/editor-setting';
|
||||||
|
|
||||||
@OnEvent(WorkspaceInitialized, e => e.onWorkspaceInitialized)
|
@OnEvent(WorkspaceInitialized, e => e.onWorkspaceInitialized)
|
||||||
export class EditorSettingService extends Service {
|
export class EditorSettingService extends Service {
|
||||||
editorSetting = this.framework.createEntity(EditorSetting);
|
editorSetting = this.framework.createEntity(
|
||||||
|
EditorSetting
|
||||||
|
) as EditorSettingExt;
|
||||||
|
|
||||||
onWorkspaceInitialized(workspace: Workspace) {
|
onWorkspaceInitialized(workspace: Workspace) {
|
||||||
// set default mode for new doc
|
// set default mode for new doc
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import { EditorOutlineViewer } from '@affine/core/components/blocksuite/outline-
|
|||||||
import { useAppSettingHelper } from '@affine/core/hooks/affine/use-app-setting-helper';
|
import { useAppSettingHelper } from '@affine/core/hooks/affine/use-app-setting-helper';
|
||||||
import { useDocMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta';
|
import { useDocMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta';
|
||||||
import { EditorService } from '@affine/core/modules/editor';
|
import { EditorService } from '@affine/core/modules/editor';
|
||||||
import { EditorSettingService } from '@affine/core/modules/editor-settting';
|
|
||||||
import { RecentDocsService } from '@affine/core/modules/quicksearch';
|
import { RecentDocsService } from '@affine/core/modules/quicksearch';
|
||||||
import { ViewService } from '@affine/core/modules/workbench/services/view';
|
import { ViewService } from '@affine/core/modules/workbench/services/view';
|
||||||
import type { PageRootService } from '@blocksuite/blocks';
|
import type { PageRootService } from '@blocksuite/blocks';
|
||||||
@@ -16,6 +15,7 @@ import { AiIcon, FrameIcon, TocIcon, TodayIcon } from '@blocksuite/icons/rc';
|
|||||||
import { type AffineEditorContainer } from '@blocksuite/presets';
|
import { type AffineEditorContainer } from '@blocksuite/presets';
|
||||||
import {
|
import {
|
||||||
DocService,
|
DocService,
|
||||||
|
FeatureFlagService,
|
||||||
FrameworkScope,
|
FrameworkScope,
|
||||||
GlobalContextService,
|
GlobalContextService,
|
||||||
useLiveData,
|
useLiveData,
|
||||||
@@ -61,7 +61,7 @@ const DetailPageImpl = memo(function DetailPageImpl() {
|
|||||||
docService,
|
docService,
|
||||||
workspaceService,
|
workspaceService,
|
||||||
globalContextService,
|
globalContextService,
|
||||||
editorSettingService,
|
featureFlagService,
|
||||||
} = useServices({
|
} = useServices({
|
||||||
WorkbenchService,
|
WorkbenchService,
|
||||||
ViewService,
|
ViewService,
|
||||||
@@ -69,7 +69,7 @@ const DetailPageImpl = memo(function DetailPageImpl() {
|
|||||||
DocService,
|
DocService,
|
||||||
WorkspaceService,
|
WorkspaceService,
|
||||||
GlobalContextService,
|
GlobalContextService,
|
||||||
EditorSettingService,
|
FeatureFlagService,
|
||||||
});
|
});
|
||||||
const workbench = workbenchService.workbench;
|
const workbench = workbenchService.workbench;
|
||||||
const editor = editorService.editor;
|
const editor = editorService.editor;
|
||||||
@@ -250,7 +250,7 @@ const DetailPageImpl = memo(function DetailPageImpl() {
|
|||||||
</div>
|
</div>
|
||||||
</ViewBody>
|
</ViewBody>
|
||||||
|
|
||||||
{editorSettingService.editorSetting.settings$.value.enableAI && (
|
{featureFlagService.flags.enable_ai.value && (
|
||||||
<ViewSidebarTab
|
<ViewSidebarTab
|
||||||
tabId="chat"
|
tabId="chat"
|
||||||
icon={<AiIcon />}
|
icon={<AiIcon />}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { ConfirmModal, NotificationCenter, notify } from '@affine/component';
|
import { NotificationCenter, notify } from '@affine/component';
|
||||||
import { events } from '@affine/electron-api';
|
import { events } from '@affine/electron-api';
|
||||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
import { WorkspaceFlavour } from '@affine/env/workspace';
|
||||||
import { useI18n } from '@affine/i18n';
|
|
||||||
import {
|
import {
|
||||||
GlobalContextService,
|
GlobalContextService,
|
||||||
useLiveData,
|
useLiveData,
|
||||||
@@ -11,7 +10,7 @@ import {
|
|||||||
} from '@toeverything/infra';
|
} from '@toeverything/infra';
|
||||||
import { useAtom } from 'jotai';
|
import { useAtom } from 'jotai';
|
||||||
import type { ReactElement } from 'react';
|
import type { ReactElement } from 'react';
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect } from 'react';
|
||||||
|
|
||||||
import type { SettingAtom } from '../atoms';
|
import type { SettingAtom } from '../atoms';
|
||||||
import { openSettingModalAtom, openSignOutModalAtom } from '../atoms';
|
import { openSettingModalAtom, openSignOutModalAtom } from '../atoms';
|
||||||
@@ -32,7 +31,6 @@ import { useAsyncCallback } from '../hooks/affine-async-hooks';
|
|||||||
import { useNavigateHelper } from '../hooks/use-navigate-helper';
|
import { useNavigateHelper } from '../hooks/use-navigate-helper';
|
||||||
import { AuthService } from '../modules/cloud/services/auth';
|
import { AuthService } from '../modules/cloud/services/auth';
|
||||||
import { CreateWorkspaceDialogProvider } from '../modules/create-workspace';
|
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 { FindInPageModal } from '../modules/find-in-page/view/find-in-page-modal';
|
||||||
import { ImportTemplateDialogProvider } from '../modules/import-template';
|
import { ImportTemplateDialogProvider } from '../modules/import-template';
|
||||||
import { PeekViewManagerModal } from '../modules/peek-view';
|
import { PeekViewManagerModal } from '../modules/peek-view';
|
||||||
@@ -185,43 +183,6 @@ export const SignOutConfirmModal = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AIReloadConfirmModal = () => {
|
|
||||||
const t = useI18n();
|
|
||||||
const editorSettingService = useService(EditorSettingService);
|
|
||||||
const enableAI = useLiveData(
|
|
||||||
editorSettingService.editorSetting.settings$.selector(s => s.enableAI)
|
|
||||||
);
|
|
||||||
const [aiState] = useState(enableAI);
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setOpen(enableAI !== aiState);
|
|
||||||
}, [aiState, enableAI]);
|
|
||||||
|
|
||||||
const onConfirm = useCallback(() => {
|
|
||||||
window.location.reload();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ConfirmModal
|
|
||||||
open={open}
|
|
||||||
onOpenChange={setOpen}
|
|
||||||
onConfirm={onConfirm}
|
|
||||||
confirmButtonOptions={{
|
|
||||||
variant: 'primary',
|
|
||||||
}}
|
|
||||||
title={t['com.affine.settings.editorSettings.general.ai.reload.title']()}
|
|
||||||
description={t[
|
|
||||||
'com.affine.settings.editorSettings.general.ai.reload.description'
|
|
||||||
]()}
|
|
||||||
cancelText={t['Cancel']()}
|
|
||||||
confirmText={t[
|
|
||||||
'com.affine.settings.editorSettings.general.ai.reload.confirm'
|
|
||||||
]()}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const AllWorkspaceModals = (): ReactElement => {
|
export const AllWorkspaceModals = (): ReactElement => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -230,7 +191,6 @@ export const AllWorkspaceModals = (): ReactElement => {
|
|||||||
<CreateWorkspaceDialogProvider />
|
<CreateWorkspaceDialogProvider />
|
||||||
<AuthModal />
|
<AuthModal />
|
||||||
<SignOutConfirmModal />
|
<SignOutConfirmModal />
|
||||||
<AIReloadConfirmModal />
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1312,8 +1312,10 @@
|
|||||||
"com.affine.settings.editorSettings.general.ai.description": "Enable the powerful AI assistant, AFFiNE AI.",
|
"com.affine.settings.editorSettings.general.ai.description": "Enable the powerful AI assistant, AFFiNE AI.",
|
||||||
"com.affine.settings.editorSettings.general.ai.disable.description": "Are you sure you want to disable AI? We value your productivity and our AI can enhance it. Please think again!",
|
"com.affine.settings.editorSettings.general.ai.disable.description": "Are you sure you want to disable AI? We value your productivity and our AI can enhance it. Please think again!",
|
||||||
"com.affine.settings.editorSettings.general.ai.disable.title": "Disable AI?",
|
"com.affine.settings.editorSettings.general.ai.disable.title": "Disable AI?",
|
||||||
"com.affine.settings.editorSettings.general.ai.enable.description": "Do you want to enable AI? Our AI assistant is ready to enhance your productivity and provide smart assistance. Let's get started!",
|
"com.affine.settings.editorSettings.general.ai.disable.confirm": "Disable AI and Reload",
|
||||||
|
"com.affine.settings.editorSettings.general.ai.enable.description": "Do you want to enable AI? Our AI assistant is ready to enhance your productivity and provide smart assistance. Let's get started! We need reload page to make this change.",
|
||||||
"com.affine.settings.editorSettings.general.ai.enable.title": "Enable AI?",
|
"com.affine.settings.editorSettings.general.ai.enable.title": "Enable AI?",
|
||||||
|
"com.affine.settings.editorSettings.general.ai.enable.confirm": "Enable AI and Reload",
|
||||||
"com.affine.settings.editorSettings.general.ai.reload.confirm": "Reload",
|
"com.affine.settings.editorSettings.general.ai.reload.confirm": "Reload",
|
||||||
"com.affine.settings.editorSettings.general.ai.reload.description": "AI settings have been updated. Please reload the page to apply the changes.",
|
"com.affine.settings.editorSettings.general.ai.reload.description": "AI settings have been updated. Please reload the page to apply the changes.",
|
||||||
"com.affine.settings.editorSettings.general.ai.reload.title": "You need to reload the page",
|
"com.affine.settings.editorSettings.general.ai.reload.title": "You need to reload the page",
|
||||||
|
|||||||
@@ -1313,7 +1313,7 @@
|
|||||||
"com.affine.settings.editorSettings.general.ai.description": "启用卓越的 AI 助手,AFFiNE AI。",
|
"com.affine.settings.editorSettings.general.ai.description": "启用卓越的 AI 助手,AFFiNE AI。",
|
||||||
"com.affine.settings.editorSettings.general.ai.disable.description": "您确定要禁用 AI 吗?我们重视您的工作效率,而我们的 AI 可以提高它。请再考虑一下!",
|
"com.affine.settings.editorSettings.general.ai.disable.description": "您确定要禁用 AI 吗?我们重视您的工作效率,而我们的 AI 可以提高它。请再考虑一下!",
|
||||||
"com.affine.settings.editorSettings.general.ai.disable.title": "禁用 AI ?",
|
"com.affine.settings.editorSettings.general.ai.disable.title": "禁用 AI ?",
|
||||||
"com.affine.settings.editorSettings.general.ai.enable.description": "您想启用 AI 吗?我们的 AI 助手已准备好提高您的工作效率并提供智能帮助。让我们开始吧!",
|
"com.affine.settings.editorSettings.general.ai.enable.description": "您想启用 AI 吗?我们的 AI 助手已准备好提高您的工作效率并提供智能帮助。让我们开始吧!我们需要重新加载页面以进行此更改。",
|
||||||
"com.affine.settings.editorSettings.general.ai.enable.title": "启用 AI ?",
|
"com.affine.settings.editorSettings.general.ai.enable.title": "启用 AI ?",
|
||||||
"com.affine.settings.editorSettings.general.ai.reload.confirm": "重新加载",
|
"com.affine.settings.editorSettings.general.ai.reload.confirm": "重新加载",
|
||||||
"com.affine.settings.editorSettings.general.ai.reload.description": "AI 设置已更新。请重新加载页面以应用更改。",
|
"com.affine.settings.editorSettings.general.ai.reload.description": "AI 设置已更新。请重新加载页面以应用更改。",
|
||||||
|
|||||||
Reference in New Issue
Block a user