chore: populate page prop for mixpanel (#7425)

This commit is contained in:
pengx17
2024-07-05 07:45:38 +00:00
parent 481a2269f8
commit 8dfa601771
11 changed files with 127 additions and 24 deletions
@@ -1,5 +1,5 @@
export { Navigator } from './entities/navigator';
export { resolveLinkToDoc } from './utils';
export { resolveLinkToDoc, resolveRouteLinkMeta } from './utils';
export { NavigationButtons } from './view/navigation-buttons';
import { type Framework, WorkspaceScope } from '@toeverything/infra';
@@ -8,7 +8,7 @@ function maybeAffineOrigin(origin: string) {
);
}
export const resolveLinkToDoc = (href: string) => {
export const resolveRouteLinkMeta = (href: string) => {
try {
const url = new URL(href, location.origin);
@@ -18,23 +18,49 @@ export const resolveLinkToDoc = (href: string) => {
return null;
}
// http://xxx/workspace/48__RTCSwASvWZxyAk3Jw/-Uge-K6SYcAbcNYfQ5U-j#xxxx
// http://xxx/workspace/all/yyy
// to { workspaceId: '48__RTCSwASvWZxyAk3Jw', docId: '-Uge-K6SYcAbcNYfQ5U-j', blockId: 'xxxx' }
const [_, workspaceId, docId, blockId] =
const [_, workspaceId, moduleName, subModuleName] =
url.toString().match(/\/workspace\/([^/]+)\/([^#]+)(?:#(.+))?/) || [];
/**
* @see /packages/frontend/core/src/router.tsx
*/
const excludedPaths = ['all', 'collection', 'tag', 'trash'];
if (!docId || excludedPaths.includes(docId)) {
return null;
if (isRouteModulePath(moduleName)) {
return {
workspaceId,
moduleName,
subModuleName,
};
} else if (moduleName) {
// for now we assume all other cases are doc links
return {
workspaceId,
moduleName: 'doc' as const,
docId: moduleName,
blockId: subModuleName,
};
}
return { workspaceId, docId, blockId };
return;
} catch {
return null;
}
};
/**
* @see /packages/frontend/core/src/router.tsx
*/
const routeModulePaths = ['all', 'collection', 'tag', 'trash'] as const;
const isRouteModulePath = (
path: string
): path is (typeof routeModulePaths)[number] =>
routeModulePaths.includes(path as any);
export const resolveLinkToDoc = (href: string) => {
const meta = resolveRouteLinkMeta(href);
if (!meta || meta.moduleName !== 'doc') return null;
return {
workspaceId: meta.workspaceId,
docId: meta.docId,
blockId: meta.blockId,
};
};
@@ -1,8 +1,14 @@
import type { Framework } from '@toeverything/infra';
import { type Framework, WorkspaceScope } from '@toeverything/infra';
import { AuthService } from '../cloud';
import { TelemetryService } from './services/telemetry';
import {
TelemetryService,
TelemetryWorkspaceContextService,
} from './services/telemetry';
export function configureTelemetryModule(framework: Framework) {
framework.service(TelemetryService, [AuthService]);
framework
.scope(WorkspaceScope)
.service(TelemetryWorkspaceContextService, [WorkspaceScope]);
}
@@ -1,6 +1,12 @@
import { mixpanel } from '@affine/core/utils';
import type { QuotaQuery } from '@affine/graphql';
import { ApplicationStarted, OnEvent, Service } from '@toeverything/infra';
import type { WorkspaceScope } from '@toeverything/infra';
import {
ApplicationStarted,
DocsService,
OnEvent,
Service,
} from '@toeverything/infra';
import {
AccountChanged,
@@ -9,6 +15,8 @@ import {
} from '../../cloud';
import { AccountLoggedOut } from '../../cloud/services/auth';
import { UserQuotaChanged } from '../../cloud/services/user-quota';
import { resolveRouteLinkMeta } from '../../navigation';
import { WorkbenchService } from '../../workbench';
@OnEvent(ApplicationStarted, e => e.onApplicationStart)
@OnEvent(AccountChanged, e => e.updateIdentity)
@@ -67,3 +75,38 @@ export class TelemetryService extends Service {
this.prevQuota = quota;
}
}
// get telemetry related context in Workspace scope
export class TelemetryWorkspaceContextService extends Service {
constructor(private readonly provider: WorkspaceScope) {
super();
}
getPageContext() {
const workbench = this.provider?.getOptional(WorkbenchService)?.workbench;
const docs = this.provider?.getOptional(DocsService);
if (!workbench || !docs) return '';
const basename = workbench.basename$.value;
const path = workbench.location$.value;
const fullPath = basename + path.pathname + path.search + path.hash;
const linkMeta = resolveRouteLinkMeta(fullPath);
return (() => {
const moduleName =
linkMeta?.moduleName === 'doc'
? docs.list.getMode(linkMeta.docId)
: linkMeta?.moduleName;
switch (moduleName) {
case 'page':
return 'page editor';
case 'edgeless':
return 'whiteboard editor';
case 'trash':
return 'trash';
default:
return 'doc library';
}
})();
}
}