editor-switch.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import { memo, useCallback } from 'react'
  2. import useScopeValue from '../../../shared/hooks/use-scope-value'
  3. import Tooltip from '../../../shared/components/tooltip'
  4. import { sendMB } from '../../../infrastructure/event-tracking'
  5. import getMeta from '../../../utils/meta'
  6. import SplitTestBadge from '../../../shared/components/split-test-badge'
  7. import isValidTeXFile from '../../../main/is-valid-tex-file'
  8. function Badge() {
  9. const content = (
  10. <>
  11. Overleaf has upgraded the source editor. You can still use the old editor
  12. by selecting "Source (legacy)".
  13. <br />
  14. <br />
  15. Click to learn more and give feedback
  16. </>
  17. )
  18. return (
  19. <Tooltip
  20. id="editor-switch"
  21. description={content}
  22. overlayProps={{
  23. placement: 'bottom',
  24. delayHide: 100,
  25. }}
  26. tooltipProps={{ className: 'tooltip-wide' }}
  27. >
  28. <a
  29. href="https://forms.gle/GmSs6odZRKRp3VX98"
  30. target="_blank"
  31. rel="noopener noreferrer"
  32. className="badge info-badge"
  33. >
  34. <span className="sr-only">{content}</span>
  35. </a>
  36. </Tooltip>
  37. )
  38. }
  39. const showLegacySourceEditor: boolean = getMeta('ol-showLegacySourceEditor')
  40. function EditorSwitch() {
  41. const [newSourceEditor, setNewSourceEditor] = useScopeValue(
  42. 'editor.newSourceEditor'
  43. )
  44. const [richText, setRichText] = useScopeValue('editor.showRichText')
  45. const [visual, setVisual] = useScopeValue('editor.showVisual')
  46. const [docName] = useScopeValue('editor.open_doc_name')
  47. const richTextAvailable = isValidTeXFile(docName)
  48. const richTextOrVisual = richText || (richTextAvailable && visual)
  49. const handleChange = useCallback(
  50. event => {
  51. const editorType = event.target.value
  52. switch (editorType) {
  53. case 'ace':
  54. setRichText(false)
  55. setVisual(false)
  56. setNewSourceEditor(false)
  57. break
  58. case 'cm6':
  59. setRichText(false)
  60. setVisual(false)
  61. setNewSourceEditor(true)
  62. break
  63. case 'rich-text':
  64. if (getMeta('ol-richTextVariant') === 'cm6') {
  65. setRichText(false)
  66. setVisual(true)
  67. setNewSourceEditor(true)
  68. } else {
  69. setRichText(true)
  70. setVisual(false)
  71. }
  72. break
  73. }
  74. sendMB('editor-switch-change', { editorType })
  75. },
  76. [setRichText, setVisual, setNewSourceEditor]
  77. )
  78. return (
  79. <div className="editor-toggle-switch">
  80. {showLegacySourceEditor ? <Badge /> : null}
  81. <fieldset className="toggle-switch">
  82. <legend className="sr-only">Editor mode.</legend>
  83. <input
  84. type="radio"
  85. name="editor"
  86. value="cm6"
  87. id="editor-switch-cm6"
  88. className="toggle-switch-input"
  89. checked={!richTextOrVisual && !!newSourceEditor}
  90. onChange={handleChange}
  91. />
  92. <label htmlFor="editor-switch-cm6" className="toggle-switch-label">
  93. <span>Source</span>
  94. </label>
  95. {showLegacySourceEditor ? (
  96. <>
  97. <input
  98. type="radio"
  99. name="editor"
  100. value="ace"
  101. id="editor-switch-ace"
  102. className="toggle-switch-input"
  103. checked={!richTextOrVisual && !newSourceEditor}
  104. onChange={handleChange}
  105. />
  106. <label htmlFor="editor-switch-ace" className="toggle-switch-label">
  107. <span>Source (legacy)</span>
  108. </label>
  109. </>
  110. ) : null}
  111. <input
  112. type="radio"
  113. name="editor"
  114. value="rich-text"
  115. id="editor-switch-rich-text"
  116. className="toggle-switch-input"
  117. checked={!!richTextOrVisual}
  118. onChange={handleChange}
  119. disabled={!richTextAvailable}
  120. />
  121. <label
  122. htmlFor="editor-switch-rich-text"
  123. className="toggle-switch-label"
  124. >
  125. <span>Rich Text</span>
  126. </label>
  127. </fieldset>
  128. {!!richTextOrVisual && (
  129. <SplitTestBadge splitTestName="rich-text" displayOnVariants={['cm6']} />
  130. )}
  131. </div>
  132. )
  133. }
  134. export default memo(EditorSwitch)