mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-10 21:48:48 +08:00
chore: bump bs with new extension api (#8042)
This commit is contained in:
@@ -4,11 +4,12 @@ import type {
|
||||
EditorHost,
|
||||
TextSelection,
|
||||
} from '@blocksuite/block-std';
|
||||
import type {
|
||||
DocMode,
|
||||
EdgelessRootService,
|
||||
ImageSelection,
|
||||
PageRootService,
|
||||
import {
|
||||
type DocMode,
|
||||
DocModeProvider,
|
||||
type EdgelessRootService,
|
||||
type ImageSelection,
|
||||
type PageRootService,
|
||||
} from '@blocksuite/blocks';
|
||||
import { BlocksUtils, NoteDisplayMode } from '@blocksuite/blocks';
|
||||
import {
|
||||
@@ -176,8 +177,7 @@ function addAIChatBlock(
|
||||
}
|
||||
|
||||
export function promptDocTitle(host: EditorHost, autofill?: string) {
|
||||
const notification =
|
||||
host.std.spec.getService('affine:page').notificationService;
|
||||
const notification = host.std.getService('affine:page').notificationService;
|
||||
if (!notification) return Promise.resolve(undefined);
|
||||
|
||||
return notification.prompt({
|
||||
@@ -297,11 +297,12 @@ const SAVE_CHAT_TO_BLOCK_ACTION: ChatAction = {
|
||||
return false;
|
||||
}
|
||||
|
||||
const rootService = host.spec.getService('affine:page');
|
||||
const surfaceService = host.spec.getService('affine:surface');
|
||||
const rootService = host.std.getService('affine:page');
|
||||
const surfaceService = host.std.getService('affine:surface');
|
||||
if (!rootService || !surfaceService) return false;
|
||||
|
||||
const { docModeService, notificationService } = rootService;
|
||||
const { notificationService } = rootService;
|
||||
const docModeService = host.std.get(DocModeProvider);
|
||||
const { layer } = surfaceService;
|
||||
const curMode = docModeService.getMode();
|
||||
const viewportCenter = getViewportCenter(
|
||||
@@ -312,7 +313,7 @@ const SAVE_CHAT_TO_BLOCK_ACTION: ChatAction = {
|
||||
// If current mode is not edgeless, switch to edgeless mode first
|
||||
if (curMode !== 'edgeless') {
|
||||
// Set mode to edgeless
|
||||
docModeService.setMode('edgeless');
|
||||
docModeService.setMode('edgeless' as DocMode);
|
||||
// Notify user to switch to edgeless mode
|
||||
notificationService?.notify({
|
||||
title: 'Save chat to a block',
|
||||
@@ -382,7 +383,7 @@ const ADD_TO_EDGELESS_AS_NOTE = {
|
||||
handler: async (host: EditorHost, content: string) => {
|
||||
reportResponse('result:add-note');
|
||||
const { doc } = host;
|
||||
const service = host.spec.getService<EdgelessRootService>('affine:page');
|
||||
const service = host.std.getService<EdgelessRootService>('affine:page');
|
||||
const elements = service.selection.selectedElements;
|
||||
|
||||
const props: { displayMode: NoteDisplayMode; xywh?: SerializedXYWH } = {
|
||||
@@ -423,8 +424,8 @@ const CREATE_AS_DOC = {
|
||||
newDoc.addBlock('affine:surface', {}, rootId);
|
||||
const noteId = newDoc.addBlock('affine:note', {}, rootId);
|
||||
|
||||
host.spec.getService('affine:page').slots.docLinkClicked.emit({
|
||||
docId: newDoc.id,
|
||||
host.std.getService('affine:page').slots.docLinkClicked.emit({
|
||||
pageId: newDoc.id,
|
||||
});
|
||||
let complete = false;
|
||||
(function addContent() {
|
||||
@@ -460,8 +461,9 @@ const CREATE_AS_LINKED_DOC = {
|
||||
return false;
|
||||
}
|
||||
|
||||
const service = host.spec.getService<EdgelessRootService>('affine:page');
|
||||
const mode = service.docModeService.getMode();
|
||||
const service = host.std.getService<EdgelessRootService>('affine:page');
|
||||
const docModeService = host.std.get(DocModeProvider);
|
||||
const mode = docModeService.getMode();
|
||||
if (mode !== 'edgeless') {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { type EditorHost, WithDisposable } from '@blocksuite/block-std';
|
||||
import {
|
||||
type AIItemGroupConfig,
|
||||
DocMode,
|
||||
EdgelessRootService,
|
||||
scrollbarStyle,
|
||||
} from '@blocksuite/blocks';
|
||||
@@ -63,7 +64,7 @@ export class AskAIPanel extends WithDisposable(LitElement) {
|
||||
item.showWhen
|
||||
? item.showWhen(
|
||||
this.host.command.chain(),
|
||||
this._edgeless ? 'edgeless' : 'page',
|
||||
this._edgeless ? DocMode.Edgeless : DocMode.Page,
|
||||
this.host
|
||||
)
|
||||
: true
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ export class ChatActionList extends LitElement {
|
||||
}
|
||||
|
||||
private get _rootService() {
|
||||
return this.host.spec.getService('affine:page');
|
||||
return this.host.std.getService('affine:page');
|
||||
}
|
||||
|
||||
private get _currentTextSelection(): TextSelection | undefined {
|
||||
|
||||
@@ -73,7 +73,7 @@ export class ChatCopyMore extends WithDisposable(LitElement) {
|
||||
`;
|
||||
|
||||
private get _rootService() {
|
||||
return this.host.spec.getService('affine:page');
|
||||
return this.host.std.getService('affine:page');
|
||||
}
|
||||
|
||||
private get _selectionValue() {
|
||||
|
||||
@@ -12,7 +12,7 @@ import { Slice } from '@blocksuite/store';
|
||||
import { getMarkdownFromSlice } from './markdown-utils';
|
||||
|
||||
export const getRootService = (host: EditorHost) => {
|
||||
return host.std.spec.getService('affine:page');
|
||||
return host.std.getService('affine:page');
|
||||
};
|
||||
|
||||
export function getEdgelessRootFromEditor(editor: EditorHost) {
|
||||
@@ -24,7 +24,7 @@ export function getEdgelessRootFromEditor(editor: EditorHost) {
|
||||
return edgelessRoot;
|
||||
}
|
||||
export function getEdgelessService(editor: EditorHost) {
|
||||
const rootService = editor.std.spec.getService('affine:page');
|
||||
const rootService = editor.std.getService('affine:page');
|
||||
if (rootService instanceof EdgelessRootService) {
|
||||
return rootService;
|
||||
}
|
||||
|
||||
@@ -507,7 +507,7 @@ export const responses: {
|
||||
const contents = data.contents as unknown[];
|
||||
if (!contents) return;
|
||||
const images = data.images as { url: string; id: string }[][];
|
||||
const service = host.spec.getService<EdgelessRootService>('affine:page');
|
||||
const service = host.std.getService<EdgelessRootService>('affine:page');
|
||||
|
||||
(async function () {
|
||||
for (let i = 0; i < contents.length - 1; i++) {
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import type { BlockSpec } from '@blocksuite/block-std';
|
||||
import {
|
||||
BlockServiceWatcher,
|
||||
type ExtensionType,
|
||||
WidgetViewMapIdentifier,
|
||||
} from '@blocksuite/block-std';
|
||||
import {
|
||||
AFFINE_AI_PANEL_WIDGET,
|
||||
AFFINE_EDGELESS_COPILOT_WIDGET,
|
||||
@@ -11,8 +15,10 @@ import {
|
||||
EdgelessCopilotWidget,
|
||||
EdgelessElementToolbarWidget,
|
||||
EdgelessRootBlockSpec,
|
||||
edgelessRootWigetViewMap,
|
||||
ImageBlockSpec,
|
||||
PageRootBlockSpec,
|
||||
pageRootWidgetViewMap,
|
||||
ParagraphBlockService,
|
||||
ParagraphBlockSpec,
|
||||
} from '@blocksuite/blocks';
|
||||
@@ -30,56 +36,52 @@ import { setupImageToolbarEntry } from './entries/image-toolbar/setup-image-tool
|
||||
import { setupSlashMenuEntry } from './entries/slash-menu/setup-slash-menu';
|
||||
import { setupSpaceEntry } from './entries/space/setup-space';
|
||||
|
||||
export const AIPageRootBlockSpec: BlockSpec = {
|
||||
class AIPageRootWatcher extends BlockServiceWatcher {
|
||||
static override readonly flavour = 'affine:page';
|
||||
|
||||
override mounted() {
|
||||
super.mounted();
|
||||
this.blockService.specSlots.widgetConnected.on(view => {
|
||||
if (view.component instanceof AffineAIPanelWidget) {
|
||||
view.component.style.width = '630px';
|
||||
view.component.config = buildAIPanelConfig(view.component);
|
||||
setupSpaceEntry(view.component);
|
||||
}
|
||||
|
||||
if (view.component instanceof AffineFormatBarWidget) {
|
||||
setupFormatBarEntry(view.component);
|
||||
}
|
||||
|
||||
if (view.component instanceof AffineSlashMenuWidget) {
|
||||
setupSlashMenuEntry(view.component);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const AIPageRootBlockSpec: ExtensionType[] = [
|
||||
...PageRootBlockSpec,
|
||||
view: {
|
||||
...PageRootBlockSpec.view,
|
||||
widgets: {
|
||||
...PageRootBlockSpec.view.widgets,
|
||||
[AFFINE_AI_PANEL_WIDGET]: literal`${unsafeStatic(
|
||||
AFFINE_AI_PANEL_WIDGET
|
||||
)}`,
|
||||
AIPageRootWatcher,
|
||||
{
|
||||
setup: di => {
|
||||
di.override(WidgetViewMapIdentifier('affine:page'), () => {
|
||||
return {
|
||||
...pageRootWidgetViewMap,
|
||||
[AFFINE_AI_PANEL_WIDGET]: literal`${unsafeStatic(
|
||||
AFFINE_AI_PANEL_WIDGET
|
||||
)}`,
|
||||
};
|
||||
});
|
||||
},
|
||||
},
|
||||
setup: (slots, disposableGroup) => {
|
||||
PageRootBlockSpec.setup?.(slots, disposableGroup);
|
||||
disposableGroup.add(
|
||||
slots.widgetConnected.on(view => {
|
||||
if (view.component instanceof AffineAIPanelWidget) {
|
||||
view.component.style.width = '630px';
|
||||
view.component.config = buildAIPanelConfig(view.component);
|
||||
setupSpaceEntry(view.component);
|
||||
}
|
||||
];
|
||||
|
||||
if (view.component instanceof AffineFormatBarWidget) {
|
||||
setupFormatBarEntry(view.component);
|
||||
}
|
||||
class AIEdgelessRootWatcher extends BlockServiceWatcher {
|
||||
static override readonly flavour = 'affine:page';
|
||||
|
||||
if (view.component instanceof AffineSlashMenuWidget) {
|
||||
setupSlashMenuEntry(view.component);
|
||||
}
|
||||
})
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export const AIEdgelessRootBlockSpec: BlockSpec = {
|
||||
...EdgelessRootBlockSpec,
|
||||
view: {
|
||||
...EdgelessRootBlockSpec.view,
|
||||
widgets: {
|
||||
...EdgelessRootBlockSpec.view.widgets,
|
||||
[AFFINE_EDGELESS_COPILOT_WIDGET]: literal`${unsafeStatic(
|
||||
AFFINE_EDGELESS_COPILOT_WIDGET
|
||||
)}`,
|
||||
[AFFINE_AI_PANEL_WIDGET]: literal`${unsafeStatic(
|
||||
AFFINE_AI_PANEL_WIDGET
|
||||
)}`,
|
||||
},
|
||||
},
|
||||
setup(slots, disposableGroup) {
|
||||
EdgelessRootBlockSpec.setup?.(slots, disposableGroup);
|
||||
slots.widgetConnected.on(view => {
|
||||
override mounted() {
|
||||
super.mounted();
|
||||
this.blockService.specSlots.widgetConnected.on(view => {
|
||||
if (view.component instanceof AffineAIPanelWidget) {
|
||||
view.component.style.width = '430px';
|
||||
view.component.config = buildAIPanelConfig(view.component);
|
||||
@@ -102,55 +104,93 @@ export const AIEdgelessRootBlockSpec: BlockSpec = {
|
||||
setupSlashMenuEntry(view.component);
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export const AIParagraphBlockSpec: BlockSpec = {
|
||||
...ParagraphBlockSpec,
|
||||
setup(slots, disposableGroup) {
|
||||
ParagraphBlockSpec.setup?.(slots, disposableGroup);
|
||||
slots.mounted.on(({ service }) => {
|
||||
assertInstanceOf(service, ParagraphBlockService);
|
||||
service.placeholderGenerator = model => {
|
||||
if (model.type === 'text') {
|
||||
return "Type '/' for commands, 'space' for AI";
|
||||
}
|
||||
|
||||
const placeholders = {
|
||||
h1: 'Heading 1',
|
||||
h2: 'Heading 2',
|
||||
h3: 'Heading 3',
|
||||
h4: 'Heading 4',
|
||||
h5: 'Heading 5',
|
||||
h6: 'Heading 6',
|
||||
quote: '',
|
||||
export const AIEdgelessRootBlockSpec: ExtensionType[] = [
|
||||
...EdgelessRootBlockSpec,
|
||||
AIEdgelessRootWatcher,
|
||||
{
|
||||
setup: di => {
|
||||
di.override(WidgetViewMapIdentifier('affine:page'), () => {
|
||||
return {
|
||||
...edgelessRootWigetViewMap,
|
||||
[AFFINE_EDGELESS_COPILOT_WIDGET]: literal`${unsafeStatic(
|
||||
AFFINE_EDGELESS_COPILOT_WIDGET
|
||||
)}`,
|
||||
[AFFINE_AI_PANEL_WIDGET]: literal`${unsafeStatic(
|
||||
AFFINE_AI_PANEL_WIDGET
|
||||
)}`,
|
||||
};
|
||||
return placeholders[model.type];
|
||||
};
|
||||
});
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
];
|
||||
|
||||
export const AICodeBlockSpec: BlockSpec = {
|
||||
...CodeBlockSpec,
|
||||
setup(slots, disposableGroup) {
|
||||
CodeBlockSpec.setup?.(slots, disposableGroup);
|
||||
slots.widgetConnected.on(view => {
|
||||
class AIParagraphBlockWatcher extends BlockServiceWatcher {
|
||||
static override readonly flavour = 'affine:paragraph';
|
||||
|
||||
override mounted() {
|
||||
super.mounted();
|
||||
const service = this.blockService;
|
||||
assertInstanceOf(service, ParagraphBlockService);
|
||||
service.placeholderGenerator = model => {
|
||||
if (model.type === 'text') {
|
||||
return "Type '/' for commands, 'space' for AI";
|
||||
}
|
||||
|
||||
const placeholders = {
|
||||
h1: 'Heading 1',
|
||||
h2: 'Heading 2',
|
||||
h3: 'Heading 3',
|
||||
h4: 'Heading 4',
|
||||
h5: 'Heading 5',
|
||||
h6: 'Heading 6',
|
||||
quote: '',
|
||||
};
|
||||
return placeholders[model.type];
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export const AIParagraphBlockSpec: ExtensionType[] = [
|
||||
...ParagraphBlockSpec,
|
||||
AIParagraphBlockWatcher,
|
||||
];
|
||||
|
||||
class AICodeBlockWatcher extends BlockServiceWatcher {
|
||||
static override readonly flavour = 'affine:code';
|
||||
|
||||
override mounted() {
|
||||
super.mounted();
|
||||
const service = this.blockService;
|
||||
service.specSlots.widgetConnected.on(view => {
|
||||
if (view.component instanceof AffineCodeToolbarWidget) {
|
||||
setupCodeToolbarEntry(view.component);
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export const AIImageBlockSpec: BlockSpec = {
|
||||
...ImageBlockSpec,
|
||||
setup(slots, disposableGroup) {
|
||||
ImageBlockSpec.setup?.(slots, disposableGroup);
|
||||
slots.widgetConnected.on(view => {
|
||||
export const AICodeBlockSpec: ExtensionType[] = [
|
||||
...CodeBlockSpec,
|
||||
AICodeBlockWatcher,
|
||||
];
|
||||
|
||||
class AIImageBlockWatcher extends BlockServiceWatcher {
|
||||
static override readonly flavour = 'affine:image';
|
||||
|
||||
override mounted() {
|
||||
super.mounted();
|
||||
this.blockService.specSlots.widgetConnected.on(view => {
|
||||
if (view.component instanceof AffineImageToolbarWidget) {
|
||||
setupImageToolbarEntry(view.component);
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export const AIImageBlockSpec: ExtensionType[] = [
|
||||
...ImageBlockSpec,
|
||||
AIImageBlockWatcher,
|
||||
];
|
||||
|
||||
@@ -17,6 +17,7 @@ import type { BaseSelection, EditorHost } from '@blocksuite/block-std';
|
||||
import { ShadowlessElement, WithDisposable } from '@blocksuite/block-std';
|
||||
import {
|
||||
type AIError,
|
||||
DocModeProvider,
|
||||
isInsidePageEditor,
|
||||
PaymentRequiredError,
|
||||
UnauthorizedError,
|
||||
@@ -161,7 +162,7 @@ export class ChatPanelMessages extends WithDisposable(ShadowlessElement) {
|
||||
this._selectionValue = this.host.selection.value;
|
||||
})
|
||||
);
|
||||
const { docModeService } = this.host.spec.getService('affine:page');
|
||||
const docModeService = this.host.std.get(DocModeProvider);
|
||||
disposables.add(docModeService.onModeChange(() => this.requestUpdate()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ export class ChatPanel extends WithDisposable(ShadowlessElement) {
|
||||
|
||||
private readonly _cleanupHistories = async () => {
|
||||
const notification =
|
||||
this.host.std.spec.getService('affine:page').notificationService;
|
||||
this.host.std.getService('affine:page').notificationService;
|
||||
if (!notification) return;
|
||||
|
||||
if (
|
||||
|
||||
+28
-39
@@ -1,9 +1,6 @@
|
||||
import '../../_common/components/ask-ai-button';
|
||||
|
||||
import type {
|
||||
AffineCodeToolbarWidget,
|
||||
CodeBlockComponent,
|
||||
} from '@blocksuite/blocks';
|
||||
import type { AffineCodeToolbarWidget } from '@blocksuite/blocks';
|
||||
import { html } from 'lit';
|
||||
|
||||
const AICodeItemGroups = buildAICodeItemGroups();
|
||||
@@ -14,42 +11,34 @@ const buttonOptions: AskAIButtonOptions = {
|
||||
|
||||
import type { AskAIButtonOptions } from '../../_common/components/ask-ai-button';
|
||||
import { buildAICodeItemGroups } from '../../_common/config';
|
||||
import { AIStarIcon } from '../../_common/icons';
|
||||
|
||||
export function setupCodeToolbarEntry(codeToolbar: AffineCodeToolbarWidget) {
|
||||
const onAskAIClick = () => {
|
||||
const { host } = codeToolbar;
|
||||
const { selection } = host;
|
||||
const codeBlock = codeToolbar.block;
|
||||
selection.setGroup('note', [
|
||||
selection.create('block', { blockId: codeBlock.blockId }),
|
||||
]);
|
||||
};
|
||||
codeToolbar.setupDefaultConfig();
|
||||
codeToolbar.addItems(
|
||||
[
|
||||
{
|
||||
type: 'custom',
|
||||
name: 'Ask AI',
|
||||
tooltip: 'Ask AI',
|
||||
icon: AIStarIcon,
|
||||
showWhen: CodeBlockComponent => !CodeBlockComponent.doc.readonly,
|
||||
render(codeBlock: CodeBlockComponent, onClick?: () => void) {
|
||||
return html`<ask-ai-button
|
||||
class="code-toolbar-button ask-ai"
|
||||
.host=${codeBlock.host}
|
||||
.actionGroups=${AICodeItemGroups}
|
||||
.toggleType=${'click'}
|
||||
.options=${buttonOptions}
|
||||
@click=${(e: MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
onAskAIClick();
|
||||
onClick?.();
|
||||
}}
|
||||
></ask-ai-button>`;
|
||||
},
|
||||
codeToolbar.addPrimaryItems([
|
||||
{
|
||||
type: 'ask-ai',
|
||||
when: ({ doc }) => !doc.readonly,
|
||||
generate: ({ host, blockComponent }) => {
|
||||
return {
|
||||
action: () => {
|
||||
const { selection } = host;
|
||||
selection.setGroup('note', [
|
||||
selection.create('block', { blockId: blockComponent.blockId }),
|
||||
]);
|
||||
},
|
||||
render: item =>
|
||||
html`<ask-ai-button
|
||||
class="code-toolbar-button ask-ai"
|
||||
.host=${host}
|
||||
.actionGroups=${AICodeItemGroups}
|
||||
.toggleType=${'click'}
|
||||
.options=${buttonOptions}
|
||||
@click=${(e: MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
item.action();
|
||||
}}
|
||||
></ask-ai-button>`,
|
||||
};
|
||||
},
|
||||
],
|
||||
0
|
||||
);
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type {
|
||||
AIItemGroupConfig,
|
||||
DocMode,
|
||||
EdgelessCopilotWidget,
|
||||
EdgelessElementToolbarWidget,
|
||||
EdgelessRootBlockComponent,
|
||||
@@ -27,7 +28,7 @@ export function setupEdgelessElementToolbarEntry(
|
||||
const chain = edgeless.service.std.command.chain();
|
||||
const filteredGroups = edgelessActionGroups.reduce((pre, group) => {
|
||||
const filtered = group.items.filter(item =>
|
||||
item.showWhen?.(chain, 'edgeless', edgeless.host)
|
||||
item.showWhen?.(chain, 'edgeless' as DocMode, edgeless.host)
|
||||
);
|
||||
|
||||
if (filtered.length > 0) pre.push({ ...group, items: filtered });
|
||||
|
||||
+25
-29
@@ -1,9 +1,6 @@
|
||||
import '../../_common/components/ask-ai-button';
|
||||
|
||||
import type {
|
||||
AffineImageToolbarWidget,
|
||||
ImageBlockComponent,
|
||||
} from '@blocksuite/blocks';
|
||||
import type { AffineImageToolbarWidget } from '@blocksuite/blocks';
|
||||
import { html } from 'lit';
|
||||
|
||||
import type { AskAIButtonOptions } from '../../_common/components/ask-ai-button';
|
||||
@@ -17,34 +14,33 @@ const buttonOptions: AskAIButtonOptions = {
|
||||
};
|
||||
|
||||
export function setupImageToolbarEntry(imageToolbar: AffineImageToolbarWidget) {
|
||||
const onAskAIClick = () => {
|
||||
const { host } = imageToolbar;
|
||||
const { selection } = host;
|
||||
const imageBlock = imageToolbar.block;
|
||||
selection.setGroup('note', [
|
||||
selection.create('image', { blockId: imageBlock.blockId }),
|
||||
]);
|
||||
};
|
||||
imageToolbar.buildDefaultConfig();
|
||||
imageToolbar.addConfigItems(
|
||||
imageToolbar.addPrimaryItems(
|
||||
[
|
||||
{
|
||||
type: 'custom',
|
||||
render(imageBlock: ImageBlockComponent, onClick?: () => void) {
|
||||
return html`<ask-ai-button
|
||||
class="image-toolbar-button ask-ai"
|
||||
.host=${imageBlock.host}
|
||||
.actionGroups=${AIImageItemGroups}
|
||||
.toggleType=${'click'}
|
||||
.options=${buttonOptions}
|
||||
@click=${(e: MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
onAskAIClick();
|
||||
onClick?.();
|
||||
}}
|
||||
></ask-ai-button>`;
|
||||
type: 'ask-ai',
|
||||
when: ({ doc }) => !doc.readonly,
|
||||
generate: ({ host, blockComponent }) => {
|
||||
return {
|
||||
action: () => {
|
||||
const { selection } = host;
|
||||
selection.setGroup('note', [
|
||||
selection.create('image', { blockId: blockComponent.blockId }),
|
||||
]);
|
||||
},
|
||||
render: item =>
|
||||
html`<ask-ai-button
|
||||
class="image-toolbar-button ask-ai"
|
||||
.host=${host}
|
||||
.actionGroups=${AIImageItemGroups}
|
||||
.toggleType=${'click'}
|
||||
.options=${buttonOptions}
|
||||
@click=${(e: MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
item.action();
|
||||
}}
|
||||
></ask-ai-button>`,
|
||||
};
|
||||
},
|
||||
showWhen: imageBlockComponent => !imageBlockComponent.doc.readonly,
|
||||
},
|
||||
],
|
||||
0
|
||||
|
||||
+10
-10
@@ -1,10 +1,11 @@
|
||||
import type {
|
||||
AffineAIPanelWidget,
|
||||
AffineSlashMenuActionItem,
|
||||
AffineSlashMenuContext,
|
||||
AffineSlashMenuItem,
|
||||
AffineSlashSubMenu,
|
||||
AIItemConfig,
|
||||
import {
|
||||
type AffineAIPanelWidget,
|
||||
type AffineSlashMenuActionItem,
|
||||
type AffineSlashMenuContext,
|
||||
type AffineSlashMenuItem,
|
||||
type AffineSlashSubMenu,
|
||||
type AIItemConfig,
|
||||
DocModeProvider,
|
||||
} from '@blocksuite/blocks';
|
||||
import {
|
||||
AFFINE_AI_PANEL_WIDGET,
|
||||
@@ -38,9 +39,8 @@ export function setupSlashMenuEntry(slashMenu: AffineSlashMenuWidget) {
|
||||
if (affineAIPanelWidget === null) return false;
|
||||
|
||||
const chain = rootComponent.host.command.chain();
|
||||
const editorMode = rootComponent.service.docModeService.getMode(
|
||||
rootComponent.doc.id
|
||||
);
|
||||
const docModeService = rootComponent.std.get(DocModeProvider);
|
||||
const editorMode = docModeService.getMode(rootComponent.doc.id);
|
||||
|
||||
return item?.showWhen?.(chain, editorMode, rootComponent.host) ?? true;
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { EditorHost } from '@blocksuite/block-std';
|
||||
import { BlockStdScope, type EditorHost } from '@blocksuite/block-std';
|
||||
import { WithDisposable } from '@blocksuite/block-std';
|
||||
import {
|
||||
type AffineAIPanelWidgetConfig,
|
||||
@@ -207,7 +207,10 @@ export class AISlidesRenderer extends WithDisposable(LitElement) {
|
||||
class="edgeless-container affine-edgeless-viewport"
|
||||
${ref(this._editorContainer)}
|
||||
>
|
||||
${this.host.renderSpecPortal(this._doc, EdgelessEditorBlockSpecs)}
|
||||
${new BlockStdScope({
|
||||
doc: this._doc,
|
||||
extensions: EdgelessEditorBlockSpecs,
|
||||
}).render()}
|
||||
</div>
|
||||
<div class="mask"></div>
|
||||
</div>`;
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import { type EditorHost, WithDisposable } from '@blocksuite/block-std';
|
||||
import type {
|
||||
AffineAIPanelState,
|
||||
AffineAIPanelWidgetConfig,
|
||||
import {
|
||||
BlockStdScope,
|
||||
type EditorHost,
|
||||
WithDisposable,
|
||||
} from '@blocksuite/block-std';
|
||||
import {
|
||||
type AffineAIPanelState,
|
||||
type AffineAIPanelWidgetConfig,
|
||||
} from '@blocksuite/blocks';
|
||||
import {
|
||||
CodeBlockComponent,
|
||||
@@ -271,7 +275,10 @@ export class AIAnswerText extends WithDisposable(LitElement) {
|
||||
${keyed(
|
||||
this._doc,
|
||||
html`<div class="ai-answer-text-editor affine-page-viewport">
|
||||
${this.host.renderSpecPortal(this._doc, CustomPageEditorBlockSpecs)}
|
||||
${new BlockStdScope({
|
||||
doc: this._doc,
|
||||
extensions: CustomPageEditorBlockSpecs,
|
||||
}).render()}
|
||||
</div>`
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
type AIError,
|
||||
CanvasElementType,
|
||||
ConnectorMode,
|
||||
DocModeProvider,
|
||||
type EdgelessRootService,
|
||||
} from '@blocksuite/blocks';
|
||||
import {
|
||||
@@ -37,11 +38,11 @@ export class AIChatBlockPeekView extends LitElement {
|
||||
static override styles = PeekViewStyles;
|
||||
|
||||
private get _rootService() {
|
||||
return this.host.spec.getService('affine:page');
|
||||
return this.host.std.getService('affine:page');
|
||||
}
|
||||
|
||||
private get _modeService() {
|
||||
return this._rootService.docModeService;
|
||||
return this.host.std.get(DocModeProvider);
|
||||
}
|
||||
|
||||
private get parentSessionId() {
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
} from './template';
|
||||
|
||||
export const PPTBuilder = (host: EditorHost) => {
|
||||
const service = host.spec.getService<EdgelessRootService>('affine:page');
|
||||
const service = host.std.getService<EdgelessRootService>('affine:page');
|
||||
const docs: PPTDoc[] = [];
|
||||
const contents: unknown[] = [];
|
||||
const allImages: TemplateImage[][] = [];
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
import {
|
||||
BlockFlavourIdentifier,
|
||||
BlockServiceIdentifier,
|
||||
BlockViewIdentifier,
|
||||
type ExtensionType,
|
||||
StdIdentifier,
|
||||
} from '@blocksuite/block-std';
|
||||
import { PageEditorBlockSpecs, PageRootService } from '@blocksuite/blocks';
|
||||
import { literal } from 'lit/static-html.js';
|
||||
|
||||
@@ -8,15 +15,19 @@ class CustomPageRootService extends PageRootService {
|
||||
override loadFonts() {}
|
||||
}
|
||||
|
||||
export const CustomPageEditorBlockSpecs = PageEditorBlockSpecs.map(spec => {
|
||||
if (spec.schema.model.flavour === 'affine:page') {
|
||||
return {
|
||||
...spec,
|
||||
service: CustomPageRootService,
|
||||
view: {
|
||||
component: literal`affine-page-root`,
|
||||
},
|
||||
};
|
||||
}
|
||||
return spec;
|
||||
});
|
||||
export const CustomPageEditorBlockSpecs: ExtensionType[] = [
|
||||
...PageEditorBlockSpecs,
|
||||
{
|
||||
setup: di => {
|
||||
di.override(
|
||||
BlockServiceIdentifier('affine:page'),
|
||||
CustomPageRootService,
|
||||
[StdIdentifier, BlockFlavourIdentifier('affine:page')]
|
||||
);
|
||||
di.override(
|
||||
BlockViewIdentifier('affine:page'),
|
||||
() => literal`affine-page-root`
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -40,7 +40,7 @@ export function isMindmapChild(ele: BlockSuite.EdgelessModel) {
|
||||
}
|
||||
|
||||
export function getService(host: EditorHost) {
|
||||
const edgelessService = host.spec.getService(
|
||||
const edgelessService = host.std.getService(
|
||||
'affine:page'
|
||||
) as EdgelessRootService;
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import { getEdgelessCopilotWidget, getService } from './edgeless';
|
||||
import { getContentFromSlice } from './markdown-utils';
|
||||
|
||||
export const getRootService = (host: EditorHost) => {
|
||||
return host.std.spec.getService('affine:page');
|
||||
return host.std.getService('affine:page');
|
||||
};
|
||||
|
||||
export function getEdgelessRootFromEditor(editor: EditorHost) {
|
||||
@@ -30,7 +30,7 @@ export function getEdgelessRootFromEditor(editor: EditorHost) {
|
||||
return edgelessRoot;
|
||||
}
|
||||
export function getEdgelessService(editor: EditorHost) {
|
||||
const rootService = editor.std.spec.getService('affine:page');
|
||||
const rootService = editor.std.getService('affine:page');
|
||||
if (rootService instanceof EdgelessRootService) {
|
||||
return rootService;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user