feat(editor): add feature flag service (#9592)
This commit is contained in:
55 files changed
+283
-188
No files matched your search
@@ -1,4 +1,5 @@
|
|||||||
import type { DatabaseBlockModel } from '@blocksuite/affine-model';
|
import type { DatabaseBlockModel } from '@blocksuite/affine-model';
|
||||||
|
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||||
import {
|
import {
|
||||||
insertPositionToIndex,
|
insertPositionToIndex,
|
||||||
type InsertToPosition,
|
type InsertToPosition,
|
||||||
@@ -57,10 +58,12 @@ export class DatabaseBlockDataSource extends DataSourceBase {
|
|||||||
private readonly _model: DatabaseBlockModel;
|
private readonly _model: DatabaseBlockModel;
|
||||||
|
|
||||||
override featureFlags$: ReadonlySignal<DatabaseFlags> = computed(() => {
|
override featureFlags$: ReadonlySignal<DatabaseFlags> = computed(() => {
|
||||||
|
const featureFlagService = this.doc.get(FeatureFlagService);
|
||||||
|
const flag = featureFlagService.getFlag(
|
||||||
|
'enable_database_number_formatting'
|
||||||
|
);
|
||||||
return {
|
return {
|
||||||
enable_number_formatting:
|
enable_number_formatting: flag ?? false,
|
||||||
this.doc.awarenessStore.getFlag('enable_database_number_formatting') ??
|
|
||||||
false,
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+5
-4
@@ -3,6 +3,7 @@ import {
|
|||||||
EMBED_CARD_HEIGHT,
|
EMBED_CARD_HEIGHT,
|
||||||
EMBED_CARD_WIDTH,
|
EMBED_CARD_WIDTH,
|
||||||
} from '@blocksuite/affine-shared/consts';
|
} from '@blocksuite/affine-shared/consts';
|
||||||
|
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||||
import { cloneReferenceInfoWithoutAliases } from '@blocksuite/affine-shared/utils';
|
import { cloneReferenceInfoWithoutAliases } from '@blocksuite/affine-shared/utils';
|
||||||
import { Bound } from '@blocksuite/global/utils';
|
import { Bound } from '@blocksuite/global/utils';
|
||||||
|
|
||||||
@@ -15,10 +16,10 @@ export class EmbedEdgelessLinkedDocBlockComponent extends toEdgelessEmbedBlock(
|
|||||||
override convertToEmbed = () => {
|
override convertToEmbed = () => {
|
||||||
const { id, doc, caption, xywh } = this.model;
|
const { id, doc, caption, xywh } = this.model;
|
||||||
|
|
||||||
// synced doc entry controlled by awareness flag
|
// synced doc entry controlled by flag
|
||||||
const isSyncedDocEnabled = doc.awarenessStore.getFlag(
|
const isSyncedDocEnabled = doc
|
||||||
'enable_synced_doc_block'
|
.get(FeatureFlagService)
|
||||||
);
|
.getFlag('enable_synced_doc_block');
|
||||||
if (!isSyncedDocEnabled) {
|
if (!isSyncedDocEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
DocDisplayMetaProvider,
|
DocDisplayMetaProvider,
|
||||||
DocModeProvider,
|
DocModeProvider,
|
||||||
|
FeatureFlagService,
|
||||||
ThemeProvider,
|
ThemeProvider,
|
||||||
} from '@blocksuite/affine-shared/services';
|
} from '@blocksuite/affine-shared/services';
|
||||||
import {
|
import {
|
||||||
@@ -129,10 +130,10 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
|
|||||||
|
|
||||||
const { doc, caption } = this.model;
|
const { doc, caption } = this.model;
|
||||||
|
|
||||||
// synced doc entry controlled by awareness flag
|
// synced doc entry controlled by flag
|
||||||
const isSyncedDocEnabled = doc.awarenessStore.getFlag(
|
const isSyncedDocEnabled = doc
|
||||||
'enable_synced_doc_block'
|
.get(FeatureFlagService)
|
||||||
);
|
.getFlag('enable_synced_doc_block');
|
||||||
if (!isSyncedDocEnabled) {
|
if (!isSyncedDocEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import type {
|
|||||||
TextAlign,
|
TextAlign,
|
||||||
TextVerticalAlign,
|
TextVerticalAlign,
|
||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
|
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||||
import type { Bound, SerializedXYWH } from '@blocksuite/global/utils';
|
import type { Bound, SerializedXYWH } from '@blocksuite/global/utils';
|
||||||
import { deltaInsertsToChunks } from '@blocksuite/inline';
|
import { deltaInsertsToChunks } from '@blocksuite/inline';
|
||||||
|
|
||||||
@@ -68,9 +69,9 @@ export function drawGeneralShape(
|
|||||||
const { blur, offsetX, offsetY, color } = shapeModel.shadow;
|
const { blur, offsetX, offsetY, color } = shapeModel.shadow;
|
||||||
const scale = ctx.getTransform().a;
|
const scale = ctx.getTransform().a;
|
||||||
|
|
||||||
const enableShadowBlur = shapeModel.surface.doc.awarenessStore.getFlag(
|
const enableShadowBlur = shapeModel.surface.doc
|
||||||
'enable_shape_shadow_blur'
|
.get(FeatureFlagService)
|
||||||
);
|
.getFlag('enable_shape_shadow_blur');
|
||||||
|
|
||||||
// hard shadow, or soft shadow if `enable_shape_shadow_blur` is true
|
// hard shadow, or soft shadow if `enable_shape_shadow_blur` is true
|
||||||
// see comment of `shape.shadow` in `ShapeElementModel`
|
// see comment of `shape.shadow` in `ShapeElementModel`
|
||||||
|
|||||||
+5
-4
@@ -1,5 +1,6 @@
|
|||||||
import type { ReferenceInfo } from '@blocksuite/affine-model';
|
import type { ReferenceInfo } from '@blocksuite/affine-model';
|
||||||
import {
|
import {
|
||||||
|
FeatureFlagService,
|
||||||
GenerateDocUrlProvider,
|
GenerateDocUrlProvider,
|
||||||
type LinkEventType,
|
type LinkEventType,
|
||||||
type TelemetryEvent,
|
type TelemetryEvent,
|
||||||
@@ -305,10 +306,10 @@ export class ReferencePopup extends WithDisposable(LitElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _viewSelector() {
|
private _viewSelector() {
|
||||||
// synced doc entry controlled by awareness flag
|
// synced doc entry controlled by flag
|
||||||
const isSyncedDocEnabled = this.doc.awarenessStore.getFlag(
|
const isSyncedDocEnabled = this.doc
|
||||||
'enable_synced_doc_block'
|
.get(FeatureFlagService)
|
||||||
);
|
.getFlag('enable_synced_doc_block');
|
||||||
const buttons = [];
|
const buttons = [];
|
||||||
|
|
||||||
buttons.push({
|
buttons.push({
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import { type Store, StoreExtension } from '@blocksuite/store';
|
||||||
|
import { type Signal, signal } from '@preact/signals-core';
|
||||||
|
|
||||||
|
export interface BlockSuiteFlags {
|
||||||
|
enable_synced_doc_block: boolean;
|
||||||
|
enable_pie_menu: boolean;
|
||||||
|
enable_database_number_formatting: boolean;
|
||||||
|
enable_database_attachment_note: boolean;
|
||||||
|
enable_database_full_width: boolean;
|
||||||
|
enable_block_query: boolean;
|
||||||
|
enable_lasso_tool: boolean;
|
||||||
|
enable_edgeless_text: boolean;
|
||||||
|
enable_ai_onboarding: boolean;
|
||||||
|
enable_ai_chat_block: boolean;
|
||||||
|
enable_color_picker: boolean;
|
||||||
|
enable_mind_map_import: boolean;
|
||||||
|
enable_advanced_block_visibility: boolean;
|
||||||
|
enable_shape_shadow_blur: boolean;
|
||||||
|
enable_mobile_keyboard_toolbar: boolean;
|
||||||
|
enable_mobile_linked_doc_menu: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class FeatureFlagService extends StoreExtension {
|
||||||
|
static override key = 'feature-flag-server';
|
||||||
|
|
||||||
|
private readonly _flags: Signal<BlockSuiteFlags> = signal({
|
||||||
|
enable_synced_doc_block: true,
|
||||||
|
enable_pie_menu: false,
|
||||||
|
enable_database_number_formatting: false,
|
||||||
|
enable_database_attachment_note: false,
|
||||||
|
enable_database_full_width: false,
|
||||||
|
enable_block_query: false,
|
||||||
|
enable_lasso_tool: false,
|
||||||
|
enable_edgeless_text: true,
|
||||||
|
enable_ai_onboarding: true,
|
||||||
|
enable_ai_chat_block: true,
|
||||||
|
enable_color_picker: true,
|
||||||
|
enable_mind_map_import: true,
|
||||||
|
enable_advanced_block_visibility: false,
|
||||||
|
enable_shape_shadow_blur: false,
|
||||||
|
enable_mobile_keyboard_toolbar: false,
|
||||||
|
enable_mobile_linked_doc_menu: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
setFlag(key: keyof BlockSuiteFlags, value: boolean) {
|
||||||
|
this._flags.value = {
|
||||||
|
...this._flags.value,
|
||||||
|
[key]: value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
getFlag(key: keyof BlockSuiteFlags) {
|
||||||
|
return this._flags.value[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(store: Store) {
|
||||||
|
super(store);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ export * from './drag-handle-config';
|
|||||||
export * from './edit-props-store';
|
export * from './edit-props-store';
|
||||||
export * from './editor-setting-service';
|
export * from './editor-setting-service';
|
||||||
export * from './embed-option-service';
|
export * from './embed-option-service';
|
||||||
|
export * from './feature-flag-service';
|
||||||
export * from './font-loader';
|
export * from './font-loader';
|
||||||
export * from './generate-url-service';
|
export * from './generate-url-service';
|
||||||
export * from './native-clipboard-service';
|
export * from './native-clipboard-service';
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||||
import { Job, type JobMiddleware, Schema } from '@blocksuite/store';
|
import { Job, type JobMiddleware, Schema } from '@blocksuite/store';
|
||||||
import { TestWorkspace } from '@blocksuite/store/test';
|
import { TestWorkspace } from '@blocksuite/store/test';
|
||||||
|
|
||||||
@@ -22,6 +23,7 @@ export function createJob(middlewares?: JobMiddleware[]) {
|
|||||||
testMiddlewares.push(defaultImageProxyMiddleware);
|
testMiddlewares.push(defaultImageProxyMiddleware);
|
||||||
const schema = new Schema().register(AffineSchemas);
|
const schema = new Schema().register(AffineSchemas);
|
||||||
const docCollection = new TestWorkspace({ schema });
|
const docCollection = new TestWorkspace({ schema });
|
||||||
|
docCollection.storeExtensions = [FeatureFlagService];
|
||||||
docCollection.meta.initialize();
|
docCollection.meta.initialize();
|
||||||
return new Job({
|
return new Job({
|
||||||
schema,
|
schema,
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
DocDisplayMetaService,
|
DocDisplayMetaService,
|
||||||
EditPropsStore,
|
EditPropsStore,
|
||||||
|
FeatureFlagService,
|
||||||
FontLoaderService,
|
FontLoaderService,
|
||||||
} from '@blocksuite/affine-shared/services';
|
} from '@blocksuite/affine-shared/services';
|
||||||
import type { ExtensionType } from '@blocksuite/store';
|
import type { ExtensionType } from '@blocksuite/store';
|
||||||
@@ -73,3 +74,5 @@ export const EdgelessFirstPartyBlockSpecs: ExtensionType[] = [
|
|||||||
EdgelessTextBlockSpec,
|
EdgelessTextBlockSpec,
|
||||||
FontLoaderService,
|
FontLoaderService,
|
||||||
].flat();
|
].flat();
|
||||||
|
|
||||||
|
export const StoreExtensions: ExtensionType[] = [FeatureFlagService];
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
export * from './common.js';
|
||||||
export * from './preset/edgeless-specs.js';
|
export * from './preset/edgeless-specs.js';
|
||||||
export * from './preset/mobile-patch.js';
|
export * from './preset/mobile-patch.js';
|
||||||
export * from './preset/page-specs.js';
|
export * from './preset/page-specs.js';
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
type ReferenceNodeConfig,
|
type ReferenceNodeConfig,
|
||||||
ReferenceNodeConfigIdentifier,
|
ReferenceNodeConfigIdentifier,
|
||||||
} from '@blocksuite/affine-components/rich-text';
|
} from '@blocksuite/affine-components/rich-text';
|
||||||
|
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||||
import {
|
import {
|
||||||
type BlockStdScope,
|
type BlockStdScope,
|
||||||
ConfigIdentifier,
|
ConfigIdentifier,
|
||||||
@@ -21,9 +22,10 @@ export class MobileSpecsPatches extends LifeCycleWatcher {
|
|||||||
|
|
||||||
constructor(std: BlockStdScope) {
|
constructor(std: BlockStdScope) {
|
||||||
super(std);
|
super(std);
|
||||||
|
const featureFlagService = std.get(FeatureFlagService);
|
||||||
|
|
||||||
std.doc.awarenessStore.setFlag('enable_mobile_keyboard_toolbar', true);
|
featureFlagService.setFlag('enable_mobile_keyboard_toolbar', true);
|
||||||
std.doc.awarenessStore.setFlag('enable_mobile_linked_doc_menu', true);
|
featureFlagService.setFlag('enable_mobile_linked_doc_menu', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static override setup(di: Container) {
|
static override setup(di: Container) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { SpecProvider } from '@blocksuite/affine-shared/utils';
|
import { SpecProvider } from '@blocksuite/affine-shared/utils';
|
||||||
|
|
||||||
import { CommonBlockSpecs } from './common.js';
|
import { CommonBlockSpecs, StoreExtensions } from './common.js';
|
||||||
import { EdgelessEditorBlockSpecs } from './preset/edgeless-specs.js';
|
import { EdgelessEditorBlockSpecs } from './preset/edgeless-specs.js';
|
||||||
import { PageEditorBlockSpecs } from './preset/page-specs.js';
|
import { PageEditorBlockSpecs } from './preset/page-specs.js';
|
||||||
import {
|
import {
|
||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
} from './preset/preview-specs.js';
|
} from './preset/preview-specs.js';
|
||||||
|
|
||||||
export function registerSpecs() {
|
export function registerSpecs() {
|
||||||
|
SpecProvider.getInstance().addSpec('store', StoreExtensions);
|
||||||
SpecProvider.getInstance().addSpec('common', CommonBlockSpecs);
|
SpecProvider.getInstance().addSpec('common', CommonBlockSpecs);
|
||||||
SpecProvider.getInstance().addSpec('page', PageEditorBlockSpecs);
|
SpecProvider.getInstance().addSpec('page', PageEditorBlockSpecs);
|
||||||
SpecProvider.getInstance().addSpec('edgeless', EdgelessEditorBlockSpecs);
|
SpecProvider.getInstance().addSpec('edgeless', EdgelessEditorBlockSpecs);
|
||||||
|
|||||||
+4
-3
@@ -26,6 +26,7 @@ import {
|
|||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
import {
|
import {
|
||||||
EditPropsStore,
|
EditPropsStore,
|
||||||
|
FeatureFlagService,
|
||||||
ThemeProvider,
|
ThemeProvider,
|
||||||
} from '@blocksuite/affine-shared/services';
|
} from '@blocksuite/affine-shared/services';
|
||||||
import { captureEventTarget } from '@blocksuite/affine-shared/utils';
|
import { captureEventTarget } from '@blocksuite/affine-shared/utils';
|
||||||
@@ -249,9 +250,9 @@ export class EdgelessAutoCompletePanel extends WithDisposable(LitElement) {
|
|||||||
const { xywh, position } = target;
|
const { xywh, position } = target;
|
||||||
const bound = Bound.fromXYWH(xywh);
|
const bound = Bound.fromXYWH(xywh);
|
||||||
|
|
||||||
const textFlag = this.edgeless.doc.awarenessStore.getFlag(
|
const textFlag = this.edgeless.doc
|
||||||
'enable_edgeless_text'
|
.get(FeatureFlagService)
|
||||||
);
|
.getFlag('enable_edgeless_text');
|
||||||
if (textFlag) {
|
if (textFlag) {
|
||||||
const { textId } = this.edgeless.std.command.exec('insertEdgelessText', {
|
const { textId } = this.edgeless.std.command.exec('insertEdgelessText', {
|
||||||
x: bound.x,
|
x: bound.x,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { DefaultTheme } from '@blocksuite/affine-model';
|
import { DefaultTheme } from '@blocksuite/affine-model';
|
||||||
import {
|
import {
|
||||||
EditPropsStore,
|
EditPropsStore,
|
||||||
|
FeatureFlagService,
|
||||||
ThemeProvider,
|
ThemeProvider,
|
||||||
} from '@blocksuite/affine-shared/services';
|
} from '@blocksuite/affine-shared/services';
|
||||||
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
||||||
@@ -65,9 +66,9 @@ export class EdgelessBrushMenu extends EdgelessToolbarToolMixin(
|
|||||||
.value=${this._props$.value.color}
|
.value=${this._props$.value.color}
|
||||||
.theme=${this._theme$.value}
|
.theme=${this._theme$.value}
|
||||||
.palettes=${DefaultTheme.StrokeColorPalettes}
|
.palettes=${DefaultTheme.StrokeColorPalettes}
|
||||||
.hasTransparent=${!this.edgeless.doc.awarenessStore.getFlag(
|
.hasTransparent=${!this.edgeless.doc
|
||||||
'enable_color_picker'
|
.get(FeatureFlagService)
|
||||||
)}
|
.getFlag('enable_color_picker')}
|
||||||
@select=${(e: ColorEvent) =>
|
@select=${(e: ColorEvent) =>
|
||||||
this.onChange({ color: e.detail.value })}
|
this.onChange({ color: e.detail.value })}
|
||||||
></edgeless-color-panel>
|
></edgeless-color-panel>
|
||||||
|
|||||||
+4
-3
@@ -6,6 +6,7 @@ import {
|
|||||||
import { ConnectorMode, DefaultTheme } from '@blocksuite/affine-model';
|
import { ConnectorMode, DefaultTheme } from '@blocksuite/affine-model';
|
||||||
import {
|
import {
|
||||||
EditPropsStore,
|
EditPropsStore,
|
||||||
|
FeatureFlagService,
|
||||||
ThemeProvider,
|
ThemeProvider,
|
||||||
} from '@blocksuite/affine-shared/services';
|
} from '@blocksuite/affine-shared/services';
|
||||||
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
||||||
@@ -130,9 +131,9 @@ export class EdgelessConnectorMenu extends EdgelessToolbarToolMixin(
|
|||||||
.value=${stroke}
|
.value=${stroke}
|
||||||
.theme=${this._theme$.value}
|
.theme=${this._theme$.value}
|
||||||
.palettes=${DefaultTheme.StrokeColorPalettes}
|
.palettes=${DefaultTheme.StrokeColorPalettes}
|
||||||
.hasTransparent=${!this.edgeless.doc.awarenessStore.getFlag(
|
.hasTransparent=${!this.edgeless.doc
|
||||||
'enable_color_picker'
|
.get(FeatureFlagService)
|
||||||
)}
|
.getFlag('enable_color_picker')}
|
||||||
@select=${(e: ColorEvent) =>
|
@select=${(e: ColorEvent) =>
|
||||||
this.onChange({ stroke: e.detail.value })}
|
this.onChange({ stroke: e.detail.value })}
|
||||||
></edgeless-color-panel>
|
></edgeless-color-panel>
|
||||||
|
|||||||
+7
-2
@@ -1,6 +1,9 @@
|
|||||||
import { CanvasElementType } from '@blocksuite/affine-block-surface';
|
import { CanvasElementType } from '@blocksuite/affine-block-surface';
|
||||||
import { type MindmapStyle, TextElementModel } from '@blocksuite/affine-model';
|
import { type MindmapStyle, TextElementModel } from '@blocksuite/affine-model';
|
||||||
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
import {
|
||||||
|
FeatureFlagService,
|
||||||
|
TelemetryProvider,
|
||||||
|
} from '@blocksuite/affine-shared/services';
|
||||||
import { assertInstanceOf, Bound } from '@blocksuite/global/utils';
|
import { assertInstanceOf, Bound } from '@blocksuite/global/utils';
|
||||||
import type { TemplateResult } from 'lit';
|
import type { TemplateResult } from 'lit';
|
||||||
import * as Y from 'yjs';
|
import * as Y from 'yjs';
|
||||||
@@ -103,7 +106,9 @@ export const textRender: DraggableTool['render'] = (
|
|||||||
const w = 100;
|
const w = 100;
|
||||||
const h = 32;
|
const h = 32;
|
||||||
|
|
||||||
const flag = edgeless.doc.awarenessStore.getFlag('enable_edgeless_text');
|
const flag = edgeless.doc
|
||||||
|
.get(FeatureFlagService)
|
||||||
|
.getFlag('enable_edgeless_text');
|
||||||
let id: string;
|
let id: string;
|
||||||
if (flag) {
|
if (flag) {
|
||||||
const { textId } = edgeless.std.command.exec('insertEdgelessText', {
|
const { textId } = edgeless.std.command.exec('insertEdgelessText', {
|
||||||
|
|||||||
+2
-1
@@ -2,6 +2,7 @@ import { toast } from '@blocksuite/affine-components/toast';
|
|||||||
import type { MindmapStyle } from '@blocksuite/affine-model';
|
import type { MindmapStyle } from '@blocksuite/affine-model';
|
||||||
import {
|
import {
|
||||||
EditPropsStore,
|
EditPropsStore,
|
||||||
|
FeatureFlagService,
|
||||||
TelemetryProvider,
|
TelemetryProvider,
|
||||||
} from '@blocksuite/affine-shared/services';
|
} from '@blocksuite/affine-shared/services';
|
||||||
import type { BlockStdScope } from '@blocksuite/block-std';
|
import type { BlockStdScope } from '@blocksuite/block-std';
|
||||||
@@ -316,7 +317,7 @@ export class EdgelessMindmapMenu extends EdgelessToolbarToolMixin(
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
})}
|
})}
|
||||||
${this.std.doc.awarenessStore.getFlag('enable_mind_map_import')
|
${this.std.doc.get(FeatureFlagService).getFlag('enable_mind_map_import')
|
||||||
? this._importMindMapEntry()
|
? this._importMindMapEntry()
|
||||||
: nothing}
|
: nothing}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
import {
|
import {
|
||||||
EditPropsStore,
|
EditPropsStore,
|
||||||
|
FeatureFlagService,
|
||||||
ThemeProvider,
|
ThemeProvider,
|
||||||
} from '@blocksuite/affine-shared/services';
|
} from '@blocksuite/affine-shared/services';
|
||||||
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
||||||
@@ -173,9 +174,9 @@ export class EdgelessShapeMenu extends SignalWatcher(
|
|||||||
.value=${fillColor}
|
.value=${fillColor}
|
||||||
.theme=${this._theme$.value}
|
.theme=${this._theme$.value}
|
||||||
.palettes=${DefaultTheme.FillColorPalettes}
|
.palettes=${DefaultTheme.FillColorPalettes}
|
||||||
.hasTransparent=${!this.edgeless.doc.awarenessStore.getFlag(
|
.hasTransparent=${!this.edgeless.doc
|
||||||
'enable_color_picker'
|
.get(FeatureFlagService)
|
||||||
)}
|
.getFlag('enable_color_picker')}
|
||||||
@select=${(e: ColorEvent) => this._setFillColor(e.detail)}
|
@select=${(e: ColorEvent) => this._setFillColor(e.detail)}
|
||||||
></edgeless-color-panel>
|
></edgeless-color-panel>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
import {
|
import {
|
||||||
EditPropsStore,
|
EditPropsStore,
|
||||||
|
FeatureFlagService,
|
||||||
TelemetryProvider,
|
TelemetryProvider,
|
||||||
} from '@blocksuite/affine-shared/services';
|
} from '@blocksuite/affine-shared/services';
|
||||||
import { LassoMode } from '@blocksuite/affine-shared/types';
|
import { LassoMode } from '@blocksuite/affine-shared/types';
|
||||||
@@ -72,7 +73,11 @@ export class EdgelessPageKeyboardManager extends PageKeyboardManager {
|
|||||||
this._setEdgelessTool('connector', { mode });
|
this._setEdgelessTool('connector', { mode });
|
||||||
},
|
},
|
||||||
l: () => {
|
l: () => {
|
||||||
if (!rootComponent.doc.awarenessStore.getFlag('enable_lasso_tool')) {
|
if (
|
||||||
|
!rootComponent.doc
|
||||||
|
.get(FeatureFlagService)
|
||||||
|
.getFlag('enable_lasso_tool')
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +86,11 @@ export class EdgelessPageKeyboardManager extends PageKeyboardManager {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
'Shift-l': () => {
|
'Shift-l': () => {
|
||||||
if (!rootComponent.doc.awarenessStore.getFlag('enable_lasso_tool')) {
|
if (
|
||||||
|
!rootComponent.doc
|
||||||
|
.get(FeatureFlagService)
|
||||||
|
.getFlag('enable_lasso_tool')
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// toggle between lasso modes
|
// toggle between lasso modes
|
||||||
|
|||||||
@@ -15,7 +15,10 @@ import {
|
|||||||
ShapeElementModel,
|
ShapeElementModel,
|
||||||
TextElementModel,
|
TextElementModel,
|
||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
import {
|
||||||
|
FeatureFlagService,
|
||||||
|
TelemetryProvider,
|
||||||
|
} from '@blocksuite/affine-shared/services';
|
||||||
import {
|
import {
|
||||||
clamp,
|
clamp,
|
||||||
handleNativeRangeAtPoint,
|
handleNativeRangeAtPoint,
|
||||||
@@ -783,7 +786,9 @@ export class DefaultTool extends BaseTool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!selected) {
|
if (!selected) {
|
||||||
const textFlag = this.doc.awarenessStore.getFlag('enable_edgeless_text');
|
const textFlag = this.doc
|
||||||
|
.get(FeatureFlagService)
|
||||||
|
.getFlag('enable_edgeless_text');
|
||||||
|
|
||||||
if (textFlag) {
|
if (textFlag) {
|
||||||
const [x, y] = this.gfx.viewport.toModelCoord(e.x, e.y);
|
const [x, y] = this.gfx.viewport.toModelCoord(e.x, e.y);
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
import type { TextElementModel } from '@blocksuite/affine-model';
|
import type { TextElementModel } from '@blocksuite/affine-model';
|
||||||
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
import {
|
||||||
|
FeatureFlagService,
|
||||||
|
TelemetryProvider,
|
||||||
|
} from '@blocksuite/affine-shared/services';
|
||||||
import type { PointerEventState } from '@blocksuite/block-std';
|
import type { PointerEventState } from '@blocksuite/block-std';
|
||||||
import { BaseTool, type GfxController } from '@blocksuite/block-std/gfx';
|
import { BaseTool, type GfxController } from '@blocksuite/block-std/gfx';
|
||||||
import { Bound } from '@blocksuite/global/utils';
|
import { Bound } from '@blocksuite/global/utils';
|
||||||
@@ -38,9 +41,9 @@ export class TextTool extends BaseTool {
|
|||||||
static override toolName: string = 'text';
|
static override toolName: string = 'text';
|
||||||
|
|
||||||
override click(e: PointerEventState): void {
|
override click(e: PointerEventState): void {
|
||||||
const textFlag = this.gfx.doc.awarenessStore.getFlag(
|
const textFlag = this.gfx.doc
|
||||||
'enable_edgeless_text'
|
.get(FeatureFlagService)
|
||||||
);
|
.getFlag('enable_edgeless_text');
|
||||||
|
|
||||||
if (textFlag) {
|
if (textFlag) {
|
||||||
const [x, y] = this.gfx.viewport.toModelCoord(e.x, e.y);
|
const [x, y] = this.gfx.viewport.toModelCoord(e.x, e.y);
|
||||||
|
|||||||
+4
-3
@@ -12,6 +12,7 @@ import {
|
|||||||
type RootBlockModel,
|
type RootBlockModel,
|
||||||
type SurfaceRefBlockModel,
|
type SurfaceRefBlockModel,
|
||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
|
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||||
import {
|
import {
|
||||||
matchFlavours,
|
matchFlavours,
|
||||||
stopPropagation,
|
stopPropagation,
|
||||||
@@ -555,9 +556,9 @@ export class EdgelessAutoConnectWidget extends WidgetComponent<
|
|||||||
}
|
}
|
||||||
|
|
||||||
override render() {
|
override render() {
|
||||||
const advancedVisibilityEnabled = this.doc.awarenessStore.getFlag(
|
const advancedVisibilityEnabled = this.doc
|
||||||
'enable_advanced_block_visibility'
|
.get(FeatureFlagService)
|
||||||
);
|
.getFlag('enable_advanced_block_visibility');
|
||||||
|
|
||||||
if (!this._show || this._dragging || !advancedVisibilityEnabled) {
|
if (!this._show || this._dragging || !advancedVisibilityEnabled) {
|
||||||
return nothing;
|
return nothing;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
LineWidth,
|
LineWidth,
|
||||||
resolveColor,
|
resolveColor,
|
||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
|
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||||
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
||||||
import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils';
|
import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils';
|
||||||
import { html, LitElement, nothing } from 'lit';
|
import { html, LitElement, nothing } from 'lit';
|
||||||
@@ -120,7 +121,9 @@ export class EdgelessChangeBrushButton extends WithDisposable(LitElement) {
|
|||||||
<editor-toolbar-separator></editor-toolbar-separator>
|
<editor-toolbar-separator></editor-toolbar-separator>
|
||||||
|
|
||||||
${when(
|
${when(
|
||||||
this.edgeless.doc.awarenessStore.getFlag('enable_color_picker'),
|
this.edgeless.doc
|
||||||
|
.get(FeatureFlagService)
|
||||||
|
.getFlag('enable_color_picker'),
|
||||||
() => {
|
() => {
|
||||||
const { type, colors } = packColorsWithColorScheme(
|
const { type, colors } = packColorsWithColorScheme(
|
||||||
colorScheme,
|
colorScheme,
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import {
|
|||||||
resolveColor,
|
resolveColor,
|
||||||
StrokeStyle,
|
StrokeStyle,
|
||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
|
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||||
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
||||||
import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils';
|
import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils';
|
||||||
import { html, LitElement, nothing, type TemplateResult } from 'lit';
|
import { html, LitElement, nothing, type TemplateResult } from 'lit';
|
||||||
@@ -361,7 +362,9 @@ export class EdgelessChangeConnectorButton extends WithDisposable(LitElement) {
|
|||||||
return join(
|
return join(
|
||||||
[
|
[
|
||||||
when(
|
when(
|
||||||
this.edgeless.doc.awarenessStore.getFlag('enable_color_picker'),
|
this.edgeless.doc
|
||||||
|
.get(FeatureFlagService)
|
||||||
|
.getFlag('enable_color_picker'),
|
||||||
() => {
|
() => {
|
||||||
const { type, colors } = packColorsWithColorScheme(
|
const { type, colors } = packColorsWithColorScheme(
|
||||||
colorScheme,
|
colorScheme,
|
||||||
|
|||||||
+4
-3
@@ -40,6 +40,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
EmbedOptionProvider,
|
EmbedOptionProvider,
|
||||||
type EmbedOptions,
|
type EmbedOptions,
|
||||||
|
FeatureFlagService,
|
||||||
GenerateDocUrlProvider,
|
GenerateDocUrlProvider,
|
||||||
type GenerateDocUrlService,
|
type GenerateDocUrlService,
|
||||||
type LinkEventType,
|
type LinkEventType,
|
||||||
@@ -390,9 +391,9 @@ export class EdgelessChangeEmbedCardButton extends WithDisposable(LitElement) {
|
|||||||
|
|
||||||
// synced doc entry controlled by awareness flag
|
// synced doc entry controlled by awareness flag
|
||||||
if (!!block && isEmbedLinkedDocBlock(block.model)) {
|
if (!!block && isEmbedLinkedDocBlock(block.model)) {
|
||||||
const isSyncedDocEnabled = block.doc.awarenessStore.getFlag(
|
const isSyncedDocEnabled = block.doc
|
||||||
'enable_synced_doc_block'
|
.get(FeatureFlagService)
|
||||||
);
|
.getFlag('enable_synced_doc_block');
|
||||||
if (!isSyncedDocEnabled) {
|
if (!isSyncedDocEnabled) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import {
|
|||||||
NoteDisplayMode,
|
NoteDisplayMode,
|
||||||
resolveColor,
|
resolveColor,
|
||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
|
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||||
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
||||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
||||||
import { GfxExtensionIdentifier } from '@blocksuite/block-std/gfx';
|
import { GfxExtensionIdentifier } from '@blocksuite/block-std/gfx';
|
||||||
@@ -190,7 +191,9 @@ export class EdgelessChangeFrameButton extends WithDisposable(LitElement) {
|
|||||||
`,
|
`,
|
||||||
|
|
||||||
when(
|
when(
|
||||||
this.edgeless.doc.awarenessStore.getFlag('enable_color_picker'),
|
this.edgeless.doc
|
||||||
|
.get(FeatureFlagService)
|
||||||
|
.getFlag('enable_color_picker'),
|
||||||
() => {
|
() => {
|
||||||
const { type, colors } = packColorsWithColorScheme(
|
const { type, colors } = packColorsWithColorScheme(
|
||||||
colorScheme,
|
colorScheme,
|
||||||
|
|||||||
@@ -28,7 +28,10 @@ import {
|
|||||||
resolveColor,
|
resolveColor,
|
||||||
type StrokeStyle,
|
type StrokeStyle,
|
||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
import { ThemeProvider } from '@blocksuite/affine-shared/services';
|
import {
|
||||||
|
FeatureFlagService,
|
||||||
|
ThemeProvider,
|
||||||
|
} from '@blocksuite/affine-shared/services';
|
||||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
||||||
import {
|
import {
|
||||||
assertExists,
|
assertExists,
|
||||||
@@ -133,7 +136,9 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private get _advancedVisibilityEnabled() {
|
private get _advancedVisibilityEnabled() {
|
||||||
return this.doc.awarenessStore.getFlag('enable_advanced_block_visibility');
|
return this.doc
|
||||||
|
.get(FeatureFlagService)
|
||||||
|
.getFlag('enable_advanced_block_visibility');
|
||||||
}
|
}
|
||||||
|
|
||||||
private get doc() {
|
private get doc() {
|
||||||
@@ -301,7 +306,9 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
|
|||||||
isDocOnly
|
isDocOnly
|
||||||
? nothing
|
? nothing
|
||||||
: when(
|
: when(
|
||||||
this.edgeless.doc.awarenessStore.getFlag('enable_color_picker'),
|
this.edgeless.doc
|
||||||
|
.get(FeatureFlagService)
|
||||||
|
.getFlag('enable_color_picker'),
|
||||||
() => {
|
() => {
|
||||||
const { type, colors } = packColorsWithColorScheme(
|
const { type, colors } = packColorsWithColorScheme(
|
||||||
colorScheme,
|
colorScheme,
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import {
|
|||||||
ShapeStyle,
|
ShapeStyle,
|
||||||
StrokeStyle,
|
StrokeStyle,
|
||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
|
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||||
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
||||||
import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils';
|
import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils';
|
||||||
import { css, html, LitElement, nothing, type TemplateResult } from 'lit';
|
import { css, html, LitElement, nothing, type TemplateResult } from 'lit';
|
||||||
@@ -317,7 +318,9 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
|
|||||||
`,
|
`,
|
||||||
|
|
||||||
when(
|
when(
|
||||||
this.edgeless.doc.awarenessStore.getFlag('enable_color_picker'),
|
this.edgeless.doc
|
||||||
|
.get(FeatureFlagService)
|
||||||
|
.getFlag('enable_color_picker'),
|
||||||
() => {
|
() => {
|
||||||
const { type, colors } = packColorsWithColorScheme(
|
const { type, colors } = packColorsWithColorScheme(
|
||||||
colorScheme,
|
colorScheme,
|
||||||
@@ -367,7 +370,9 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
|
|||||||
),
|
),
|
||||||
|
|
||||||
when(
|
when(
|
||||||
this.edgeless.doc.awarenessStore.getFlag('enable_color_picker'),
|
this.edgeless.doc
|
||||||
|
.get(FeatureFlagService)
|
||||||
|
.getFlag('enable_color_picker'),
|
||||||
() => {
|
() => {
|
||||||
const { type, colors } = packColorsWithColorScheme(
|
const { type, colors } = packColorsWithColorScheme(
|
||||||
colorScheme,
|
colorScheme,
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import {
|
|||||||
TextElementModel,
|
TextElementModel,
|
||||||
type TextStyleProps,
|
type TextStyleProps,
|
||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
|
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||||
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
||||||
import {
|
import {
|
||||||
Bound,
|
Bound,
|
||||||
@@ -372,7 +373,9 @@ export class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
|
|||||||
`,
|
`,
|
||||||
|
|
||||||
when(
|
when(
|
||||||
this.edgeless.doc.awarenessStore.getFlag('enable_color_picker'),
|
this.edgeless.doc
|
||||||
|
.get(FeatureFlagService)
|
||||||
|
.getFlag('enable_color_picker'),
|
||||||
() => {
|
() => {
|
||||||
const { type, colors } = packColorsWithColorScheme(
|
const { type, colors } = packColorsWithColorScheme(
|
||||||
colorScheme,
|
colorScheme,
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
EmbedOptionProvider,
|
EmbedOptionProvider,
|
||||||
type EmbedOptions,
|
type EmbedOptions,
|
||||||
|
FeatureFlagService,
|
||||||
GenerateDocUrlProvider,
|
GenerateDocUrlProvider,
|
||||||
type GenerateDocUrlService,
|
type GenerateDocUrlService,
|
||||||
type LinkEventType,
|
type LinkEventType,
|
||||||
@@ -203,9 +204,9 @@ export class EmbedCardToolbar extends WidgetComponent<
|
|||||||
private get _canConvertToEmbedView() {
|
private get _canConvertToEmbedView() {
|
||||||
// synced doc entry controlled by awareness flag
|
// synced doc entry controlled by awareness flag
|
||||||
if (this.focusModel && isEmbedLinkedDocBlock(this.focusModel)) {
|
if (this.focusModel && isEmbedLinkedDocBlock(this.focusModel)) {
|
||||||
const isSyncedDocEnabled = this.doc.awarenessStore.getFlag(
|
const isSyncedDocEnabled = this.doc
|
||||||
'enable_synced_doc_block'
|
.get(FeatureFlagService)
|
||||||
);
|
.getFlag('enable_synced_doc_block');
|
||||||
if (!isSyncedDocEnabled) {
|
if (!isSyncedDocEnabled) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { RootBlockModel } from '@blocksuite/affine-model';
|
import type { RootBlockModel } from '@blocksuite/affine-model';
|
||||||
|
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||||
import { WidgetComponent } from '@blocksuite/block-std';
|
import { WidgetComponent } from '@blocksuite/block-std';
|
||||||
import { IS_MOBILE } from '@blocksuite/global/env';
|
import { IS_MOBILE } from '@blocksuite/global/env';
|
||||||
import { assertType } from '@blocksuite/global/utils';
|
import { assertType } from '@blocksuite/global/utils';
|
||||||
@@ -71,7 +72,9 @@ export class AffineKeyboardToolbarWidget extends WidgetComponent<
|
|||||||
if (
|
if (
|
||||||
this.doc.readonly ||
|
this.doc.readonly ||
|
||||||
!IS_MOBILE ||
|
!IS_MOBILE ||
|
||||||
!this.doc.awarenessStore.getFlag('enable_mobile_keyboard_toolbar')
|
!this.doc
|
||||||
|
.get(FeatureFlagService)
|
||||||
|
.getFlag('enable_mobile_keyboard_toolbar')
|
||||||
)
|
)
|
||||||
return nothing;
|
return nothing;
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
getRangeRects,
|
getRangeRects,
|
||||||
type SelectionRect,
|
type SelectionRect,
|
||||||
} from '@blocksuite/affine-shared/commands';
|
} from '@blocksuite/affine-shared/commands';
|
||||||
|
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||||
import { getViewportElement } from '@blocksuite/affine-shared/utils';
|
import { getViewportElement } from '@blocksuite/affine-shared/utils';
|
||||||
import type { BlockComponent } from '@blocksuite/block-std';
|
import type { BlockComponent } from '@blocksuite/block-std';
|
||||||
import { BLOCK_ID_ATTR, WidgetComponent } from '@blocksuite/block-std';
|
import { BLOCK_ID_ATTR, WidgetComponent } from '@blocksuite/block-std';
|
||||||
@@ -256,9 +257,9 @@ export class AffineLinkedDocWidget extends WidgetComponent<
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const enableMobile = this.doc.awarenessStore.getFlag(
|
const enableMobile = this.doc
|
||||||
'enable_mobile_linked_doc_menu'
|
.get(FeatureFlagService)
|
||||||
);
|
.getFlag('enable_mobile_linked_doc_menu');
|
||||||
this._mode$.value = enableMobile ? mode : 'desktop';
|
this._mode$.value = enableMobile ? mode : 'desktop';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,10 @@ import type {
|
|||||||
ParagraphBlockModel,
|
ParagraphBlockModel,
|
||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
import { REFERENCE_NODE } from '@blocksuite/affine-shared/consts';
|
import { REFERENCE_NODE } from '@blocksuite/affine-shared/consts';
|
||||||
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
import {
|
||||||
|
FeatureFlagService,
|
||||||
|
TelemetryProvider,
|
||||||
|
} from '@blocksuite/affine-shared/services';
|
||||||
import {
|
import {
|
||||||
createDefaultDoc,
|
createDefaultDoc,
|
||||||
openFileOrFiles,
|
openFileOrFiles,
|
||||||
@@ -574,7 +577,7 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
|
|||||||
showWhen: ({ model }) =>
|
showWhen: ({ model }) =>
|
||||||
model.doc.schema.flavourSchemaMap.has('affine:database') &&
|
model.doc.schema.flavourSchemaMap.has('affine:database') &&
|
||||||
!insideEdgelessText(model) &&
|
!insideEdgelessText(model) &&
|
||||||
!!model.doc.awarenessStore.getFlag('enable_block_query'),
|
!!model.doc.get(FeatureFlagService).getFlag('enable_block_query'),
|
||||||
|
|
||||||
action: ({ model, rootComponent }) => {
|
action: ({ model, rootComponent }) => {
|
||||||
const parent = rootComponent.doc.getParent(model);
|
const parent = rootComponent.doc.getParent(model);
|
||||||
|
|||||||
@@ -1,20 +1,4 @@
|
|||||||
export interface BlockSuiteFlags {
|
export interface BlockSuiteFlags {
|
||||||
enable_synced_doc_block: boolean;
|
|
||||||
enable_pie_menu: boolean;
|
|
||||||
enable_database_number_formatting: boolean;
|
|
||||||
enable_database_attachment_note: boolean;
|
|
||||||
enable_database_full_width: boolean;
|
|
||||||
enable_block_query: boolean;
|
|
||||||
enable_lasso_tool: boolean;
|
|
||||||
enable_edgeless_text: boolean;
|
|
||||||
enable_ai_onboarding: boolean;
|
|
||||||
enable_ai_chat_block: boolean;
|
|
||||||
enable_color_picker: boolean;
|
|
||||||
enable_mind_map_import: boolean;
|
|
||||||
enable_advanced_block_visibility: boolean;
|
|
||||||
enable_shape_shadow_blur: boolean;
|
|
||||||
enable_mobile_keyboard_toolbar: boolean;
|
|
||||||
enable_mobile_linked_doc_menu: boolean;
|
|
||||||
readonly: Record<string, boolean>;
|
readonly: Record<string, boolean>;
|
||||||
}
|
}
|
||||||
export * from './virtual-keyboard.js';
|
export * from './virtual-keyboard.js';
|
||||||
@@ -860,22 +860,6 @@ describe('getBlock', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('flags', () => {
|
|
||||||
it('update flags', () => {
|
|
||||||
const options = createTestOptions();
|
|
||||||
const collection = new TestWorkspace(options);
|
|
||||||
collection.meta.initialize();
|
|
||||||
|
|
||||||
const awareness = collection.awarenessStore;
|
|
||||||
|
|
||||||
awareness.setFlag('enable_lasso_tool', false);
|
|
||||||
expect(awareness.getFlag('enable_lasso_tool')).toBe(false);
|
|
||||||
|
|
||||||
awareness.setFlag('enable_lasso_tool', true);
|
|
||||||
expect(awareness.getFlag('enable_lasso_tool')).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
namespace BlockSuite {
|
namespace BlockSuite {
|
||||||
interface BlockModels {
|
interface BlockModels {
|
||||||
|
|||||||
@@ -688,4 +688,12 @@ export class Store {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get get() {
|
||||||
|
return this.provider.get.bind(this.provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
get getOptional() {
|
||||||
|
return this.provider.getOptional.bind(this.provider);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@ import type { Doc, GetBlocksOptions, Workspace } from '../model/index.js';
|
|||||||
import type { Query } from '../model/store/query.js';
|
import type { Query } from '../model/store/query.js';
|
||||||
import { Store } from '../model/store/store.js';
|
import { Store } from '../model/store/store.js';
|
||||||
import type { AwarenessStore } from '../yjs/index.js';
|
import type { AwarenessStore } from '../yjs/index.js';
|
||||||
|
import type { TestWorkspace } from './test-workspace.js';
|
||||||
|
|
||||||
type DocOptions = {
|
type DocOptions = {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -294,7 +295,9 @@ export class TestDoc implements Doc {
|
|||||||
readonly,
|
readonly,
|
||||||
query,
|
query,
|
||||||
provider,
|
provider,
|
||||||
extensions,
|
extensions: (this.workspace as TestWorkspace).storeExtensions.concat(
|
||||||
|
extensions ?? []
|
||||||
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
this._docMap[readonlyKey].set(key, doc);
|
this._docMap[readonlyKey].set(key, doc);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import merge from 'lodash.merge';
|
|||||||
import { Awareness } from 'y-protocols/awareness.js';
|
import { Awareness } from 'y-protocols/awareness.js';
|
||||||
import * as Y from 'yjs';
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
|
import type { ExtensionType } from '../extension/extension.js';
|
||||||
import type {
|
import type {
|
||||||
CreateBlocksOptions,
|
CreateBlocksOptions,
|
||||||
GetBlocksOptions,
|
GetBlocksOptions,
|
||||||
@@ -46,22 +47,6 @@ export type DocCollectionOptions = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const FLAGS_PRESET = {
|
const FLAGS_PRESET = {
|
||||||
enable_synced_doc_block: false,
|
|
||||||
enable_pie_menu: false,
|
|
||||||
enable_database_number_formatting: false,
|
|
||||||
enable_database_attachment_note: false,
|
|
||||||
enable_database_full_width: false,
|
|
||||||
enable_block_query: false,
|
|
||||||
enable_lasso_tool: false,
|
|
||||||
enable_edgeless_text: true,
|
|
||||||
enable_ai_onboarding: false,
|
|
||||||
enable_ai_chat_block: false,
|
|
||||||
enable_color_picker: false,
|
|
||||||
enable_mind_map_import: false,
|
|
||||||
enable_advanced_block_visibility: false,
|
|
||||||
enable_shape_shadow_blur: false,
|
|
||||||
enable_mobile_keyboard_toolbar: false,
|
|
||||||
enable_mobile_linked_doc_menu: false,
|
|
||||||
readonly: {},
|
readonly: {},
|
||||||
} satisfies BlockSuiteFlags;
|
} satisfies BlockSuiteFlags;
|
||||||
|
|
||||||
@@ -72,6 +57,8 @@ const FLAGS_PRESET = {
|
|||||||
export class TestWorkspace implements Workspace {
|
export class TestWorkspace implements Workspace {
|
||||||
protected readonly _schema: Schema;
|
protected readonly _schema: Schema;
|
||||||
|
|
||||||
|
storeExtensions: ExtensionType[] = [];
|
||||||
|
|
||||||
readonly awarenessStore: AwarenessStore;
|
readonly awarenessStore: AwarenessStore;
|
||||||
|
|
||||||
readonly awarenessSync: AwarenessEngine;
|
readonly awarenessSync: AwarenessEngine;
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import { AffineSchemas } from '@blocksuite/blocks';
|
import { AffineSchemas, SpecProvider } from '@blocksuite/blocks';
|
||||||
import { Schema } from '@blocksuite/store';
|
import { Schema } from '@blocksuite/store';
|
||||||
import { TestWorkspace } from '@blocksuite/store/test';
|
import { TestWorkspace } from '@blocksuite/store/test';
|
||||||
|
|
||||||
export function createEmptyDoc() {
|
export function createEmptyDoc() {
|
||||||
const schema = new Schema().register(AffineSchemas);
|
const schema = new Schema().register(AffineSchemas);
|
||||||
const collection = new TestWorkspace({ schema });
|
const collection = new TestWorkspace({ schema });
|
||||||
|
collection.storeExtensions =
|
||||||
|
SpecProvider.getInstance().getSpec('store').value;
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
const doc = collection.createDoc();
|
const doc = collection.createDoc();
|
||||||
|
|
||||||
|
|||||||
@@ -7,18 +7,14 @@ import {
|
|||||||
} from '@blocksuite/blocks';
|
} from '@blocksuite/blocks';
|
||||||
import { viewPresets } from '@blocksuite/data-view/view-presets';
|
import { viewPresets } from '@blocksuite/data-view/view-presets';
|
||||||
import { assertExists } from '@blocksuite/global/utils';
|
import { assertExists } from '@blocksuite/global/utils';
|
||||||
import { type DocCollection, Text } from '@blocksuite/store';
|
import { Text, type Workspace } from '@blocksuite/store';
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
|
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
|
||||||
import { propertyPresets } from '../../../../affine/data-view/src/property-presets';
|
import { propertyPresets } from '../../../../affine/data-view/src/property-presets';
|
||||||
import type { InitFn } from './utils.js';
|
import type { InitFn } from './utils.js';
|
||||||
|
|
||||||
export const database: InitFn = (collection: DocCollection, id: string) => {
|
export const database: InitFn = (collection: Workspace, id: string) => {
|
||||||
const doc = collection.createDoc({ id });
|
const doc = collection.createDoc({ id });
|
||||||
doc.awarenessStore.setFlag('enable_database_number_formatting', true);
|
|
||||||
doc.awarenessStore.setFlag('enable_database_attachment_note', true);
|
|
||||||
doc.awarenessStore.setFlag('enable_database_full_width', true);
|
|
||||||
doc.awarenessStore.setFlag('enable_block_query', true);
|
|
||||||
|
|
||||||
doc.load(() => {
|
doc.load(() => {
|
||||||
// Add root block and surface block at root level
|
// Add root block and surface block at root level
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { AffineSchemas, TestUtils } from '@blocksuite/blocks';
|
import { AffineSchemas, SpecProvider, TestUtils } from '@blocksuite/blocks';
|
||||||
import type { BlockSuiteFlags } from '@blocksuite/global/types';
|
import type { BlockSuiteFlags } from '@blocksuite/global/types';
|
||||||
import { assertExists } from '@blocksuite/global/utils';
|
import { assertExists } from '@blocksuite/global/utils';
|
||||||
import { type BlockCollection, Job, nanoid, Schema } from '@blocksuite/store';
|
import { type BlockCollection, Job, nanoid, Schema } from '@blocksuite/store';
|
||||||
@@ -75,6 +75,8 @@ export function createStarterDocCollection() {
|
|||||||
blobSources,
|
blobSources,
|
||||||
};
|
};
|
||||||
const collection = new TestWorkspace(options);
|
const collection = new TestWorkspace(options);
|
||||||
|
collection.storeExtensions =
|
||||||
|
SpecProvider.getInstance().getSpec('store').value;
|
||||||
collection.start();
|
collection.start();
|
||||||
|
|
||||||
// debug info
|
// debug info
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ effects();
|
|||||||
import {
|
import {
|
||||||
CommunityCanvasTextFonts,
|
CommunityCanvasTextFonts,
|
||||||
type DocMode,
|
type DocMode,
|
||||||
|
FeatureFlagService,
|
||||||
FontConfigExtension,
|
FontConfigExtension,
|
||||||
} from '@blocksuite/blocks';
|
} from '@blocksuite/blocks';
|
||||||
import { AffineSchemas } from '@blocksuite/blocks/schemas';
|
import { AffineSchemas } from '@blocksuite/blocks/schemas';
|
||||||
@@ -84,6 +85,7 @@ async function createEditor(collection: TestWorkspace, mode: DocMode = 'page') {
|
|||||||
|
|
||||||
export async function setupEditor(mode: DocMode = 'page') {
|
export async function setupEditor(mode: DocMode = 'page') {
|
||||||
const collection = new TestWorkspace(createCollectionOptions());
|
const collection = new TestWorkspace(createCollectionOptions());
|
||||||
|
collection.storeExtensions = [FeatureFlagService];
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
|
|
||||||
window.collection = collection;
|
window.collection = collection;
|
||||||
|
|||||||
@@ -108,10 +108,11 @@ test.describe('auto-complete', () => {
|
|||||||
test('drag on right auto-complete button to add canvas text', async ({
|
test('drag on right auto-complete button to add canvas text', async ({
|
||||||
page,
|
page,
|
||||||
}) => {
|
}) => {
|
||||||
await enterPlaygroundRoom(page, {
|
await enterPlaygroundRoom(page);
|
||||||
flags: {
|
await page.evaluate(() => {
|
||||||
enable_edgeless_text: false,
|
window.doc
|
||||||
},
|
.get(window.$blocksuite.blocks.FeatureFlagService)
|
||||||
|
.setFlag('enable_edgeless_text', false);
|
||||||
});
|
});
|
||||||
await initEmptyEdgelessState(page);
|
await initEmptyEdgelessState(page);
|
||||||
await switchEditorMode(page);
|
await switchEditorMode(page);
|
||||||
|
|||||||
@@ -54,11 +54,7 @@ async function assertEdgelessTextModelRect(
|
|||||||
|
|
||||||
test.describe('edgeless text block', () => {
|
test.describe('edgeless text block', () => {
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
await enterPlaygroundRoom(page, {
|
await enterPlaygroundRoom(page);
|
||||||
flags: {
|
|
||||||
enable_edgeless_text: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await initEmptyEdgelessState(page);
|
await initEmptyEdgelessState(page);
|
||||||
await switchEditorMode(page);
|
await switchEditorMode(page);
|
||||||
});
|
});
|
||||||
@@ -546,11 +542,7 @@ test.describe('edgeless text block', () => {
|
|||||||
test('press backspace at the start of first line when edgeless text exist', async ({
|
test('press backspace at the start of first line when edgeless text exist', async ({
|
||||||
page,
|
page,
|
||||||
}, testInfo) => {
|
}, testInfo) => {
|
||||||
await enterPlaygroundRoom(page, {
|
await enterPlaygroundRoom(page);
|
||||||
flags: {
|
|
||||||
enable_edgeless_text: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await page.evaluate(() => {
|
await page.evaluate(() => {
|
||||||
const { doc } = window;
|
const { doc } = window;
|
||||||
const rootId = doc.addBlock('affine:page', {
|
const rootId = doc.addBlock('affine:page', {
|
||||||
|
|||||||
@@ -66,11 +66,7 @@ test.describe('pasting blocks', () => {
|
|||||||
await expect(blocks.nth(3)).toContainText('code');
|
await expect(blocks.nth(3)).toContainText('code');
|
||||||
});
|
});
|
||||||
test('pasting a edgeless block', async ({ page }) => {
|
test('pasting a edgeless block', async ({ page }) => {
|
||||||
await enterPlaygroundRoom(page, {
|
await enterPlaygroundRoom(page);
|
||||||
flags: {
|
|
||||||
enable_edgeless_text: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await initEmptyEdgelessState(page);
|
await initEmptyEdgelessState(page);
|
||||||
await switchEditorMode(page);
|
await switchEditorMode(page);
|
||||||
await setEdgelessTool(page, 'default');
|
await setEdgelessTool(page, 'default');
|
||||||
|
|||||||
@@ -641,10 +641,11 @@ test.describe('shape hit test', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
await enterPlaygroundRoom(page, {
|
await enterPlaygroundRoom(page);
|
||||||
flags: {
|
await page.evaluate(() => {
|
||||||
enable_edgeless_text: false,
|
window.doc
|
||||||
},
|
.get(window.$blocksuite.blocks.FeatureFlagService)
|
||||||
|
.setFlag('enable_edgeless_text', false);
|
||||||
});
|
});
|
||||||
await initEmptyEdgelessState(page);
|
await initEmptyEdgelessState(page);
|
||||||
await switchEditorMode(page);
|
await switchEditorMode(page);
|
||||||
|
|||||||
@@ -38,10 +38,11 @@ async function assertTextFont(page: Page, font: string) {
|
|||||||
|
|
||||||
test.describe('edgeless canvas text', () => {
|
test.describe('edgeless canvas text', () => {
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
await enterPlaygroundRoom(page, {
|
await enterPlaygroundRoom(page);
|
||||||
flags: {
|
await page.evaluate(() => {
|
||||||
enable_edgeless_text: false,
|
window.doc
|
||||||
},
|
.get(window.$blocksuite.blocks.FeatureFlagService)
|
||||||
|
.setFlag('enable_edgeless_text', false);
|
||||||
});
|
});
|
||||||
await initEmptyEdgelessState(page);
|
await initEmptyEdgelessState(page);
|
||||||
await switchEditorMode(page);
|
await switchEditorMode(page);
|
||||||
|
|||||||
@@ -95,6 +95,9 @@ async function initEmptyEditor({
|
|||||||
}
|
}
|
||||||
const createEditor = () => {
|
const createEditor = () => {
|
||||||
const editor = document.createElement('affine-editor-container');
|
const editor = document.createElement('affine-editor-container');
|
||||||
|
doc
|
||||||
|
.get(window.$blocksuite.blocks.FeatureFlagService)
|
||||||
|
.setFlag('enable_advanced_block_visibility', true);
|
||||||
editor.doc = doc;
|
editor.doc = doc;
|
||||||
editor.autofocus = true;
|
editor.autofocus = true;
|
||||||
const defaultExtensions: ExtensionType[] = [
|
const defaultExtensions: ExtensionType[] = [
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { ShadowlessElement } from '@blocksuite/affine/block-std';
|
|||||||
import {
|
import {
|
||||||
type AIError,
|
type AIError,
|
||||||
DocModeProvider,
|
DocModeProvider,
|
||||||
|
FeatureFlagService,
|
||||||
isInsidePageEditor,
|
isInsidePageEditor,
|
||||||
PaymentRequiredError,
|
PaymentRequiredError,
|
||||||
UnauthorizedError,
|
UnauthorizedError,
|
||||||
@@ -141,7 +142,7 @@ export class ChatPanelMessages extends WithDisposable(ShadowlessElement) {
|
|||||||
|
|
||||||
private _renderAIOnboarding() {
|
private _renderAIOnboarding() {
|
||||||
return this.isLoading ||
|
return this.isLoading ||
|
||||||
!this.host?.doc.awarenessStore.getFlag('enable_ai_onboarding')
|
!this.host?.doc.get(FeatureFlagService).getFlag('enable_ai_onboarding')
|
||||||
? nothing
|
? nothing
|
||||||
: html`<div
|
: html`<div
|
||||||
style=${styleMap({
|
style=${styleMap({
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import type { DefaultOpenProperty } from '@affine/core/components/doc-properties
|
|||||||
import {
|
import {
|
||||||
type DocMode,
|
type DocMode,
|
||||||
EdgelessRootService,
|
EdgelessRootService,
|
||||||
|
FeatureFlagService as BSFeatureFlagService,
|
||||||
HighlightSelection,
|
HighlightSelection,
|
||||||
type ReferenceParams,
|
type ReferenceParams,
|
||||||
} from '@blocksuite/affine/blocks';
|
} from '@blocksuite/affine/blocks';
|
||||||
@@ -16,6 +17,7 @@ import { defaults, isEqual, omit } from 'lodash-es';
|
|||||||
import { skip } from 'rxjs';
|
import { skip } from 'rxjs';
|
||||||
|
|
||||||
import type { DocService } from '../../doc';
|
import type { DocService } from '../../doc';
|
||||||
|
import { AFFINE_FLAGS, type FeatureFlagService } from '../../feature-flag';
|
||||||
import { paramsParseOptions, preprocessParams } from '../../navigation/utils';
|
import { paramsParseOptions, preprocessParams } from '../../navigation/utils';
|
||||||
import type { WorkbenchView } from '../../workbench';
|
import type { WorkbenchView } from '../../workbench';
|
||||||
import type { WorkspaceService } from '../../workspace';
|
import type { WorkspaceService } from '../../workspace';
|
||||||
@@ -193,6 +195,8 @@ export class Editor extends Entity {
|
|||||||
if (this.editorContainer$.value) {
|
if (this.editorContainer$.value) {
|
||||||
throw new Error('already bound');
|
throw new Error('already bound');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._setupBlocksuiteEditorFlags(editorContainer);
|
||||||
this.editorContainer$.next(editorContainer);
|
this.editorContainer$.next(editorContainer);
|
||||||
const unsubs: (() => void)[] = [];
|
const unsubs: (() => void)[] = [];
|
||||||
|
|
||||||
@@ -325,9 +329,24 @@ export class Editor extends Entity {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _setupBlocksuiteEditorFlags(editorContainer: AffineEditorContainer) {
|
||||||
|
const affineFeatureFlagService = this.featureFlagService;
|
||||||
|
const bsFeatureFlagService = editorContainer.doc.get(BSFeatureFlagService);
|
||||||
|
Object.entries(AFFINE_FLAGS).forEach(([key, flag]) => {
|
||||||
|
if (flag.category === 'blocksuite') {
|
||||||
|
const value =
|
||||||
|
affineFeatureFlagService.flags[key as keyof AFFINE_FLAGS].value;
|
||||||
|
if (value !== undefined) {
|
||||||
|
bsFeatureFlagService.setFlag(flag.bsFlag, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly docService: DocService,
|
private readonly docService: DocService,
|
||||||
private readonly workspaceService: WorkspaceService
|
private readonly workspaceService: WorkspaceService,
|
||||||
|
private readonly featureFlagService: FeatureFlagService
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { type Framework } from '@toeverything/infra';
|
import { type Framework } from '@toeverything/infra';
|
||||||
|
|
||||||
import { DocScope, DocService } from '../doc';
|
import { DocScope, DocService } from '../doc';
|
||||||
|
import { FeatureFlagService } from '../feature-flag';
|
||||||
import { WorkspaceScope, WorkspaceService } from '../workspace';
|
import { WorkspaceScope, WorkspaceService } from '../workspace';
|
||||||
import { Editor } from './entities/editor';
|
import { Editor } from './entities/editor';
|
||||||
import { EditorScope } from './scopes/editor';
|
import { EditorScope } from './scopes/editor';
|
||||||
@@ -18,7 +19,7 @@ export function configureEditorModule(framework: Framework) {
|
|||||||
.scope(WorkspaceScope)
|
.scope(WorkspaceScope)
|
||||||
.scope(DocScope)
|
.scope(DocScope)
|
||||||
.service(EditorsService)
|
.service(EditorsService)
|
||||||
.entity(Editor, [DocService, WorkspaceService])
|
.entity(Editor, [DocService, WorkspaceService, FeatureFlagService])
|
||||||
.scope(EditorScope)
|
.scope(EditorScope)
|
||||||
.service(EditorService, [EditorScope]);
|
.service(EditorService, [EditorScope]);
|
||||||
}
|
}
|
||||||
@@ -2,27 +2,12 @@ import { OnEvent, Service } from '@toeverything/infra';
|
|||||||
import { distinctUntilChanged, skip } from 'rxjs';
|
import { distinctUntilChanged, skip } from 'rxjs';
|
||||||
|
|
||||||
import { ApplicationStarted } from '../../lifecycle';
|
import { ApplicationStarted } from '../../lifecycle';
|
||||||
import type { Workspace } from '../../workspace';
|
|
||||||
import { WorkspaceInitialized } from '../../workspace/events';
|
|
||||||
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(ApplicationStarted, e => e.setupRestartListener)
|
@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;
|
||||||
|
|
||||||
setupBlocksuiteEditorFlags(workspace: Workspace) {
|
|
||||||
for (const [key, flag] of Object.entries(AFFINE_FLAGS)) {
|
|
||||||
if (flag.category === 'blocksuite') {
|
|
||||||
const value = this.flags[key as keyof AFFINE_FLAGS].value;
|
|
||||||
if (value !== undefined) {
|
|
||||||
workspace.docCollection.awarenessStore.setFlag(flag.bsFlag, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setupRestartListener() {
|
setupRestartListener() {
|
||||||
this.flags.enable_ai.$.pipe(distinctUntilChanged(), skip(1)).subscribe(
|
this.flags.enable_ai.$.pipe(distinctUntilChanged(), skip(1)).subscribe(
|
||||||
() => {
|
() => {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { BlockSuiteFlags } from '@blocksuite/affine/global/types';
|
import type { BlockSuiteFlags } from '@blocksuite/affine/blocks';
|
||||||
|
|
||||||
type FeedbackType = 'discord' | 'email' | 'github';
|
type FeedbackType = 'discord' | 'email' | 'github';
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { SpecProvider } from '@blocksuite/affine/blocks';
|
||||||
import { type Disposable, Slot } from '@blocksuite/affine/global/utils';
|
import { type Disposable, Slot } from '@blocksuite/affine/global/utils';
|
||||||
import {
|
import {
|
||||||
type AwarenessStore,
|
type AwarenessStore,
|
||||||
@@ -283,13 +284,18 @@ export class DocImpl implements Doc {
|
|||||||
return this._docMap[readonlyKey].get(key) as Store;
|
return this._docMap[readonlyKey].get(key) as Store;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const storeExtensions = SpecProvider.getInstance().getSpec('store');
|
||||||
|
const extensionSet = new Set(
|
||||||
|
storeExtensions.value.concat(extensions ?? [])
|
||||||
|
);
|
||||||
|
|
||||||
const doc = new Store({
|
const doc = new Store({
|
||||||
doc: this,
|
doc: this,
|
||||||
schema: this.workspace.schema,
|
schema: this.workspace.schema,
|
||||||
readonly,
|
readonly,
|
||||||
query,
|
query,
|
||||||
provider,
|
provider,
|
||||||
extensions,
|
extensions: Array.from(extensionSet),
|
||||||
});
|
});
|
||||||
|
|
||||||
this._docMap[readonlyKey].set(key, doc);
|
this._docMap[readonlyKey].set(key, doc);
|
||||||
|
|||||||
@@ -34,22 +34,6 @@ type WorkspaceOptions = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const FLAGS_PRESET = {
|
const FLAGS_PRESET = {
|
||||||
enable_synced_doc_block: false,
|
|
||||||
enable_pie_menu: false,
|
|
||||||
enable_database_number_formatting: false,
|
|
||||||
enable_database_attachment_note: false,
|
|
||||||
enable_database_full_width: false,
|
|
||||||
enable_block_query: false,
|
|
||||||
enable_lasso_tool: false,
|
|
||||||
enable_edgeless_text: true,
|
|
||||||
enable_ai_onboarding: false,
|
|
||||||
enable_ai_chat_block: false,
|
|
||||||
enable_color_picker: false,
|
|
||||||
enable_mind_map_import: false,
|
|
||||||
enable_advanced_block_visibility: false,
|
|
||||||
enable_shape_shadow_blur: false,
|
|
||||||
enable_mobile_keyboard_toolbar: false,
|
|
||||||
enable_mobile_linked_doc_menu: false,
|
|
||||||
readonly: {},
|
readonly: {},
|
||||||
} satisfies BlockSuiteFlags;
|
} satisfies BlockSuiteFlags;
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user