mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-10 13:38:49 +08:00
feat(core): block diff ui
This commit is contained in:
@@ -28,6 +28,7 @@ import { query, state } from 'lit/decorators.js';
|
|||||||
import { classMap } from 'lit/directives/class-map.js';
|
import { classMap } from 'lit/directives/class-map.js';
|
||||||
import { styleMap } from 'lit/directives/style-map.js';
|
import { styleMap } from 'lit/directives/style-map.js';
|
||||||
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
||||||
|
import { repeat } from 'lit/directives/repeat.js';
|
||||||
|
|
||||||
import { ParagraphBlockConfigExtension } from './paragraph-block-config.js';
|
import { ParagraphBlockConfigExtension } from './paragraph-block-config.js';
|
||||||
import { paragraphBlockStyles } from './styles.js';
|
import { paragraphBlockStyles } from './styles.js';
|
||||||
@@ -227,6 +228,12 @@ export class ParagraphBlockComponent extends CaptionedBlockComponent<ParagraphBl
|
|||||||
}
|
}
|
||||||
|
|
||||||
override renderBlock(): TemplateResult<1> {
|
override renderBlock(): TemplateResult<1> {
|
||||||
|
const widgets = html`${repeat(
|
||||||
|
Object.entries(this.widgets),
|
||||||
|
([id]) => id,
|
||||||
|
([_, widget]) => widget
|
||||||
|
)}`;
|
||||||
|
|
||||||
const { type$ } = this.model.props;
|
const { type$ } = this.model.props;
|
||||||
const collapsed = this.store.readonly
|
const collapsed = this.store.readonly
|
||||||
? this._readonlyCollapsed
|
? this._readonlyCollapsed
|
||||||
@@ -341,6 +348,7 @@ export class ParagraphBlockComponent extends CaptionedBlockComponent<ParagraphBl
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
${children}
|
${children}
|
||||||
|
${widgets}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ import {
|
|||||||
} from './widgets/ai-panel/components';
|
} from './widgets/ai-panel/components';
|
||||||
import { AIFinishTip } from './widgets/ai-panel/components/finish-tip';
|
import { AIFinishTip } from './widgets/ai-panel/components/finish-tip';
|
||||||
import { GeneratingPlaceholder } from './widgets/ai-panel/components/generating-placeholder';
|
import { GeneratingPlaceholder } from './widgets/ai-panel/components/generating-placeholder';
|
||||||
|
import { AFFINE_BLOCK_DIFF_WIDGET, AffineBlockDiffWidget } from './widgets/block-diff/widget';
|
||||||
import {
|
import {
|
||||||
AFFINE_EDGELESS_COPILOT_WIDGET,
|
AFFINE_EDGELESS_COPILOT_WIDGET,
|
||||||
EdgelessCopilotWidget,
|
EdgelessCopilotWidget,
|
||||||
@@ -158,6 +159,7 @@ export function registerAIEffects() {
|
|||||||
|
|
||||||
customElements.define(AFFINE_AI_PANEL_WIDGET, AffineAIPanelWidget);
|
customElements.define(AFFINE_AI_PANEL_WIDGET, AffineAIPanelWidget);
|
||||||
customElements.define(AFFINE_EDGELESS_COPILOT_WIDGET, EdgelessCopilotWidget);
|
customElements.define(AFFINE_EDGELESS_COPILOT_WIDGET, EdgelessCopilotWidget);
|
||||||
|
customElements.define(AFFINE_BLOCK_DIFF_WIDGET, AffineBlockDiffWidget);
|
||||||
|
|
||||||
customElements.define('edgeless-copilot-panel', EdgelessCopilotPanel);
|
customElements.define('edgeless-copilot-panel', EdgelessCopilotPanel);
|
||||||
customElements.define(
|
customElements.define(
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import { createIdentifier } from '@blocksuite/global/di';
|
||||||
|
import type { PatchOp } from '../utils/apply-model/markdown-diff';
|
||||||
|
|
||||||
|
interface DiffMap {
|
||||||
|
// removed blocks
|
||||||
|
deletes: string[];
|
||||||
|
// inserted blocks
|
||||||
|
// key is the start block id, value is the blocks(markdowns) inserted
|
||||||
|
inserts: Record<string, string[]>;
|
||||||
|
// updated blocks
|
||||||
|
// key is the block id, value is the block(markdown)
|
||||||
|
updates: Record<string, string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BlockDiffService {
|
||||||
|
/**
|
||||||
|
* Set the patches to the block diffs
|
||||||
|
* @param patches - The patches to set.
|
||||||
|
* @returns The diff map.
|
||||||
|
*/
|
||||||
|
setPatches(patches: PatchOp[]): DiffMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const BlockDiffService = createIdentifier<BlockDiffService>(
|
||||||
|
'AffineBlockDiffService'
|
||||||
|
);
|
||||||
|
|
||||||
|
export class BlockDiffServiceImpl implements BlockDiffService {
|
||||||
|
setPatches(patches: PatchOp[]): DiffMap {
|
||||||
|
const diffMap: DiffMap = {
|
||||||
|
deletes: [],
|
||||||
|
inserts: {},
|
||||||
|
updates: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const patch of patches) {
|
||||||
|
switch (patch.op) {
|
||||||
|
case 'delete':
|
||||||
|
diffMap.deletes.push(patch.block_id);
|
||||||
|
break;
|
||||||
|
case 'insert_at':
|
||||||
|
diffMap.inserts[patch.new_block.id] = [patch.new_block.content];
|
||||||
|
break;
|
||||||
|
case 'replace':
|
||||||
|
diffMap.updates[patch.block_id] = patch.new_content;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return diffMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -505,6 +505,7 @@ export class AffineAIPanelWidget extends WidgetComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override render() {
|
override render() {
|
||||||
|
console.log
|
||||||
if (this.state === 'hidden') {
|
if (this.state === 'hidden') {
|
||||||
return nothing;
|
return nothing;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { WidgetComponent, WidgetViewExtension } from '@blocksuite/affine/std';
|
||||||
|
import { html } from 'lit';
|
||||||
|
import { literal, unsafeStatic } from 'lit/static-html.js';
|
||||||
|
|
||||||
|
export const AFFINE_BLOCK_DIFF_WIDGET = 'affine-block-diff-widget';
|
||||||
|
|
||||||
|
export class AffineBlockDiffWidget extends WidgetComponent {
|
||||||
|
override render() {
|
||||||
|
const attached = this.block?.blockId;
|
||||||
|
return html`<div
|
||||||
|
class="ai-panel-container"
|
||||||
|
data-testid="ai-panel-container"
|
||||||
|
>
|
||||||
|
<h1>Block Diff</h1>
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const blockDiffWidget = WidgetViewExtension(
|
||||||
|
'affine:paragraph',
|
||||||
|
AFFINE_BLOCK_DIFF_WIDGET,
|
||||||
|
literal`${unsafeStatic(AFFINE_BLOCK_DIFF_WIDGET)}`
|
||||||
|
);
|
||||||
@@ -20,6 +20,7 @@ import { FrameworkProvider } from '@toeverything/infra';
|
|||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { EdgelessClipboardAIChatConfig } from './edgeless-clipboard';
|
import { EdgelessClipboardAIChatConfig } from './edgeless-clipboard';
|
||||||
|
import { blockDiffWidget } from '../../ai/widgets/block-diff/widget';
|
||||||
|
|
||||||
const optionsSchema = z.object({
|
const optionsSchema = z.object({
|
||||||
enable: z.boolean().optional(),
|
enable: z.boolean().optional(),
|
||||||
@@ -50,6 +51,8 @@ export class AIViewExtension extends ViewExtensionProvider<AIViewOptions> {
|
|||||||
config: imageToolbarAIEntryConfig(),
|
config: imageToolbarAIEntryConfig(),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
if (context.scope === 'edgeless' || context.scope === 'page') {
|
if (context.scope === 'edgeless' || context.scope === 'page') {
|
||||||
context.register([
|
context.register([
|
||||||
aiPanelWidget,
|
aiPanelWidget,
|
||||||
@@ -73,6 +76,7 @@ export class AIViewExtension extends ViewExtensionProvider<AIViewOptions> {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
if (context.scope === 'page') {
|
if (context.scope === 'page') {
|
||||||
|
context.register(blockDiffWidget);
|
||||||
context.register(getAIPageRootWatcher(framework));
|
context.register(getAIPageRootWatcher(framework));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user