mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-15 05:37:32 +00:00
refactor(editor): use extension level config (#12110)
Closes: BS-3396 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced structured and validated configuration options for database and linked document views, allowing for more flexible and reliable customization. - Enhanced view manager to conditionally enable AI-related paragraph placeholders and database/linked document extensions based on configuration. - **Chores** - Updated dependencies to include the latest version of the Zod validation library. - Simplified and consolidated internal configuration and registration logic for AI and widget-related extensions. - **Refactor** - Streamlined configuration types and removed unused or redundant configuration utilities to improve maintainability. - Improved robustness of linked widget configuration retrieval to handle optional service availability gracefully. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -27,62 +27,12 @@ import type { InlineRange } from '@blocksuite/std/inline';
|
||||
import type { TemplateResult } from 'lit';
|
||||
|
||||
import { showImportModal } from './import-doc/index.js';
|
||||
import type { LinkedDocViewExtensionOptions } from './view';
|
||||
|
||||
export interface LinkedWidgetConfig {
|
||||
/**
|
||||
* The first item of the trigger keys will be the primary key
|
||||
* e.g. @, [[
|
||||
*/
|
||||
triggerKeys: [string, ...string[]];
|
||||
/**
|
||||
* Convert trigger key to primary key (the first item of the trigger keys)
|
||||
* [[ -> @
|
||||
*/
|
||||
convertTriggerKey: boolean;
|
||||
ignoreBlockTypes: string[];
|
||||
ignoreSelector: string;
|
||||
getMenus: (
|
||||
query: string,
|
||||
abort: () => void,
|
||||
editorHost: EditorHost,
|
||||
inlineEditor: AffineInlineEditor,
|
||||
abortSignal: AbortSignal
|
||||
) => Promise<LinkedMenuGroup[]> | LinkedMenuGroup[];
|
||||
|
||||
/**
|
||||
* Auto focused item
|
||||
*
|
||||
* Will be called when the menu is
|
||||
* - opened
|
||||
* - query changed
|
||||
* - menu group or its items changed
|
||||
*
|
||||
* If the return value is not null, no action will be taken.
|
||||
*/
|
||||
autoFocusedItemKey?: (
|
||||
menus: LinkedMenuGroup[],
|
||||
query: string,
|
||||
currentActiveKey: string | null,
|
||||
editorHost: EditorHost,
|
||||
inlineEditor: AffineInlineEditor
|
||||
) => string | null;
|
||||
|
||||
mobile: {
|
||||
/**
|
||||
* The linked doc menu widget will scroll the container to make sure the input cursor is visible in viewport.
|
||||
* It accepts a selector string, HTMLElement or Window
|
||||
*
|
||||
* @default getViewportElement(editorHost) this is the scrollable container in playground
|
||||
*/
|
||||
scrollContainer?: string | HTMLElement | Window;
|
||||
/**
|
||||
* The offset between the top of viewport and the input cursor
|
||||
*
|
||||
* @default 46 The height of header in playground
|
||||
*/
|
||||
scrollTopOffset?: number | (() => number);
|
||||
};
|
||||
}
|
||||
export type LinkedWidgetConfig = Required<
|
||||
Omit<LinkedDocViewExtensionOptions, 'autoFocusedItemKey'>
|
||||
> &
|
||||
Pick<LinkedDocViewExtensionOptions, 'autoFocusedItemKey'>;
|
||||
|
||||
export type LinkedMenuItem = {
|
||||
key: string;
|
||||
@@ -269,7 +219,6 @@ export function getMenus(
|
||||
}
|
||||
|
||||
export const LinkedWidgetUtils = {
|
||||
createLinkedDocMenuGroup,
|
||||
createNewDocMenuGroup,
|
||||
insertLinkedNode,
|
||||
};
|
||||
|
||||
@@ -2,20 +2,82 @@ import {
|
||||
type ViewExtensionContext,
|
||||
ViewExtensionProvider,
|
||||
} from '@blocksuite/affine-ext-loader';
|
||||
import type { AffineInlineEditor } from '@blocksuite/affine-shared/types';
|
||||
import type { EditorHost } from '@blocksuite/std';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { type LinkedMenuGroup, LinkedWidgetConfigExtension } from './config';
|
||||
import { effects } from './effects';
|
||||
import { linkedDocWidget } from './widget';
|
||||
|
||||
export class LinkedDocViewExtension extends ViewExtensionProvider {
|
||||
const optionsSchema = z.object({
|
||||
triggerKeys: z.optional(z.tuple([z.string()]).rest(z.string())),
|
||||
convertTriggerKey: z.boolean().optional(),
|
||||
ignoreBlockTypes: z.array(z.string()).optional(),
|
||||
ignoreSelector: z.string().optional(),
|
||||
getMenus: z.optional(
|
||||
z
|
||||
.function()
|
||||
.args(
|
||||
z.string(),
|
||||
z.function().returns(z.void()),
|
||||
z.custom<EditorHost>(),
|
||||
z.custom<AffineInlineEditor>(),
|
||||
z.instanceof(AbortSignal)
|
||||
)
|
||||
.returns(
|
||||
z.union([
|
||||
z.promise(z.array(z.custom<LinkedMenuGroup>())),
|
||||
z.array(z.custom<LinkedMenuGroup>()),
|
||||
])
|
||||
)
|
||||
),
|
||||
|
||||
autoFocusedItemKey: z.optional(
|
||||
z
|
||||
.function()
|
||||
.args(
|
||||
z.array(z.custom<LinkedMenuGroup>()),
|
||||
z.string(),
|
||||
z.string().nullable(),
|
||||
z.custom<EditorHost>(),
|
||||
z.custom<AffineInlineEditor>()
|
||||
)
|
||||
.returns(z.string().nullable())
|
||||
),
|
||||
|
||||
mobile: z
|
||||
.object({
|
||||
scrollContainer: z.optional(
|
||||
z.union([z.string(), z.instanceof(HTMLElement), z.custom<Window>()])
|
||||
),
|
||||
scrollTopOffset: z.optional(
|
||||
z.union([z.number(), z.function().returns(z.number())])
|
||||
),
|
||||
})
|
||||
.optional(),
|
||||
});
|
||||
|
||||
export type LinkedDocViewExtensionOptions = z.infer<typeof optionsSchema>;
|
||||
|
||||
export class LinkedDocViewExtension extends ViewExtensionProvider<LinkedDocViewExtensionOptions> {
|
||||
override name = 'affine-linked-doc-widget';
|
||||
|
||||
override schema = optionsSchema;
|
||||
|
||||
override effect() {
|
||||
super.effect();
|
||||
effects();
|
||||
}
|
||||
|
||||
override setup(context: ViewExtensionContext) {
|
||||
override setup(
|
||||
context: ViewExtensionContext,
|
||||
options?: LinkedDocViewExtensionOptions
|
||||
) {
|
||||
super.setup(context);
|
||||
context.register(linkedDocWidget);
|
||||
if (options) {
|
||||
context.register(LinkedWidgetConfigExtension(options));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user