Merge pull request #28392 from overleaf/dp-segment-editor-analytics

Add editor-redesign segmentation to a bunch of analytics events

GitOrigin-RevId: e8d2091028dab09de06362c38c5a17f32253e7cc
This commit is contained in:
David
2025-09-10 11:31:23 +01:00
committed by Copybot
parent c6df7575d2
commit ae9d84c279
9 changed files with 58 additions and 29 deletions

View File

@@ -1,18 +1,19 @@
import { useTranslation } from 'react-i18next'
import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
import { useProjectContext } from '../../../shared/context/project-context'
import * as eventTracking from '../../../infrastructure/event-tracking'
import { isSmallDevice } from '../../../infrastructure/event-tracking'
import MaterialIcon from '@/shared/components/material-icon'
import OLTooltip from '@/shared/components/ol/ol-tooltip'
import { useEditorAnalytics } from '@/shared/hooks/use-editor-analytics'
export default function DownloadPDF() {
const { t } = useTranslation()
const { pdfDownloadUrl, pdfUrl } = useCompileContext()
const { projectId } = useProjectContext()
const { sendEvent } = useEditorAnalytics()
function sendDownloadEvent() {
eventTracking.sendMB('download-pdf-button-click', {
sendEvent('download-pdf-button-click', {
projectId,
location: 'left-menu',
isSmallDevice,

View File

@@ -17,6 +17,7 @@ type SearchEventSegmentation = {
searchType: 'full-project'
totalDocs: number
totalResults: number
'editor-redesign'?: 'enabled'
}
'search-result-click': {
searchType: 'full-project'

View File

@@ -10,12 +10,12 @@ import {
} from 'react'
import useScopeEventEmitter from '@/shared/hooks/use-scope-event-emitter'
import useEventListener from '@/shared/hooks/use-event-listener'
import * as eventTracking from '@/infrastructure/event-tracking'
import { isValidTeXFile } from '@/main/is-valid-tex-file'
import localStorage from '@/infrastructure/local-storage'
import { useProjectContext } from '@/shared/context/project-context'
import { useEditorOpenDocContext } from '@/features/ide-react/context/editor-open-doc-context'
import { useFileTreeOpenContext } from './file-tree-open-context'
import { useEditorAnalytics } from '@/shared/hooks/use-editor-analytics'
export type PartialFlatOutline = {
level: number
@@ -53,6 +53,7 @@ export const OutlineProvider: FC<React.PropsWithChildren> = ({ children }) => {
const [ignoreNextCursorUpdate, setIgnoreNextCursorUpdate] =
useState<boolean>(false)
const [ignoreNextScroll, setIgnoreNextScroll] = useState<boolean>(false)
const { sendEvent } = useEditorAnalytics()
const goToLineEmitter = useScopeEventEmitter('editor:gotoLine', true)
@@ -110,9 +111,9 @@ export const OutlineProvider: FC<React.PropsWithChildren> = ({ children }) => {
gotoColumn: 0,
syncToPdf,
})
eventTracking.sendMB('outline-jump-to-line')
sendEvent('outline-jump-to-line')
},
[goToLineEmitter]
[goToLineEmitter, sendEvent]
)
const highlightedLine = useMemo(
@@ -142,18 +143,18 @@ export const OutlineProvider: FC<React.PropsWithChildren> = ({ children }) => {
const expandOutline = useCallback(() => {
if (canShowOutline) {
localStorage.setItem(storageKey, true)
eventTracking.sendMB('outline-expand')
sendEvent('outline-expand')
setOutlineExpanded(true)
}
}, [canShowOutline, storageKey])
}, [canShowOutline, storageKey, sendEvent])
const collapseOutline = useCallback(() => {
if (canShowOutline) {
localStorage.setItem(storageKey, false)
eventTracking.sendMB('outline-collapse')
sendEvent('outline-collapse')
setOutlineExpanded(false)
}
}, [canShowOutline, storageKey])
}, [canShowOutline, storageKey, sendEvent])
const toggleOutlineExpanded = useCallback(() => {
if (outlineExpanded) {

View File

@@ -6,6 +6,7 @@ import { useDetachCompileContext as useCompileContext } from '@/shared/context/d
import { useProjectContext } from '@/shared/context/project-context'
import { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import { useEditorAnalytics } from '@/shared/hooks/use-editor-analytics'
export const DownloadProjectZip = () => {
const { t } = useTranslation()
@@ -45,13 +46,14 @@ export const DownloadProjectPDF = () => {
const { t } = useTranslation()
const { pdfDownloadUrl, pdfUrl } = useCompileContext()
const { projectId } = useProjectContext()
const { sendEvent } = useEditorAnalytics()
const sendDownloadEvent = useCallback(() => {
sendMB('download-pdf-button-click', {
sendEvent('download-pdf-button-click', {
projectId,
location: 'project-name-dropdown',
isSmallDevice,
})
}, [projectId])
}, [projectId, sendEvent])
useCommandProvider(
() => [
@@ -60,7 +62,7 @@ export const DownloadProjectPDF = () => {
disabled: !pdfUrl,
href: pdfDownloadUrl || pdfUrl,
handler: ({ location }) => {
sendMB('download-pdf-button-click', {
sendEvent('download-pdf-button-click', {
projectId,
location,
isSmallDevice,
@@ -69,7 +71,7 @@ export const DownloadProjectPDF = () => {
label: t('download_as_pdf'),
},
],
[t, pdfUrl, projectId, pdfDownloadUrl]
[t, pdfUrl, projectId, pdfDownloadUrl, sendEvent]
)
const button = (

View File

@@ -1,13 +1,15 @@
import { useTranslation } from 'react-i18next'
import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
import { useProjectContext } from '@/shared/context/project-context'
import { sendMB, isSmallDevice } from '@/infrastructure/event-tracking'
import { isSmallDevice } from '@/infrastructure/event-tracking'
import OLTooltip from '@/shared/components/ol/ol-tooltip'
import OLButton from '@/shared/components/ol/ol-button'
import MaterialIcon from '@/shared/components/material-icon'
import { useEditorAnalytics } from '@/shared/hooks/use-editor-analytics'
function PdfHybridDownloadButton() {
const { pdfDownloadUrl } = useCompileContext()
const { sendEvent } = useEditorAnalytics()
const { projectId } = useProjectContext()
@@ -23,7 +25,7 @@ function PdfHybridDownloadButton() {
return
}
sendMB('download-pdf-button-click', {
sendEvent('download-pdf-button-click', {
projectId,
location: 'pdf-preview',
isSmallDevice,

View File

@@ -1,7 +1,7 @@
import { useCallback, useEffect, useRef, useState } from 'react'
import PDFJSWrapper from '../util/pdf-js-wrapper'
import { sendMB } from '@/infrastructure/event-tracking'
import { debugConsole } from '@/utils/debugging'
import { useEditorAnalytics } from '@/shared/hooks/use-editor-analytics'
type StoredPDFState = {
scrollMode?: number
@@ -17,6 +17,7 @@ export default function usePresentationMode(
setScale: (scale: string) => void
): () => void {
const storedState = useRef<StoredPDFState>({})
const { sendEvent } = useEditorAnalytics()
const [presentationMode, setPresentationMode] = useState(false)
@@ -114,14 +115,14 @@ export default function usePresentationMode(
}, [presentationMode, arrowKeyListener, clickListener, mouseWheelListener])
const requestPresentationMode = useCallback(() => {
sendMB('pdf-viewer-enter-presentation-mode')
sendEvent('pdf-viewer-enter-presentation-mode')
if (pdfJsWrapper) {
pdfJsWrapper.container.parentElement
?.requestFullscreen()
.catch(debugConsole.error)
}
}, [pdfJsWrapper])
}, [pdfJsWrapper, sendEvent])
const handleEnterFullscreen = useCallback(() => {
if (pdfJsWrapper) {

View File

@@ -7,14 +7,23 @@ import {
} from '@/infrastructure/event-tracking'
import { useCallback } from 'react'
export function populateEditorRedesignSegmentation<
SegmentationType extends Segmentation,
>(
segmentation: SegmentationType | undefined = {} as SegmentationType,
editorRedesign: boolean
): SegmentationType & { 'editor-redesign'?: 'enabled' } {
return editorRedesign
? { ...segmentation, 'editor-redesign': 'enabled' }
: segmentation
}
export const useEditorAnalytics = () => {
const editorRedesign = useIsNewEditorEnabled()
const populateSegmentation = useCallback(
(segmentation: Segmentation | undefined = {}): Segmentation => {
return editorRedesign
? { ...segmentation, 'editor-redesign': 'enabled' }
: segmentation
return populateEditorRedesignSegmentation(segmentation, editorRedesign)
},
[editorRedesign]
)

View File

@@ -111,7 +111,11 @@ const FullProjectSearchUI: FC = () => {
await projectSnapshot.refresh()
if (!abortControllerRef.current.signal.aborted) {
const results = await searchSnapshot(projectSnapshot, searchQuery)
const results = await searchSnapshot(
projectSnapshot,
searchQuery,
newEditor
)
setMatchedFiles(results)
}
} catch (error) {
@@ -121,7 +125,7 @@ const FullProjectSearchUI: FC = () => {
setLoading(false)
}
},
[openDocs, projectSnapshot, t]
[openDocs, projectSnapshot, t, newEditor]
)
const searchInputRef = useRef<HTMLInputElement>(null)

View File

@@ -3,6 +3,7 @@ import { RegExpCursor, SearchCursor, SearchQuery } from '@codemirror/search'
import { ProjectSnapshot } from '@/infrastructure/project-snapshot'
import { categorizer, regexpWordTest, stringWordTest } from './search'
import { sendSearchEvent } from '@/features/event-tracking/search-events'
import { populateEditorRedesignSegmentation } from '@/shared/hooks/use-editor-analytics'
export type Hit = {
lineIndex: number
@@ -20,7 +21,8 @@ const toLowerCase = (string: string) => string.toLowerCase()
export const searchSnapshot = async (
projectSnapshot: ProjectSnapshot,
searchQuery: SearchQuery
searchQuery: SearchQuery,
newEditor: boolean
) => {
if (!searchQuery.search.trim().length) {
return
@@ -82,11 +84,17 @@ export const searchSnapshot = async (
a.path.localeCompare(b.path)
)
sendSearchEvent('search-execute', {
searchType: 'full-project',
totalDocs: docPaths.length,
totalResults: results.flatMap(file => file.hits).length,
})
sendSearchEvent(
'search-execute',
populateEditorRedesignSegmentation(
{
searchType: 'full-project',
totalDocs: docPaths.length,
totalResults: results.flatMap(file => file.hits).length,
},
newEditor
)
)
return results
}