feat(core): move blocksuite flags to experimental features (#6113)

This commit is contained in:
Peng Xiao 2024-03-14 05:24:47 +00:00
parent dd9a253772
commit d2bad68b74
No known key found for this signature in database
GPG Key ID: 23F23D9E8B3971ED
6 changed files with 84 additions and 33 deletions

View File

@ -1,17 +1,10 @@
/// <reference types="@blocksuite/global" /> /// <reference types="@blocksuite/global" />
import { assertEquals } from '@blocksuite/global/utils'; import { assertEquals } from '@blocksuite/global/utils';
import type { DocCollection } from '@blocksuite/store';
import { z } from 'zod'; import { z } from 'zod';
import { isDesktop, isServer } from './constant.js'; import { isDesktop, isServer } from './constant.js';
import { UaHelper } from './ua-helper.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({ export const runtimeFlagsSchema = z.object({
enableTestProperties: z.boolean(), enableTestProperties: z.boolean(),
enableBroadcastChannelProvider: z.boolean(), enableBroadcastChannelProvider: z.boolean(),
@ -36,7 +29,6 @@ export const runtimeFlagsSchema = z.object({
// this is for the electron app // this is for the electron app
serverUrlPrefix: z.string(), serverUrlPrefix: z.string(),
enableMoveDatabase: z.boolean(), enableMoveDatabase: z.boolean(),
editorFlags: blockSuiteFeatureFlags,
appVersion: z.string(), appVersion: z.string(),
editorVersion: z.string(), editorVersion: z.string(),
appBuildType: z.union([ appBuildType: z.union([
@ -48,8 +40,6 @@ export const runtimeFlagsSchema = z.object({
isSelfHosted: z.boolean().optional(), isSelfHosted: z.boolean().optional(),
}); });
export type BlockSuiteFeatureFlags = z.infer<typeof blockSuiteFeatureFlags>;
export type RuntimeConfig = z.infer<typeof runtimeFlagsSchema>; export type RuntimeConfig = z.infer<typeof runtimeFlagsSchema>;
type BrowserBase = { type BrowserBase = {
@ -153,12 +143,3 @@ export function setupGlobal() {
globalThis.$AFFINE_SETUP = true; globalThis.$AFFINE_SETUP = true;
} }
export function setupEditorFlags(docCollection: DocCollection) {
Object.entries(runtimeConfig.editorFlags).forEach(([key, value]) => {
docCollection.awarenessStore.setFlag(
key as keyof BlockSuiteFeatureFlags,
value
);
});
}

View File

@ -1,10 +1,16 @@
import { DebugLogger } from '@affine/debug';
import { setupGlobal } from '@affine/env/global'; import { setupGlobal } from '@affine/env/global';
import type { DocCollection } from '@blocksuite/store';
import { atom } from 'jotai'; import { atom } from 'jotai';
import { atomWithStorage } from 'jotai/utils'; import { atomWithStorage } from 'jotai/utils';
import { atomEffect } from 'jotai-effect'; import { atomEffect } from 'jotai-effect';
import { getCurrentStore } from './root-store';
setupGlobal(); setupGlobal();
const logger = new DebugLogger('affine:settings');
export type DateFormats = export type DateFormats =
| 'MM/dd/YYYY' | 'MM/dd/YYYY'
| 'dd/MM/YYYY' | 'dd/MM/YYYY'
@ -26,6 +32,7 @@ export type AppSetting = {
autoCheckUpdate: boolean; autoCheckUpdate: boolean;
autoDownloadUpdate: boolean; autoDownloadUpdate: boolean;
enableMultiView: boolean; enableMultiView: boolean;
editorFlags: Partial<Omit<BlockSuiteFlags, 'readonly'>>;
}; };
export const windowFrameStyleOptions: AppSetting['windowFrameStyle'][] = [ export const windowFrameStyleOptions: AppSetting['windowFrameStyle'][] = [
'frameless', 'frameless',
@ -65,15 +72,35 @@ const appSettingBaseAtom = atomWithStorage<AppSetting>('affine-settings', {
autoCheckUpdate: true, autoCheckUpdate: true,
autoDownloadUpdate: true, autoDownloadUpdate: true,
enableMultiView: false, 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> = Value | ((prev: Value) => Value); type SetStateAction<Value> = Value | ((prev: Value) => Value);
const appSettingEffect = atomEffect(get => { const appSettingEffect = atomEffect(get => {
const settings = get(appSettingBaseAtom); const settings = get(appSettingBaseAtom);
// some values in settings should be synced into electron side // some values in settings should be synced into electron side
if (environment.isDesktop) { 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 // this api type in @affine/electron-api, but it is circular dependency this package, use any here
(window as any).apis?.updater (window as any).apis?.updater
.setConfig({ .setConfig({

View File

@ -1,10 +1,10 @@
import { DebugLogger } from '@affine/debug'; import { DebugLogger } from '@affine/debug';
import { setupEditorFlags } from '@affine/env/global';
import { WorkspaceFlavour } from '@affine/env/workspace'; import { WorkspaceFlavour } from '@affine/env/workspace';
import { assertEquals } from '@blocksuite/global/utils'; import { assertEquals } from '@blocksuite/global/utils';
import type { DocCollection } from '@blocksuite/store'; import type { DocCollection } from '@blocksuite/store';
import { applyUpdate, encodeStateAsUpdate } from 'yjs'; import { applyUpdate, encodeStateAsUpdate } from 'yjs';
import { setupEditorFlags } from '../atom/settings';
import { fixWorkspaceVersion } from '../blocksuite'; import { fixWorkspaceVersion } from '../blocksuite';
import type { ServiceCollection, ServiceProvider } from '../di'; import type { ServiceCollection, ServiceProvider } from '../di';
import { ObjectPool } from '../utils/object-pool'; import { ObjectPool } from '../utils/object-pool';

View File

@ -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 type { BuildFlags } from '@affine/cli/config';
import { createRequire } from 'node:module'; import { createRequire } from 'node:module';
const require = createRequire(import.meta.url); const require = createRequire(import.meta.url);
const packageJson = require('../package.json'); 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 { export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig {
const buildPreset: Record<BuildFlags['channel'], RuntimeConfig> = { const buildPreset: Record<BuildFlags['channel'], RuntimeConfig> = {
stable: { stable: {
@ -35,7 +29,6 @@ export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig {
enablePageHistory: true, enablePageHistory: true,
allowLocalWorkspace: false, allowLocalWorkspace: false,
serverUrlPrefix: 'https://app.affine.pro', serverUrlPrefix: 'https://app.affine.pro',
editorFlags,
appVersion: packageJson.version, appVersion: packageJson.version,
editorVersion: packageJson.dependencies['@blocksuite/presets'], editorVersion: packageJson.dependencies['@blocksuite/presets'],
appBuildType: 'stable', appBuildType: 'stable',
@ -78,7 +71,6 @@ export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig {
enablePageHistory: true, enablePageHistory: true,
allowLocalWorkspace: false, allowLocalWorkspace: false,
serverUrlPrefix: 'https://affine.fail', serverUrlPrefix: 'https://affine.fail',
editorFlags,
appVersion: packageJson.version, appVersion: packageJson.version,
editorVersion: packageJson.dependencies['@blocksuite/presets'], editorVersion: packageJson.dependencies['@blocksuite/presets'],
appBuildType: 'canary', appBuildType: 'canary',

View File

@ -39,6 +39,13 @@ export const promptDisclaimer = style({
marginBottom: 32, marginBottom: 32,
gap: 4, gap: 4,
}); });
export const settingsContainer = style({
display: 'flex',
flexDirection: 'column',
gap: 24,
});
export const promptDisclaimerConfirm = style({ export const promptDisclaimerConfirm = style({
display: 'flex', display: 'flex',
justifyContent: 'center', justifyContent: 'center',
@ -47,9 +54,13 @@ export const switchRow = style({
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
justifyContent: 'space-between', justifyContent: 'space-between',
marginBottom: 32,
}); });
export const switchDisabled = style({ export const switchDisabled = style({
opacity: 0.5, opacity: 0.5,
pointerEvents: 'none', pointerEvents: 'none',
}); });
export const subHeader = style({
fontWeight: '600',
color: cssVar('textSecondaryColor'),
marginBottom: 8,
});

View File

@ -168,6 +168,43 @@ const SplitViewSettingRow = () => {
); );
}; };
// feature flag -> display name
const blocksuiteFeatureFlags: Partial<Record<keyof BlockSuiteFlags, string>> = {
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]) => (
<ExperimentalFeaturesItem
key={flag}
title={'Block Suite: ' + displayName}
checked={!!appSettings.editorFlags?.[flag as EditorFlag]}
onChange={checked =>
toggleSetting(flag as keyof BlockSuiteFlags, checked)
}
/>
))}
</>
);
};
const ExperimentalFeaturesMain = ({ const ExperimentalFeaturesMain = ({
workspaceMetadata, workspaceMetadata,
}: { }: {
@ -182,8 +219,11 @@ const ExperimentalFeaturesMain = ({
'com.affine.settings.workspace.experimental-features.header.plugins' 'com.affine.settings.workspace.experimental-features.header.plugins'
]()} ]()}
/> />
<CopilotSettingRow workspaceMetadata={workspaceMetadata} /> <div className={styles.settingsContainer}>
<SplitViewSettingRow /> <CopilotSettingRow workspaceMetadata={workspaceMetadata} />
<SplitViewSettingRow />
<BlocksuiteFeatureFlagSettings />
</div>
</> </>
); );
}; };