chore(editor): add event track for html preview (#12592)

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

- **New Features**
  - Enhanced tracking for code block interactions, including language selection and preview toggling.
  - Improved error reporting for HTML block preview failures, providing better visibility into issues.
- **Bug Fixes**
  - Added explicit feedback and tracking when cross-origin isolation is not supported during code block preview setup.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Flrande
2025-05-28 10:08:19 +00:00
parent 9e5d132bd0
commit f610d7b8af
7 changed files with 63 additions and 3 deletions
@@ -4,6 +4,10 @@ import {
showPopFilterableList, showPopFilterableList,
} from '@blocksuite/affine-components/filterable-list'; } from '@blocksuite/affine-components/filterable-list';
import { ArrowDownIcon } from '@blocksuite/affine-components/icons'; import { ArrowDownIcon } from '@blocksuite/affine-components/icons';
import {
DocModeProvider,
TelemetryProvider,
} from '@blocksuite/affine-shared/services';
import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme'; import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme';
import { SignalWatcher, WithDisposable } from '@blocksuite/global/lit'; import { SignalWatcher, WithDisposable } from '@blocksuite/global/lit';
import { noop } from '@blocksuite/global/utils'; import { noop } from '@blocksuite/global/utils';
@@ -73,6 +77,18 @@ export class LanguageListButton extends WithDisposable(
this.blockComponent.store.transact(() => { this.blockComponent.store.transact(() => {
this.blockComponent.model.props.language$.value = item.name; this.blockComponent.model.props.language$.value = item.name;
}); });
const std = this.blockComponent.std;
const mode =
std.getOptional(DocModeProvider)?.getEditorMode() ?? 'page';
const telemetryService = std.getOptional(TelemetryProvider);
if (!telemetryService) return;
telemetryService.track('codeBlockLanguageSelect', {
page: mode,
segment: 'code block',
module: 'language selector',
control: item.name,
});
}, },
active: item => item.name === this.blockComponent.model.props.language, active: item => item.name === this.blockComponent.model.props.language,
items: this._sortedBundledLanguages, items: this._sortedBundledLanguages,
@@ -1,3 +1,7 @@
import {
DocModeProvider,
TelemetryProvider,
} from '@blocksuite/affine-shared/services';
import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme'; import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme';
import { SignalWatcher, WithDisposable } from '@blocksuite/global/lit'; import { SignalWatcher, WithDisposable } from '@blocksuite/global/lit';
import { css, html, LitElement, nothing } from 'lit'; import { css, html, LitElement, nothing } from 'lit';
@@ -55,6 +59,17 @@ export class PreviewButton extends WithDisposable(SignalWatcher(LitElement)) {
this.blockComponent.store.updateBlock(this.blockComponent.model, { this.blockComponent.store.updateBlock(this.blockComponent.model, {
preview: value, preview: value,
}); });
const std = this.blockComponent.std;
const mode = std.getOptional(DocModeProvider)?.getEditorMode() ?? 'page';
const telemetryService = std.getOptional(TelemetryProvider);
if (!telemetryService) return;
telemetryService.track('htmlBlockTogglePreview', {
page: mode,
segment: 'code block',
module: 'code toolbar container',
control: 'preview toggle button',
});
}; };
get preview() { get preview() {
@@ -0,0 +1,8 @@
import type { TelemetryEvent } from './types.js';
export type CodeBlockEventType =
| 'codeBlockLanguageSelect'
| 'htmlBlockTogglePreview'
| 'htmlBlockPreviewFailed';
export type CodeBlockEvents = Record<CodeBlockEventType, TelemetryEvent>;
@@ -1,6 +1,7 @@
import { createIdentifier } from '@blocksuite/global/di'; import { createIdentifier } from '@blocksuite/global/di';
import type { ExtensionType } from '@blocksuite/store'; import type { ExtensionType } from '@blocksuite/store';
import type { CodeBlockEvents } from './code-block.js';
import type { OutDatabaseAllEvents } from './database.js'; import type { OutDatabaseAllEvents } from './database.js';
import type { LinkToolbarEvents } from './link.js'; import type { LinkToolbarEvents } from './link.js';
import type { NoteEvents } from './note.js'; import type { NoteEvents } from './note.js';
@@ -26,6 +27,7 @@ import type {
export type TelemetryEventMap = OutDatabaseAllEvents & export type TelemetryEventMap = OutDatabaseAllEvents &
LinkToolbarEvents & LinkToolbarEvents &
SlashMenuEvents & SlashMenuEvents &
CodeBlockEvents &
NoteEvents & { NoteEvents & {
DocCreated: DocCreatedEvent; DocCreated: DocCreatedEvent;
Link: TelemetryEvent; Link: TelemetryEvent;
@@ -1,3 +1,4 @@
import track from '@affine/track';
import { CodeBlockPreviewExtension } from '@blocksuite/affine/blocks/code'; import { CodeBlockPreviewExtension } from '@blocksuite/affine/blocks/code';
import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit'; import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit';
import type { CodeBlockModel } from '@blocksuite/affine/model'; import type { CodeBlockModel } from '@blocksuite/affine/model';
@@ -87,7 +88,13 @@ export class HTMLPreview extends SignalWatcher(WithDisposable(LitElement)) {
this.state = 'finish'; this.state = 'finish';
}) })
.catch(error => { .catch(error => {
console.error('Failed to link WebContainer:', error); const errorMessage = `Failed to link WebContainer: ${error}`;
console.error(errorMessage);
track.doc.editor.codeBlock.htmlBlockPreviewFailed({
type: errorMessage,
});
this.state = 'error'; this.state = 'error';
}); });
} }
@@ -1,4 +1,5 @@
import { FeatureFlagService } from '@affine/core/modules/feature-flag'; import { FeatureFlagService } from '@affine/core/modules/feature-flag';
import track from '@affine/track';
import { import {
type ViewExtensionContext, type ViewExtensionContext,
ViewExtensionProvider, ViewExtensionProvider,
@@ -39,7 +40,13 @@ export class CodeBlockPreviewViewExtension extends ViewExtensionProvider {
.value; .value;
if (!flag) return; if (!flag) return;
if (!window.crossOriginIsolated) return; if (!window.crossOriginIsolated) {
track.doc.editor.codeBlock.htmlBlockPreviewFailed({
type: 'cross-origin-isolated not supported',
});
return;
}
context.register(CodeBlockHtmlPreview); context.register(CodeBlockHtmlPreview);
} }
+6 -1
View File
@@ -57,7 +57,8 @@ type DocEvents =
| 'addProperty' | 'addProperty'
| 'editDisplayMenu' | 'editDisplayMenu'
| 'navigateAllDocsRouter' | 'navigateAllDocsRouter'
| 'navigatePinedCollectionRouter'; | 'navigatePinedCollectionRouter'
| 'htmlBlockPreviewFailed';
type EditorEvents = type EditorEvents =
| 'bold' | 'bold'
| 'italic' | 'italic'
@@ -463,6 +464,7 @@ interface PageEvents extends PageDivision {
aiActions: ['requestSignIn']; aiActions: ['requestSignIn'];
starterBar: ['quickStart', 'openTemplateListMenu']; starterBar: ['quickStart', 'openTemplateListMenu'];
audioBlock: ['transcribeRecording', 'openTranscribeNotes']; audioBlock: ['transcribeRecording', 'openTranscribeNotes'];
codeBlock: ['htmlBlockPreviewFailed'];
}; };
inlineDocInfo: { inlineDocInfo: {
$: ['toggle']; $: ['toggle'];
@@ -765,6 +767,9 @@ export type EventArgs = {
mentionMember: { mentionMember: {
type: 'member' | 'invite' | 'more'; type: 'member' | 'invite' | 'more';
}; };
htmlBlockPreviewFailed: {
type: string;
};
noAccessPrompted: {}; noAccessPrompted: {};
loadDoc: { loadDoc: {
workspaceId: string; workspaceId: string;