fix(editor): subscribe docLinkClicked event for text renderer (#12406)

Closes: [BS-3520](https://linear.app/affine-design/issue/BS-3520/chat-panel-doc-citation-点击没有响应)

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Enhanced citation cards to support double-click actions for improved interaction.
  - Added the ability to open a preview view when clicking document links within rendered text content.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
donteatfriedrice
2025-05-21 07:34:28 +00:00
parent 928892c5b4
commit 20e93543e2
2 changed files with 35 additions and 2 deletions

View File

@@ -2,8 +2,10 @@ import { createReactComponentFromLit } from '@affine/component';
import { getStoreManager } from '@affine/core/blocksuite/manager/store';
import { getViewManager } from '@affine/core/blocksuite/manager/view';
import type { FeatureFlagService } from '@affine/core/modules/feature-flag';
import { PeekViewProvider } from '@blocksuite/affine/components/peek';
import { Container, type ServiceProvider } from '@blocksuite/affine/global/di';
import { WithDisposable } from '@blocksuite/affine/global/lit';
import { RefNodeSlotsProvider } from '@blocksuite/affine/inlines/reference';
import {
codeBlockWrapMiddleware,
defaultImageProxyMiddleware,
@@ -34,6 +36,7 @@ import { classMap } from 'lit/directives/class-map.js';
import { keyed } from 'lit/directives/keyed.js';
import { literal } from 'lit/static-html.js';
import React from 'react';
import { filter } from 'rxjs/operators';
import { markDownToDoc } from '../../utils';
import type {
@@ -240,6 +243,28 @@ export class TextRenderer extends WithDisposable(ShadowlessElement) {
private _timer?: ReturnType<typeof setInterval> | null = null;
private readonly _subscribeDocLinkClicked = () => {
const refNodeSlots = this.host?.std.getOptional(RefNodeSlotsProvider);
if (!refNodeSlots) return;
this.disposables.add(
refNodeSlots.docLinkClicked
.pipe(
filter(
options => !!this._previewHost && options.host === this._previewHost
)
)
.subscribe(options => {
// Open the doc in center peek
this.host?.std
.getOptional(PeekViewProvider)
?.peek({
docId: options.pageId,
})
.catch(console.error);
})
);
};
private readonly _updateDoc = () => {
if (this._answers.length > 0) {
const latestAnswer = this._answers.pop();
@@ -311,6 +336,10 @@ export class TextRenderer extends WithDisposable(ShadowlessElement) {
}
}
override firstUpdated() {
this._subscribeDocLinkClicked();
}
private disposeDoc() {
this._doc?.dispose();
this._doc?.workspace.dispose();
@@ -382,6 +411,9 @@ export class TextRenderer extends WithDisposable(ShadowlessElement) {
@query('.text-renderer-container')
private accessor _container!: HTMLDivElement;
@query('.text-renderer-container editor-host')
private accessor _previewHost: EditorHost | null = null;
@property({ attribute: false })
accessor answer!: string;