"default-visual-for-beginners" split test tear down (#24759)

GitOrigin-RevId: cdd6c8d3ffb60b9ae3e972f2267f1838cf720c83
This commit is contained in:
Domagoj Kriskovic
2025-04-15 15:08:37 +02:00
committed by Copybot
parent 6ac5142b41
commit 1f7bfb4737
11 changed files with 6 additions and 187 deletions
@@ -349,7 +349,6 @@ const _ProjectController = {
!anonymous && 'ro-mirror-on-client',
'track-pdf-download',
!anonymous && 'writefull-oauth-promotion',
'default-visual-for-beginners',
'hotjar',
'reviewer-role',
'editor-redesign',
@@ -404,13 +403,6 @@ const _ProjectController = {
userId,
projectId
),
usedLatex: OnboardingDataCollectionManager.getOnboardingDataValue(
userId,
'usedLatex'
).catch(err => {
logger.error({ err, userId })
return null
}),
odcRole: OnboardingDataCollectionManager.getOnboardingDataValue(
userId,
'role'
@@ -470,7 +462,6 @@ const _ProjectController = {
subscription,
isTokenMember,
isInvitedMember,
usedLatex,
odcRole,
} = userValues
@@ -887,12 +878,6 @@ const _ProjectController = {
fixedSizeDocument: true,
hasTrackChangesFeature: Features.hasFeature('track-changes'),
projectTags,
usedLatex:
// only use the usedLatex value if the split test is enabled
splitTestAssignments['default-visual-for-beginners']?.variant ===
'enabled'
? usedLatex
: null,
odcRole:
// only use the ODC role value if the split test is enabled
splitTestAssignments['paywall-change-compile-timeout']?.variant ===
@@ -8,7 +8,6 @@ const VALID_KEYS = [
'writefull-oauth-promotion',
'bib-file-tpr-prompt',
'ai-error-assistant-consent',
'code-editor-mode-prompt',
'history-restore-promo',
'us-gov-banner',
'us-gov-banner-fedramp',
@@ -35,7 +35,6 @@ meta(name="ol-showTemplatesServerPro", data-type="boolean" content=showTemplates
meta(name="ol-hasTrackChangesFeature", data-type="boolean" content=hasTrackChangesFeature)
meta(name="ol-inactiveTutorials", data-type="json" content=user.inactiveTutorials)
meta(name="ol-projectTags" data-type="json" content=projectTags)
meta(name="ol-usedLatex" data-type="string" content=usedLatex)
meta(name="ol-ro-mirror-on-client-no-local-storage" data-type="boolean" content=roMirrorOnClientNoLocalStorage)
meta(name="ol-isSaas" data-type="boolean" content=isSaas)
meta(name="ol-shouldLoadHotjar" data-type="boolean" content=shouldLoadHotjar)
@@ -257,8 +257,6 @@
"code_check_failed": "",
"code_check_failed_explanation": "",
"code_editor": "",
"code_editor_tooltip_message": "",
"code_editor_tooltip_title": "",
"collaborate_online_and_offline": "",
"collaborator_chat": "",
"collabs_per_proj": "",
@@ -1,6 +1,5 @@
import { ReactScopeValueStore } from '@/features/ide-react/scope-value-store/react-scope-value-store'
import customLocalStorage from '@/infrastructure/local-storage'
import getMeta from '@/utils/meta'
import { DocumentContainer } from '@/features/ide-react/editor/document-container'
export type EditorScopeValue = {
@@ -37,24 +36,13 @@ export function populateEditorScope(
store.persisted(
'editor.showVisual',
getMeta('ol-usedLatex') === 'never' || showVisualFallbackValue(projectId),
showVisualFallbackValue(projectId),
`editor.lastUsedMode`,
{
toPersisted: showVisual => (showVisual ? 'visual' : 'code'),
fromPersisted: mode => mode === 'visual',
}
)
store.persisted(
'editor.codeEditorOpened',
codeEditorOpenedFallbackValue(),
'editor.codeEditorOpened'
)
store.watch('editor.showVisual', showVisual => {
if (store.get('editor.codeEditorOpened') !== true && showVisual === false) {
store.set('editor.codeEditorOpened', true)
}
})
}
function showVisualFallbackValue(projectId: string) {
@@ -68,16 +56,3 @@ function showVisualFallbackValue(projectId: string) {
return editorModeVal === 'rich-text'
}
function codeEditorOpenedFallbackValue() {
const signUpDate = getMeta('ol-user').signUpDate
if (
typeof signUpDate === 'string' &&
new Date(signUpDate) < new Date('2024-08-02')
) {
// if signUpDate is before releasing "codeEditorOpened" value
// it is assumed that the user has opened the code editor at some point
return true
}
return false
}
@@ -1,102 +0,0 @@
import { ReactElement, useCallback, useEffect, useState } from 'react'
import Close from '@/shared/components/close'
import { useEditorContext } from '@/shared/context/editor-context'
import useTutorial from '@/shared/hooks/promotions/use-tutorial'
import { useUserContext } from '@/shared/context/user-context'
import useScopeValue from '@/shared/hooks/use-scope-value'
import { useTranslation } from 'react-i18next'
import getMeta from '@/utils/meta'
import OLPopover from '@/features/ui/components/ol/ol-popover'
import OLOverlay from '@/features/ui/components/ol/ol-overlay'
const CODE_EDITOR_POPOVER_TIMEOUT = 1000
export const codeEditorModePrompt = 'code-editor-mode-prompt'
export const EditorSwitchBeginnerPopover = ({
children,
targetRef,
}: {
children: ReactElement
targetRef: React.RefObject<HTMLElement>
}) => {
const user = useUserContext()
const { inactiveTutorials } = useEditorContext()
const { t } = useTranslation()
const [codeEditorOpened] = useScopeValue('editor.codeEditorOpened')
const { completeTutorial } = useTutorial(codeEditorModePrompt, {
location: 'logs',
name: codeEditorModePrompt,
})
const [popoverShown, setPopoverShown] = useState(false)
const shouldShowCodeEditorPopover = useCallback(() => {
if (inactiveTutorials.includes(codeEditorModePrompt)) {
return false
}
if (getMeta('ol-usedLatex') !== 'never') {
// only show popover to the users that never used LaTeX (submitted in onboarding data collection)
return false
}
if (codeEditorOpened) {
// dont show popover if code editor was opened at some point
return false
}
const msSinceSignedUp =
user.signUpDate && Date.now() - new Date(user.signUpDate).getTime()
if (msSinceSignedUp && msSinceSignedUp < 24 * 60 * 60 * 1000) {
// dont show popover if user has signed up is less than 24 hours
return false
}
return true
}, [codeEditorOpened, inactiveTutorials, user.signUpDate])
useEffect(() => {
if (popoverShown && codeEditorOpened) {
setPopoverShown(false)
}
}, [codeEditorOpened, popoverShown])
useEffect(() => {
const timeout = setTimeout(() => {
if (shouldShowCodeEditorPopover()) {
setPopoverShown(true)
}
}, CODE_EDITOR_POPOVER_TIMEOUT)
return () => clearTimeout(timeout)
}, [shouldShowCodeEditorPopover])
return (
<>
{children}
<OLOverlay
placement="bottom"
show={popoverShown}
rootClose
onHide={() => setPopoverShown(false)}
target={targetRef.current}
>
<OLPopover id="editor-switch-popover">
<div>
<Close
variant="dark"
onDismiss={() => {
setPopoverShown(false)
completeTutorial({ event: 'promo-click', action: 'complete' })
}}
/>
<div className="tooltip-title">
{t('code_editor_tooltip_title')}
</div>
<div>{t('code_editor_tooltip_message')}</div>
</div>
</OLPopover>
</OLOverlay>
</>
)
}
@@ -1,29 +1,17 @@
import { ChangeEvent, FC, memo, useCallback, useRef } from 'react'
import { ChangeEvent, FC, memo, useCallback } from 'react'
import useScopeValue from '@/shared/hooks/use-scope-value'
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
import useTutorial from '@/shared/hooks/promotions/use-tutorial'
import { sendMB } from '../../../infrastructure/event-tracking'
import { isValidTeXFile } from '../../../main/is-valid-tex-file'
import { useTranslation } from 'react-i18next'
import {
EditorSwitchBeginnerPopover,
codeEditorModePrompt,
} from './editor-switch-beginner-popover'
import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context'
function EditorSwitch() {
const { t } = useTranslation()
const [visual, setVisual] = useScopeValue('editor.showVisual')
const [codeEditorOpened] = useScopeValue('editor.codeEditorOpened')
const { openDocName } = useEditorManagerContext()
const codeEditorRef = useRef<HTMLLabelElement>(null)
const richTextAvailable = openDocName ? isValidTeXFile(openDocName) : false
const { completeTutorial } = useTutorial(codeEditorModePrompt, {
location: 'logs',
name: codeEditorModePrompt,
})
const handleChange = useCallback(
event => {
@@ -32,9 +20,6 @@ function EditorSwitch() {
switch (editorType) {
case 'cm6':
setVisual(false)
if (!codeEditorOpened) {
completeTutorial({ event: 'promo-click', action: 'complete' })
}
break
case 'rich-text':
@@ -44,7 +29,7 @@ function EditorSwitch() {
sendMB('editor-switch-change', { editorType })
},
[codeEditorOpened, completeTutorial, setVisual]
[setVisual]
)
return (
@@ -64,15 +49,9 @@ function EditorSwitch() {
checked={!richTextAvailable || !visual}
onChange={handleChange}
/>
<EditorSwitchBeginnerPopover targetRef={codeEditorRef}>
<label
ref={codeEditorRef}
htmlFor="editor-switch-cm6"
className="toggle-switch-label"
>
<span>{t('code_editor')}</span>
</label>
</EditorSwitchBeginnerPopover>
<label htmlFor="editor-switch-cm6" className="toggle-switch-label">
<span>{t('code_editor')}</span>
</label>
<RichTextToggle
checked={richTextAvailable && visual}
-1
View File
@@ -229,7 +229,6 @@ export interface Meta {
'ol-translationUnableToJoin': string
'ol-usGovBannerVariant': USGovBannerVariant
'ol-useShareJsHash': boolean
'ol-usedLatex': 'never' | 'occasionally' | 'often' | undefined
'ol-user': User
'ol-userAffiliations': Affiliation[]
'ol-userCanExtendTrial': boolean
@@ -333,16 +333,6 @@
}
}
.editor-switch-tooltip .tooltip-inner {
text-align: left;
max-width: 325px;
padding: 10px;
.tooltip-title {
font-weight: bold;
line-height: 22px;
}
}
/**************************************
Formatting buttons
***************************************/
-2
View File
@@ -334,8 +334,6 @@
"code_check_failed": "Code check failed",
"code_check_failed_explanation": "Your code has errors that need to be fixed before the auto-compile can run",
"code_editor": "Code Editor",
"code_editor_tooltip_message": "You can see the code behind your project (and make edits to it) in the Code Editor",
"code_editor_tooltip_title": "Want to view and edit the LaTeX code?",
"collaborate_easily_on_your_projects": "Collaborate easily on your projects. Work on longer or more complex docs.",
"collaborate_online_and_offline": "Collaborate online and offline, using your own workflow",
"collaboration": "Collaboration",
-1
View File
@@ -45,7 +45,6 @@ export type User = {
alphaProgram?: boolean
betaProgram?: boolean
labsProgram?: boolean
isLatexBeginner?: boolean
signUpDate?: string // date string
features?: Features
refProviders?: RefProviders