[web] add analytics for @mentions (#36144)

GitOrigin-RevId: 9fb1447166eb5ee82867466abc9af2207c886f8b
This commit is contained in:
Kristina
2026-09-17 11:47:22 +00:00
committed by Copybot
parent 20a4144cf9
commit f179e89c0c
3 changed files with 48 additions and 2 deletions
@@ -35,6 +35,7 @@ import { useCodeMirrorViewContext } from '@/features/source-editor/components/co
import { rangesUpdatedEffect } from '@/features/source-editor/extensions/history-ot'
import { useEditorAnalytics } from '@/shared/hooks/use-editor-analytics'
import { useReviewPanelViewContext } from './review-panel-view-context'
import { countMentionedUsers } from '@/shared/utils/parse-mentions'
export type Threads = Record<ThreadId, ReviewPanelCommentThread>
@@ -279,7 +280,10 @@ export const ThreadsProvider: FC<React.PropsWithChildren> = ({ children }) => {
body: { content },
})
sendEvent('rp-new-comment', { size: content.length })
sendEvent('rp-new-comment', {
size: content.length,
'mentions-count': countMentionedUsers(content),
})
const op: CommentOperation = {
c: text,
@@ -317,6 +321,7 @@ export const ThreadsProvider: FC<React.PropsWithChildren> = ({ children }) => {
view: reviewPanelView,
size: content.length,
thread: threadId,
'mentions-count': countMentionedUsers(content),
})
},
async editMessage(
@@ -351,7 +356,10 @@ export const ThreadsProvider: FC<React.PropsWithChildren> = ({ children }) => {
body: { content },
})
sendEvent('rp-new-comment', { size: content.length })
sendEvent('rp-new-comment', {
size: content.length,
'mentions-count': countMentionedUsers(content),
})
const trackedDeletes = trackedDeletesFromState(view.state)
pos = trackedDeletes.toSnapshot(pos)
@@ -29,6 +29,16 @@ export function parseMentions(content: string): MentionSegment[] {
return segments
}
export function countMentionedUsers(content: string): number {
const userIds = new Set<string>()
for (const match of content.matchAll(MENTION_REGEX)) {
userIds.add(match[1])
}
return userIds.size
}
const MENTION_RAW_LENGTH = 27 // @[ + 24 hex chars + ]
export function sliceMentionSegments(
@@ -1,5 +1,6 @@
import { expect } from 'chai'
import {
countMentionedUsers,
parseMentions,
sliceMentionSegments,
} from '@/shared/utils/parse-mentions'
@@ -76,6 +77,33 @@ describe('parseMentions', function () {
})
})
describe('countMentionedUsers', function () {
const userId1 = 'aabbccddeeff00112233aabb' as UserId
const userId2 = '112233445566778899aabbcc' as UserId
it('should return 0 for content without mentions', function () {
expect(countMentionedUsers('hello world')).to.equal(0)
})
it('should count a single mention', function () {
expect(countMentionedUsers(`hey @[${userId1}]`)).to.equal(1)
})
it('should count distinct mentioned users', function () {
expect(countMentionedUsers(`@[${userId1}] and @[${userId2}]`)).to.equal(2)
})
it('should count a repeated user only once', function () {
expect(countMentionedUsers(`@[${userId1}] @[${userId1}]`)).to.equal(1)
})
it('should ignore malformed mentions', function () {
expect(countMentionedUsers('@[aabbcc] @aabbccddeeff00112233aabb')).to.equal(
0
)
})
})
describe('sliceMentionSegments', function () {
const userId = 'aabbccddeeff00112233aabb' as UserId