Przeglądaj źródła

Merge pull request #13309 from overleaf/td-history-font-size-setting

History migration: use font size, font family and line height from user settings in document diff viewer

GitOrigin-RevId: 59a0bfe3fa0403a971b7a9b0d5aba2ce37d976c8
Tim Down 3 lat temu
rodzic
commit
9db3230e97

+ 30 - 4
services/web/frontend/js/features/history/components/diff-view/document-diff-viewer.tsx

@@ -8,7 +8,14 @@ import {
 import { EditorView, lineNumbers } from '@codemirror/view'
 import { indentationMarkers } from '@replit/codemirror-indentation-markers'
 import { highlights, setHighlightsEffect } from '../../extensions/highlights'
-import { theme } from '../../extensions/theme'
+import useScopeValue from '../../../../shared/hooks/use-scope-value'
+import {
+  theme,
+  Options,
+  setOptionsTheme,
+  FontFamily,
+  LineHeight,
+} from '../../extensions/theme'
 import { indentUnit } from '@codemirror/language'
 import { Highlight } from '../../services/types/doc'
 import useIsMounted from '../../../../shared/hooks/use-is-mounted'
@@ -21,7 +28,7 @@ import Icon from '../../../../shared/components/icon'
 import { useTranslation } from 'react-i18next'
 import { inlineBackground } from '../../../source-editor/extensions/inline-background'
 
-function extensions(): Extension[] {
+function extensions(themeOptions: Options): Extension[] {
   return [
     EditorView.editable.of(false),
     EditorView.contentAttributes.of({ tabindex: '0' }),
@@ -31,7 +38,7 @@ function extensions(): Extension[] {
     indentationMarkers({ hideFirstIndent: true, highlightActiveBlock: false }),
     highlights(),
     highlightLocations(),
-    theme(),
+    theme(themeOptions),
     inlineBackground(false),
   ]
 }
@@ -43,13 +50,20 @@ function DocumentDiffViewer({
   doc: string
   highlights: Highlight[]
 }) {
+  const [fontFamily] = useScopeValue<FontFamily>('settings.fontFamily')
+  const [fontSize] = useScopeValue<number>('settings.fontSize')
+  const [lineHeight] = useScopeValue<LineHeight>('settings.lineHeight')
   const isMounted = useIsMounted()
   const { t } = useTranslation()
 
   const [state, setState] = useState(() => {
     return EditorState.create({
       doc,
-      extensions: extensions(),
+      extensions: extensions({
+        fontSize,
+        fontFamily,
+        lineHeight,
+      }),
     })
   })
 
@@ -107,6 +121,18 @@ function DocumentDiffViewer({
     })
   }, [doc, highlights, view])
 
+  // Update the document diff viewer theme whenever the font size, font family
+  // or line height user setting changes
+  useEffect(() => {
+    view.dispatch(
+      setOptionsTheme({
+        fontSize,
+        fontFamily,
+        lineHeight,
+      })
+    )
+  }, [view, fontSize, fontFamily, lineHeight])
+
   return (
     <div className="document-diff-container">
       <div ref={containerRef} className="cm-viewer-container" />

+ 70 - 30
services/web/frontend/js/features/history/extensions/theme.ts

@@ -1,32 +1,72 @@
 import { EditorView } from '@codemirror/view'
+import { Compartment, TransactionSpec } from '@codemirror/state'
 
-const fontFamily = 'Monaco, Menlo, Ubuntu Mono, Consolas, monospace'
-
-export const theme = () =>
-  EditorView.theme({
-    '&.cm-editor': {
-      '--font-size': '12px',
-      '--source-font-family': fontFamily,
-      '--line-height': 1.6,
-    },
-    '.cm-content': {
-      fontSize: 'var(--font-size)',
-      fontFamily: 'var(--source-font-family)',
-      lineHeight: 'var(--line-height)',
-      color: '#000',
-    },
-    '.cm-gutters': {
-      fontSize: 'var(--font-size)',
-      lineHeight: 'var(--line-height)',
-    },
-    '.cm-tooltip': {
-      // Set variables for tooltips, which are outside the editor
-      '--font-size': '12px',
-      '--source-font-family': fontFamily,
-      // NOTE: fontFamily is not set here, as most tooltips use the UI font
-      fontSize: 'var(--font-size)',
-    },
-    '.cm-lineNumbers': {
-      fontFamily: 'var(--source-font-family)',
-    },
-  })
+export type FontFamily = 'monaco' | 'lucida'
+export type LineHeight = 'compact' | 'normal' | 'wide'
+
+export type Options = {
+  fontSize: number
+  fontFamily: FontFamily
+  lineHeight: LineHeight
+}
+
+const optionsThemeConf = new Compartment()
+
+export const theme = (options: Options) => [
+  optionsThemeConf.of(createThemeFromOptions(options)),
+]
+
+export const lineHeights: Record<LineHeight, number> = {
+  compact: 1.33,
+  normal: 1.6,
+  wide: 2,
+}
+
+const fontFamilies: Record<FontFamily, string[]> = {
+  monaco: ['Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'monospace'],
+  lucida: ['Lucida Console', 'Source Code Pro', 'monospace'],
+}
+
+const createThemeFromOptions = ({
+  fontSize = 12,
+  fontFamily = 'monaco',
+  lineHeight = 'normal',
+}: Options) => {
+  // Theme styles that depend on settings
+  const fontFamilyValue = fontFamilies[fontFamily]?.join(', ')
+  return [
+    EditorView.theme({
+      '&.cm-editor': {
+        '--font-size': `${fontSize}px`,
+        '--source-font-family': fontFamilyValue,
+        '--line-height': lineHeights[lineHeight],
+      },
+      '.cm-content': {
+        fontSize: 'var(--font-size)',
+        fontFamily: 'var(--source-font-family)',
+        lineHeight: 'var(--line-height)',
+        color: '#000',
+      },
+      '.cm-gutters': {
+        fontSize: 'var(--font-size)',
+        lineHeight: 'var(--line-height)',
+      },
+      '.cm-tooltip': {
+        // Set variables for tooltips, which are outside the editor
+        '--font-size': `${fontSize}px`,
+        '--source-font-family': fontFamilyValue,
+        // NOTE: fontFamily is not set here, as most tooltips use the UI font
+        fontSize: 'var(--font-size)',
+      },
+      '.cm-lineNumbers': {
+        fontFamily: 'var(--source-font-family)',
+      },
+    }),
+  ]
+}
+
+export const setOptionsTheme = (options: Options): TransactionSpec => {
+  return {
+    effects: optionsThemeConf.reconfigure(createThemeFromOptions(options)),
+  }
+}