diff --git a/packages/common/env/src/global.ts b/packages/common/env/src/global.ts
index c3d8b88290..e40c78380a 100644
--- a/packages/common/env/src/global.ts
+++ b/packages/common/env/src/global.ts
@@ -1,17 +1,10 @@
///
import { assertEquals } from '@blocksuite/global/utils';
-import type { DocCollection } from '@blocksuite/store';
import { z } from 'zod';
import { isDesktop, isServer } from './constant.js';
import { UaHelper } from './ua-helper.js';
-export const blockSuiteFeatureFlags = z.object({
- enable_synced_doc_block: z.boolean(),
- enable_expand_database_block: z.boolean(),
- enable_bultin_ledits: z.boolean(),
-});
-
export const runtimeFlagsSchema = z.object({
enableTestProperties: z.boolean(),
enableBroadcastChannelProvider: z.boolean(),
@@ -36,7 +29,6 @@ export const runtimeFlagsSchema = z.object({
// this is for the electron app
serverUrlPrefix: z.string(),
enableMoveDatabase: z.boolean(),
- editorFlags: blockSuiteFeatureFlags,
appVersion: z.string(),
editorVersion: z.string(),
appBuildType: z.union([
@@ -48,8 +40,6 @@ export const runtimeFlagsSchema = z.object({
isSelfHosted: z.boolean().optional(),
});
-export type BlockSuiteFeatureFlags = z.infer;
-
export type RuntimeConfig = z.infer;
type BrowserBase = {
@@ -153,12 +143,3 @@ export function setupGlobal() {
globalThis.$AFFINE_SETUP = true;
}
-
-export function setupEditorFlags(docCollection: DocCollection) {
- Object.entries(runtimeConfig.editorFlags).forEach(([key, value]) => {
- docCollection.awarenessStore.setFlag(
- key as keyof BlockSuiteFeatureFlags,
- value
- );
- });
-}
diff --git a/packages/common/infra/src/atom/settings.ts b/packages/common/infra/src/atom/settings.ts
index d22cdf9186..f71f46e80f 100644
--- a/packages/common/infra/src/atom/settings.ts
+++ b/packages/common/infra/src/atom/settings.ts
@@ -1,10 +1,16 @@
+import { DebugLogger } from '@affine/debug';
import { setupGlobal } from '@affine/env/global';
+import type { DocCollection } from '@blocksuite/store';
import { atom } from 'jotai';
import { atomWithStorage } from 'jotai/utils';
import { atomEffect } from 'jotai-effect';
+import { getCurrentStore } from './root-store';
+
setupGlobal();
+const logger = new DebugLogger('affine:settings');
+
export type DateFormats =
| 'MM/dd/YYYY'
| 'dd/MM/YYYY'
@@ -26,6 +32,7 @@ export type AppSetting = {
autoCheckUpdate: boolean;
autoDownloadUpdate: boolean;
enableMultiView: boolean;
+ editorFlags: Partial>;
};
export const windowFrameStyleOptions: AppSetting['windowFrameStyle'][] = [
'frameless',
@@ -65,15 +72,35 @@ const appSettingBaseAtom = atomWithStorage('affine-settings', {
autoCheckUpdate: true,
autoDownloadUpdate: true,
enableMultiView: false,
+ editorFlags: {},
});
+export function setupEditorFlags(docCollection: DocCollection) {
+ const store = getCurrentStore();
+ const syncEditorFlags = () => {
+ try {
+ const editorFlags = getCurrentStore().get(appSettingBaseAtom).editorFlags;
+ Object.entries(editorFlags).forEach(([key, value]) => {
+ docCollection.awarenessStore.setFlag(
+ key as keyof BlockSuiteFlags,
+ value
+ );
+ });
+ } catch (err) {
+ logger.error('syncEditorFlags', err);
+ }
+ };
+ store.sub(appSettingBaseAtom, syncEditorFlags);
+ syncEditorFlags();
+}
+
type SetStateAction = Value | ((prev: Value) => Value);
const appSettingEffect = atomEffect(get => {
const settings = get(appSettingBaseAtom);
// some values in settings should be synced into electron side
if (environment.isDesktop) {
- console.log('set config', settings);
+ logger.debug('sync settings to electron', settings);
// this api type in @affine/electron-api, but it is circular dependency this package, use any here
(window as any).apis?.updater
.setConfig({
diff --git a/packages/common/infra/src/workspace/manager.ts b/packages/common/infra/src/workspace/manager.ts
index 49d2451cb1..13cc11409e 100644
--- a/packages/common/infra/src/workspace/manager.ts
+++ b/packages/common/infra/src/workspace/manager.ts
@@ -1,10 +1,10 @@
import { DebugLogger } from '@affine/debug';
-import { setupEditorFlags } from '@affine/env/global';
import { WorkspaceFlavour } from '@affine/env/workspace';
import { assertEquals } from '@blocksuite/global/utils';
import type { DocCollection } from '@blocksuite/store';
import { applyUpdate, encodeStateAsUpdate } from 'yjs';
+import { setupEditorFlags } from '../atom/settings';
import { fixWorkspaceVersion } from '../blocksuite';
import type { ServiceCollection, ServiceProvider } from '../di';
import { ObjectPool } from '../utils/object-pool';
diff --git a/packages/frontend/core/.webpack/runtime-config.ts b/packages/frontend/core/.webpack/runtime-config.ts
index a2f15f168d..201837f8be 100644
--- a/packages/frontend/core/.webpack/runtime-config.ts
+++ b/packages/frontend/core/.webpack/runtime-config.ts
@@ -1,16 +1,10 @@
-import type { BlockSuiteFeatureFlags, RuntimeConfig } from '@affine/env/global';
+import type { RuntimeConfig } from '@affine/env/global';
import type { BuildFlags } from '@affine/cli/config';
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);
const packageJson = require('../package.json');
-const editorFlags: BlockSuiteFeatureFlags = {
- enable_synced_doc_block: true,
- enable_expand_database_block: false,
- enable_bultin_ledits: false,
-};
-
export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig {
const buildPreset: Record = {
stable: {
@@ -35,7 +29,6 @@ export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig {
enablePageHistory: true,
allowLocalWorkspace: false,
serverUrlPrefix: 'https://app.affine.pro',
- editorFlags,
appVersion: packageJson.version,
editorVersion: packageJson.dependencies['@blocksuite/presets'],
appBuildType: 'stable',
@@ -78,7 +71,6 @@ export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig {
enablePageHistory: true,
allowLocalWorkspace: false,
serverUrlPrefix: 'https://affine.fail',
- editorFlags,
appVersion: packageJson.version,
editorVersion: packageJson.dependencies['@blocksuite/presets'],
appBuildType: 'canary',
diff --git a/packages/frontend/core/src/components/affine/setting-modal/workspace-setting/experimental-features/index.css.ts b/packages/frontend/core/src/components/affine/setting-modal/workspace-setting/experimental-features/index.css.ts
index 13291e0c87..c07da6ff9c 100644
--- a/packages/frontend/core/src/components/affine/setting-modal/workspace-setting/experimental-features/index.css.ts
+++ b/packages/frontend/core/src/components/affine/setting-modal/workspace-setting/experimental-features/index.css.ts
@@ -39,6 +39,13 @@ export const promptDisclaimer = style({
marginBottom: 32,
gap: 4,
});
+
+export const settingsContainer = style({
+ display: 'flex',
+ flexDirection: 'column',
+ gap: 24,
+});
+
export const promptDisclaimerConfirm = style({
display: 'flex',
justifyContent: 'center',
@@ -47,9 +54,13 @@ export const switchRow = style({
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
- marginBottom: 32,
});
export const switchDisabled = style({
opacity: 0.5,
pointerEvents: 'none',
});
+export const subHeader = style({
+ fontWeight: '600',
+ color: cssVar('textSecondaryColor'),
+ marginBottom: 8,
+});
diff --git a/packages/frontend/core/src/components/affine/setting-modal/workspace-setting/experimental-features/index.tsx b/packages/frontend/core/src/components/affine/setting-modal/workspace-setting/experimental-features/index.tsx
index bc11af3f26..531aa28e12 100644
--- a/packages/frontend/core/src/components/affine/setting-modal/workspace-setting/experimental-features/index.tsx
+++ b/packages/frontend/core/src/components/affine/setting-modal/workspace-setting/experimental-features/index.tsx
@@ -168,6 +168,43 @@ const SplitViewSettingRow = () => {
);
};
+// feature flag -> display name
+const blocksuiteFeatureFlags: Partial> = {
+ enable_synced_doc_block: 'Enable Synced Doc Block',
+ enable_expand_database_block: 'Enable Expand Database Block',
+ enable_bultin_ledits: 'Edit with LEDITS',
+};
+
+const BlocksuiteFeatureFlagSettings = () => {
+ const { appSettings, updateSettings } = useAppSettingHelper();
+ const toggleSetting = useCallback(
+ (flag: keyof BlockSuiteFlags, checked: boolean) => {
+ updateSettings('editorFlags', {
+ ...appSettings.editorFlags,
+ [flag]: checked,
+ });
+ },
+ [appSettings.editorFlags, updateSettings]
+ );
+
+ type EditorFlag = keyof typeof appSettings.editorFlags;
+
+ return (
+ <>
+ {Object.entries(blocksuiteFeatureFlags).map(([flag, displayName]) => (
+
+ toggleSetting(flag as keyof BlockSuiteFlags, checked)
+ }
+ />
+ ))}
+ >
+ );
+};
+
const ExperimentalFeaturesMain = ({
workspaceMetadata,
}: {
@@ -182,8 +219,11 @@ const ExperimentalFeaturesMain = ({
'com.affine.settings.workspace.experimental-features.header.plugins'
]()}
/>
-
-
+
+
+
+
+
>
);
};