feat(core): add track events for cmdk (#7668)

This commit is contained in:
JimmFly 2024-08-07 05:52:42 +00:00
parent 67dce9c97a
commit eb01e76426
No known key found for this signature in database
GPG Key ID: 126E0320FEB0D05C
13 changed files with 175 additions and 12 deletions

View File

@ -4,6 +4,7 @@ import type { createStore } from 'jotai';
import { openCreateWorkspaceModalAtom } from '../atoms';
import type { usePageHelper } from '../components/blocksuite/block-suite-page-list/utils';
import { track } from '../mixpanel';
import { registerAffineCommand } from './registry';
export function registerAffineCreationCommands({
@ -29,6 +30,8 @@ export function registerAffineCreationCommands({
}
: undefined,
run() {
track.$.cmdk.creation.createDoc({ mode: 'page' });
pageHelper.createPage();
},
})
@ -41,6 +44,10 @@ export function registerAffineCreationCommands({
icon: <PlusIcon />,
label: t['com.affine.cmdk.affine.new-edgeless-page'](),
run() {
track.$.cmdk.creation.createDoc({
mode: 'edgeless',
});
pageHelper.createEdgeless();
},
})
@ -53,6 +60,8 @@ export function registerAffineCreationCommands({
icon: <PlusIcon />,
label: t['com.affine.cmdk.affine.new-workspace'](),
run() {
track.$.cmdk.workspace.createWorkspace();
store.set(openCreateWorkspaceModalAtom, 'new');
},
})
@ -67,6 +76,10 @@ export function registerAffineCreationCommands({
return environment.isDesktop;
},
run() {
track.$.cmdk.workspace.createWorkspace({
control: 'import',
});
store.set(openCreateWorkspaceModalAtom, 'add');
},
})

View File

@ -3,6 +3,7 @@ import { ContactWithUsIcon, NewIcon } from '@blocksuite/icons/rc';
import type { createStore } from 'jotai';
import { openSettingModalAtom } from '../atoms';
import { track } from '../mixpanel';
import { popupWindow } from '../utils';
import { registerAffineCommand } from './registry';
@ -21,6 +22,7 @@ export function registerAffineHelpCommands({
icon: <NewIcon />,
label: t['com.affine.cmdk.affine.whats-new'](),
run() {
track.$.cmdk.help.openChangelog();
popupWindow(runtimeConfig.changelogUrl);
},
})
@ -32,6 +34,7 @@ export function registerAffineHelpCommands({
icon: <ContactWithUsIcon />,
label: t['com.affine.cmdk.affine.contact-us'](),
run() {
track.$.cmdk.help.contactUs();
store.set(openSettingModalAtom, {
open: true,
activeTab: 'about',

View File

@ -3,6 +3,7 @@ import { SidebarIcon } from '@blocksuite/icons/rc';
import type { createStore } from 'jotai';
import { appSidebarOpenAtom } from '../components/app-sidebar';
import { track } from '../mixpanel';
import { registerAffineCommand } from './registry';
export function registerAffineLayoutCommands({
@ -27,6 +28,8 @@ export function registerAffineLayoutCommands({
binding: '$mod+/',
},
run() {
track.$.navigationPanel.$.toggle();
store.set(appSidebarOpenAtom, v => !v);
},
})

View File

@ -28,6 +28,10 @@ export function registerAffineNavigationCommands({
icon: <ArrowRightBigIcon />,
label: t['com.affine.cmdk.affine.navigation.goto-all-pages'](),
run() {
track.$.cmdk.navigation.navigate({
to: 'allDocs',
});
navigationHelper.jumpToSubPath(docCollection.id, WorkspaceSubPath.ALL);
},
})
@ -40,6 +44,10 @@ export function registerAffineNavigationCommands({
icon: <ArrowRightBigIcon />,
label: 'Go to Collection List',
run() {
track.$.cmdk.navigation.navigate({
to: 'collectionList',
});
navigationHelper.jumpToCollections(docCollection.id);
},
})
@ -52,6 +60,10 @@ export function registerAffineNavigationCommands({
icon: <ArrowRightBigIcon />,
label: 'Go to Tag List',
run() {
track.$.cmdk.navigation.navigate({
to: 'tagList',
});
navigationHelper.jumpToTags(docCollection.id);
},
})
@ -64,6 +76,10 @@ export function registerAffineNavigationCommands({
icon: <ArrowRightBigIcon />,
label: t['com.affine.cmdk.affine.navigation.goto-workspace'](),
run() {
track.$.cmdk.navigation.navigate({
to: 'workspace',
});
store.set(openWorkspaceListModalAtom, true);
},
})
@ -109,6 +125,10 @@ export function registerAffineNavigationCommands({
icon: <ArrowRightBigIcon />,
label: t['com.affine.cmdk.affine.navigation.goto-trash'](),
run() {
track.$.cmdk.navigation.navigate({
to: 'trash',
});
navigationHelper.jumpToSubPath(
docCollection.id,
WorkspaceSubPath.TRASH

View File

@ -6,6 +6,7 @@ import type { createStore } from 'jotai';
import type { useTheme } from 'next-themes';
import type { useLanguageHelper } from '../hooks/affine/use-language-helper';
import { track } from '../mixpanel';
import { registerAffineCommand } from './registry';
export function registerAffineSettingsCommands({
@ -34,6 +35,10 @@ export function registerAffineSettingsCommands({
icon: <SettingsIcon />,
preconditionStrategy: () => theme.theme !== 'system',
run() {
track.$.cmdk.settings.changeAppSetting({
key: 'theme',
value: 'system',
});
theme.setTheme('system');
},
})
@ -48,6 +53,10 @@ export function registerAffineSettingsCommands({
icon: <SettingsIcon />,
preconditionStrategy: () => theme.theme !== 'dark',
run() {
track.$.cmdk.settings.changeAppSetting({
key: 'theme',
value: 'dark',
});
theme.setTheme('dark');
},
})
@ -63,6 +72,11 @@ export function registerAffineSettingsCommands({
icon: <SettingsIcon />,
preconditionStrategy: () => theme.theme !== 'light',
run() {
track.$.cmdk.settings.changeAppSetting({
key: 'theme',
value: 'light',
});
theme.setTheme('light');
},
})
@ -80,6 +94,11 @@ export function registerAffineSettingsCommands({
preconditionStrategy: () =>
store.get(appSettingAtom).fontStyle !== 'Sans',
run() {
track.$.cmdk.settings.changeAppSetting({
key: 'fontStyle',
value: 'Sans',
});
store.set(appSettingAtom, prev => ({
...prev,
fontStyle: 'Sans',
@ -99,6 +118,11 @@ export function registerAffineSettingsCommands({
preconditionStrategy: () =>
store.get(appSettingAtom).fontStyle !== 'Serif',
run() {
track.$.cmdk.settings.changeAppSetting({
key: 'fontStyle',
value: 'Serif',
});
store.set(appSettingAtom, prev => ({
...prev,
fontStyle: 'Serif',
@ -118,6 +142,11 @@ export function registerAffineSettingsCommands({
preconditionStrategy: () =>
store.get(appSettingAtom).fontStyle !== 'Mono',
run() {
track.$.cmdk.settings.changeAppSetting({
key: 'fontStyle',
value: 'Mono',
});
store.set(appSettingAtom, prev => ({
...prev,
fontStyle: 'Mono',
@ -138,6 +167,11 @@ export function registerAffineSettingsCommands({
icon: <SettingsIcon />,
preconditionStrategy: () => currentLanguage?.tag !== language.tag,
run() {
track.$.cmdk.settings.changeAppSetting({
key: 'language',
value: language.name,
});
onLanguageChange(language.tag);
},
})
@ -158,6 +192,10 @@ export function registerAffineSettingsCommands({
icon: <SettingsIcon />,
preconditionStrategy: () => environment.isDesktop,
run() {
track.$.cmdk.settings.changeAppSetting({
key: 'clientBorder',
value: store.get(appSettingAtom).clientBorder ? 'off' : 'on',
});
store.set(appSettingAtom, prev => ({
...prev,
clientBorder: !prev.clientBorder,
@ -178,6 +216,11 @@ export function registerAffineSettingsCommands({
category: 'affine:settings',
icon: <SettingsIcon />,
run() {
track.$.cmdk.settings.changeAppSetting({
key: 'fullWidthLayout',
value: store.get(appSettingAtom).fullWidthLayout ? 'off' : 'on',
});
store.set(appSettingAtom, prev => ({
...prev,
fullWidthLayout: !prev.fullWidthLayout,
@ -201,6 +244,11 @@ export function registerAffineSettingsCommands({
icon: <SettingsIcon />,
preconditionStrategy: () => environment.isDesktop,
run() {
track.$.cmdk.settings.changeAppSetting({
key: 'enableNoisyBackground',
value: store.get(appSettingAtom).enableNoisyBackground ? 'off' : 'on',
});
store.set(appSettingAtom, prev => ({
...prev,
enableNoisyBackground: !prev.enableNoisyBackground,
@ -222,6 +270,10 @@ export function registerAffineSettingsCommands({
icon: <SettingsIcon />,
preconditionStrategy: () => environment.isDesktop && environment.isMacOs,
run() {
track.$.cmdk.settings.changeAppSetting({
key: 'enableBlurBackground',
value: store.get(appSettingAtom).enableBlurBackground ? 'off' : 'on',
});
store.set(appSettingAtom, prev => ({
...prev,
enableBlurBackground: !prev.enableBlurBackground,

View File

@ -5,6 +5,7 @@ import type { useI18n } from '@affine/i18n';
import { ResetIcon } from '@blocksuite/icons/rc';
import type { createStore } from 'jotai';
import { track } from '../mixpanel';
import { registerAffineCommand } from './registry';
export function registerAffineUpdatesCommands({
@ -24,6 +25,8 @@ export function registerAffineUpdatesCommands({
label: t['com.affine.cmdk.affine.restart-to-upgrade'](),
preconditionStrategy: () => !!store.get(updateReadyAtom),
run() {
track.$.cmdk.updates.quitAndInstall();
apis?.updater.quitAndInstall().catch(err => {
notify.error({
title: 'Failed to restart to upgrade',

View File

@ -150,7 +150,9 @@ export const PageHeaderMenuButton = ({
const handleSwitchMode = useCallback(() => {
doc.toggleMode();
track.$.header.docOptions.switchPageMode();
track.$.header.docOptions.switchPageMode({
mode: currentMode === 'page' ? 'edgeless' : 'page',
});
toast(
currentMode === 'page'
? t['com.affine.toastMessage.edgelessMode']()

View File

@ -102,6 +102,8 @@ export function useRegisterBlocksuiteEditorCommands() {
icon: mode === 'page' ? <PageIcon /> : <EdgelessIcon />,
label: t['com.affine.page-properties.page-info.view'](),
run() {
track.$.cmdk.docInfo.open();
openInfoModal();
},
})
@ -118,6 +120,8 @@ export function useRegisterBlocksuiteEditorCommands() {
: t['com.affine.favoritePageOperation.add'](),
run() {
favAdapter.toggle(docId, 'doc');
track.$.cmdk.editor.toggleFavorite();
toast(
favorite
? t['com.affine.cmdk.affine.editor.remove-from-favourites']()
@ -141,6 +145,10 @@ export function useRegisterBlocksuiteEditorCommands() {
: t['com.affine.pageMode.page']()
}`,
run() {
track.$.cmdk.editor.switchPageMode({
mode: mode === 'page' ? 'edgeless' : 'page',
});
doc.toggleMode();
toast(
mode === 'page'
@ -161,7 +169,7 @@ export function useRegisterBlocksuiteEditorCommands() {
label: t['com.affine.header.option.duplicate'](),
run() {
duplicate(docId);
track.$.cmdk.$.createDoc({
track.$.cmdk.editor.createDoc({
control: 'duplicate',
});
},
@ -176,6 +184,10 @@ export function useRegisterBlocksuiteEditorCommands() {
icon: mode === 'page' ? <PageIcon /> : <EdgelessIcon />,
label: t['Export to PDF'](),
async run() {
track.$.cmdk.editor.export({
type: 'pdf',
});
await exportHandler('pdf');
},
})
@ -189,6 +201,10 @@ export function useRegisterBlocksuiteEditorCommands() {
icon: mode === 'page' ? <PageIcon /> : <EdgelessIcon />,
label: t['Export to HTML'](),
async run() {
track.$.cmdk.editor.export({
type: 'html',
});
await exportHandler('html');
},
})
@ -202,6 +218,10 @@ export function useRegisterBlocksuiteEditorCommands() {
icon: mode === 'page' ? <PageIcon /> : <EdgelessIcon />,
label: t['Export to PNG'](),
async run() {
track.$.cmdk.editor.export({
type: 'png',
});
await exportHandler('png');
},
})
@ -215,6 +235,10 @@ export function useRegisterBlocksuiteEditorCommands() {
icon: mode === 'page' ? <PageIcon /> : <EdgelessIcon />,
label: t['Export to Markdown'](),
async run() {
track.$.cmdk.editor.export({
type: 'markdown',
});
await exportHandler('markdown');
},
})
@ -228,6 +252,8 @@ export function useRegisterBlocksuiteEditorCommands() {
icon: mode === 'page' ? <PageIcon /> : <EdgelessIcon />,
label: t['com.affine.moveToTrash.title'](),
run() {
track.$.cmdk.editor.deleteDoc();
onClickDelete(doc.title$.value);
},
})
@ -242,6 +268,8 @@ export function useRegisterBlocksuiteEditorCommands() {
icon: mode === 'page' ? <PageIcon /> : <EdgelessIcon />,
label: t['com.affine.cmdk.affine.editor.restore-from-trash'](),
run() {
track.$.cmdk.editor.restoreDoc();
doc.restoreFromTrash();
},
})
@ -255,6 +283,8 @@ export function useRegisterBlocksuiteEditorCommands() {
icon: <HistoryIcon />,
label: t['com.affine.cmdk.affine.editor.reveal-page-history-modal'](),
run() {
track.$.cmdk.docHistory.open();
openHistoryModal();
},
})

View File

@ -3,9 +3,10 @@ import {
registerAffineCommand,
} from '@affine/core/commands';
import { useSharingUrl } from '@affine/core/hooks/affine/use-share-url';
import { track } from '@affine/core/mixpanel';
import { useIsActiveView } from '@affine/core/modules/workbench';
import { WorkspaceFlavour } from '@affine/env/workspace';
import type { WorkspaceMetadata } from '@toeverything/infra';
import { type WorkspaceMetadata } from '@toeverything/infra';
import { useEffect } from 'react';
export function useRegisterCopyLinkCommands({
@ -38,6 +39,8 @@ export function useRegisterCopyLinkCommands({
label: '',
icon: null,
run() {
track.$.cmdk.general.copyShareLink({ type: 'private' });
isActiveView && isCloud && onClickCopyLink();
},
})

View File

@ -2,6 +2,7 @@ import {
PreconditionStrategy,
registerAffineCommand,
} from '@affine/core/commands';
import { track } from '@affine/core/mixpanel';
import { FindInPageService } from '@affine/core/modules/find-in-page/services/find-in-page';
import { useService } from '@toeverything/infra';
import { useCallback, useEffect } from 'react';
@ -24,13 +25,15 @@ export function useRegisterFindInPageCommands() {
unsubs.push(
registerAffineCommand({
preconditionStrategy: PreconditionStrategy.Never,
id: `editor:find-in-page`,
id: `affine:find-in-page`,
keyBinding: {
binding: '$mod+f',
},
icon: null,
label: '',
run() {
track.$.cmdk.general.findInPage();
toggleVisible();
},
})

View File

@ -2,21 +2,26 @@
/* eslint-disable rxjs/finnish */
// SECTION: app events
type GeneralEvents = 'openMigrationDataHelp' | 'export';
type CmdkEvents = 'quickSearch';
type GeneralEvents = 'openMigrationDataHelp';
type CmdkEvents = 'quickSearch' | 'recentDocs' | 'searchResultsDocs';
type AppEvents =
| 'checkUpdates'
| 'downloadUpdate'
| 'downloadApp'
| 'quitAndInstall'
| 'openChangelog'
| 'dismissChangelog';
| 'dismissChangelog'
| 'contactUs'
| 'findInPage';
type NavigationEvents =
| 'openInNewTab'
| 'openInSplitView'
| 'switchTab'
| 'switchSplitView'
| 'navigate'
| 'goBack'
| 'goForward'
| 'toggle' // toggle navigation panel
| 'open'
| 'close'; // openclose modal/diaglog
@ -35,6 +40,7 @@ type DocEvents =
| 'renameDoc'
| 'linkDoc'
| 'deleteDoc'
| 'restoreDoc'
| 'switchPageMode'
| 'openDocOptionsMenu'
| 'openDocInfo';
@ -61,7 +67,6 @@ type FolderEvents =
| 'deleteFolder';
type TagEvents = 'createTag' | 'deleteTag' | 'renameTag' | 'tagDoc';
type FavoriteEvents = 'toggleFavorite';
type DocInfoEvents = 'toggle' | 'open';
type OrganizeItemEvents = // doc, link, folder, collection, tag
| 'createOrganizeItem'
@ -111,8 +116,7 @@ type UserEvents =
| ShareEvents
| AuthEvents
| AccountEvents
| PaymentEvents
| DocInfoEvents;
| PaymentEvents;
interface PageDivision {
[page: string]: {
@ -161,11 +165,28 @@ const PageEvents = {
about: ['checkUpdates', 'downloadUpdate', 'changeAppSetting'],
},
cmdk: {
$: ['createDoc'],
recent: ['recentDocs'],
results: ['searchResultsDocs'],
general: ['copyShareLink', 'goBack', 'goForward', 'findInPage'],
creation: ['createDoc'],
workspace: ['createWorkspace'],
settings: ['openSettings', 'changeAppSetting'],
navigation: ['navigate'],
editor: [
'toggleFavorite',
'switchPageMode',
'createDoc',
'export',
'deleteDoc',
'restoreDoc',
],
docInfo: ['open'],
docHistory: ['open'],
updates: ['quitAndInstall'],
help: ['contactUs', 'openChangelog'],
},
navigationPanel: {
$: ['quickSearch', 'createDoc', 'navigate', 'openSettings'],
$: ['quickSearch', 'createDoc', 'navigate', 'openSettings', 'toggle'],
organize: [
'createOrganizeItem',
'renameOrganizeItem',

View File

@ -2,6 +2,7 @@ import {
PreconditionStrategy,
registerAffineCommand,
} from '@affine/core/commands';
import { track } from '@affine/core/mixpanel';
import { useService } from '@toeverything/infra';
import { useEffect } from 'react';
@ -23,6 +24,8 @@ export function useRegisterNavigationCommands() {
binding: '$mod+[',
},
run() {
track.$.cmdk.general.goBack();
navigator.back();
},
})
@ -38,6 +41,8 @@ export function useRegisterNavigationCommands() {
binding: '$mod+]',
},
run() {
track.$.cmdk.general.goForward();
navigator.forward();
},
})

View File

@ -1,3 +1,4 @@
import { track } from '@affine/core/mixpanel';
import type { DocsService } from '@toeverything/infra';
import { Service } from '@toeverything/infra';
@ -47,6 +48,10 @@ export class CMDKQuickSearchService extends Service {
blockId?: string;
} = result.payload;
result.source === 'recent-doc' && track.$.cmdk.recent.recentDocs();
result.source === 'docs' &&
track.$.cmdk.results.searchResultsDocs();
this.workbenchService.workbench.openDoc({
docId: doc.docId,
blockId: doc.blockId,