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

View File

@@ -4,6 +4,10 @@ import {
showPopFilterableList,
} from '@blocksuite/affine-components/filterable-list';
import { ArrowDownIcon } from '@blocksuite/affine-components/icons';
import {
DocModeProvider,
TelemetryProvider,
} from '@blocksuite/affine-shared/services';
import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme';
import { SignalWatcher, WithDisposable } from '@blocksuite/global/lit';
import { noop } from '@blocksuite/global/utils';
@@ -73,6 +77,18 @@ export class LanguageListButton extends WithDisposable(
this.blockComponent.store.transact(() => {
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,
items: this._sortedBundledLanguages,

View File

@@ -1,3 +1,7 @@
import {
DocModeProvider,
TelemetryProvider,
} from '@blocksuite/affine-shared/services';
import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme';
import { SignalWatcher, WithDisposable } from '@blocksuite/global/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, {
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() {

View File

@@ -0,0 +1,8 @@
import type { TelemetryEvent } from './types.js';
export type CodeBlockEventType =
| 'codeBlockLanguageSelect'
| 'htmlBlockTogglePreview'
| 'htmlBlockPreviewFailed';
export type CodeBlockEvents = Record<CodeBlockEventType, TelemetryEvent>;

View File

@@ -1,6 +1,7 @@
import { createIdentifier } from '@blocksuite/global/di';
import type { ExtensionType } from '@blocksuite/store';
import type { CodeBlockEvents } from './code-block.js';
import type { OutDatabaseAllEvents } from './database.js';
import type { LinkToolbarEvents } from './link.js';
import type { NoteEvents } from './note.js';
@@ -26,6 +27,7 @@ import type {
export type TelemetryEventMap = OutDatabaseAllEvents &
LinkToolbarEvents &
SlashMenuEvents &
CodeBlockEvents &
NoteEvents & {
DocCreated: DocCreatedEvent;
Link: TelemetryEvent;

View File

@@ -1,3 +1,4 @@
import track from '@affine/track';
import { CodeBlockPreviewExtension } from '@blocksuite/affine/blocks/code';
import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit';
import type { CodeBlockModel } from '@blocksuite/affine/model';
@@ -87,7 +88,13 @@ export class HTMLPreview extends SignalWatcher(WithDisposable(LitElement)) {
this.state = 'finish';
})
.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';
});
}

View File

@@ -1,4 +1,5 @@
import { FeatureFlagService } from '@affine/core/modules/feature-flag';
import track from '@affine/track';
import {
type ViewExtensionContext,
ViewExtensionProvider,
@@ -39,7 +40,13 @@ export class CodeBlockPreviewViewExtension extends ViewExtensionProvider {
.value;
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);
}

View File

@@ -57,7 +57,8 @@ type DocEvents =
| 'addProperty'
| 'editDisplayMenu'
| 'navigateAllDocsRouter'
| 'navigatePinedCollectionRouter';
| 'navigatePinedCollectionRouter'
| 'htmlBlockPreviewFailed';
type EditorEvents =
| 'bold'
| 'italic'
@@ -463,6 +464,7 @@ interface PageEvents extends PageDivision {
aiActions: ['requestSignIn'];
starterBar: ['quickStart', 'openTemplateListMenu'];
audioBlock: ['transcribeRecording', 'openTranscribeNotes'];
codeBlock: ['htmlBlockPreviewFailed'];
};
inlineDocInfo: {
$: ['toggle'];
@@ -765,6 +767,9 @@ export type EventArgs = {
mentionMember: {
type: 'member' | 'invite' | 'more';
};
htmlBlockPreviewFailed: {
type: string;
};
noAccessPrompted: {};
loadDoc: {
workspaceId: string;