Implement "switch away survey" when users switching back to ace from cm6 (#10201)

Implement legacy source editor survey:

* Force user to switch to cm6 if they haven't seen switch away survey

* Only show user switch away survey if they open ace from another editor

* We need to wait 3 seconds until the survey is being shown

* Add comment to explain the reasoning of not showing cm6 switch away survey for rich text users

* Use localstorage `editor.has_seen_cm6_switch_away_survey` setter to not show the survey if user has seen the survey

* the `editor.has_seen_cm6_switch_away_survey` will have the value `true` even if user is not interacting with it, so update comment to reflect that

* Add `once: true` option to keydown event to avoid unnecessary callback invocation upon key presses

GitOrigin-RevId: c26be2bb39efac2dff112c821fca893e5993dcbf
This commit is contained in:
M Fahru
2022-11-04 09:05:50 +00:00
committed by Copybot
parent bcad89fd28
commit 19dd2f67e2
6 changed files with 150 additions and 3 deletions
@@ -0,0 +1,98 @@
import { useCallback, useEffect, useRef, useState } from 'react'
import { Button } from 'react-bootstrap'
import customLocalStorage from '../../../infrastructure/local-storage'
import useScopeValue from '../../../shared/hooks/use-scope-value'
type CM6SwitchAwaySurveyState = 'disabled' | 'enabled' | 'shown'
export default function CM6SwitchAwaySurvey() {
const [state, setState] = useState<CM6SwitchAwaySurveyState>('disabled')
const [newSourceEditor] = useScopeValue('editor.newSourceEditor')
const [richText] = useScopeValue('editor.showRichText')
const initialRichTextPreference = useRef<boolean>(richText)
useEffect(() => {
// If the user has previously seen the survey, then don't show it again
const hasSeenCM6SwitchAwaySurvey = customLocalStorage.getItem(
'editor.has_seen_cm6_switch_away_survey'
)
if (hasSeenCM6SwitchAwaySurvey) return
if (initialRichTextPreference.current) {
if (!richText && newSourceEditor) {
// If user change from rich text to cm6, we remove the rich text preference
// so if user use rich text -> cm6 -> ace, we will show the survey
initialRichTextPreference.current = false
}
// If the user loaded rich text initially, then don't show the survey
// (we are assuming that they will not have used CM6 as much)
return
}
if (!newSourceEditor) {
setState('enabled')
}
}, [newSourceEditor, richText])
useEffect(() => {
if (state === 'enabled') {
const handleKeyDown = () => {
const TIME_FOR_SURVEY_TO_APPEAR = 3000
setTimeout(() => {
setState('shown')
customLocalStorage.setItem(
'editor.has_seen_cm6_switch_away_survey',
true
)
}, TIME_FOR_SURVEY_TO_APPEAR)
}
// can't access the ace editor directly, so add the keydown event
// to window
window?.addEventListener('keydown', handleKeyDown, { once: true })
}
}, [state])
const handleClose = useCallback(() => {
setState('disabled')
}, [])
if (state !== 'shown') {
return null
}
return (
<div className="alert alert-success cm6-switch-away-survey" role="alert">
<Button
className="close"
data-dismiss="alert"
aria-label="Close"
onClick={handleClose}
>
<span aria-hidden="true">&times;</span>
</Button>
<div className="warning-content">
<div>
<div className="warning-text">
We noticed that you're still using the{' '}
<strong>Source (legacy)</strong> editor.
</div>
<div className="warning-text">Could you let us know why?</div>
</div>
<div style={{ display: 'inline-flex' }}>
<a
href="https://forms.gle/aW5tMRASpQ7Snds6A"
className="btn btn-sm btn-info"
target="_blank"
rel="noreferrer"
onClick={handleClose}
>
Take survey
</a>
</div>
</div>
</div>
)
}
@@ -0,0 +1,9 @@
import App from '../../../base'
import { react2angular } from 'react2angular'
import { rootContext } from '../../../shared/context/root-context'
import CM6SwitchAwaySurvey from '../components/cm6-switch-away-survey'
App.component(
'cm6SwitchAwaySurvey',
react2angular(rootContext.use(CM6SwitchAwaySurvey))
)