mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #21526 from overleaf/dp-dismiss-equation-preview
Add options to disable/hide equation preview GitOrigin-RevId: 5f71b4c747bf27ae816bdfe32c6e3e5a42f99508
This commit is contained in:
parent
d95981cb0c
commit
dfcc805549
8 changed files with 412 additions and 50 deletions
|
@ -342,6 +342,10 @@
|
|||
"details_provided_by_google_explanation": "",
|
||||
"dictionary": "",
|
||||
"did_you_know_institution_providing_professional": "",
|
||||
"disable": "",
|
||||
"disable_equation_preview": "",
|
||||
"disable_equation_preview_confirm": "",
|
||||
"disable_equation_preview_enable": "",
|
||||
"disable_single_sign_on": "",
|
||||
"disable_sso": "",
|
||||
"disable_stop_on_first_error": "",
|
||||
|
@ -612,6 +616,7 @@
|
|||
"help_articles_matching": "",
|
||||
"help_improve_overleaf_fill_out_this_survey": "",
|
||||
"help_improve_screen_reader_fill_out_this_survey": "",
|
||||
"hide": "",
|
||||
"hide_configuration": "",
|
||||
"hide_deleted_user": "",
|
||||
"hide_document_preamble": "",
|
||||
|
@ -1047,6 +1052,7 @@
|
|||
"pending_invite": "",
|
||||
"percent_discount_for_groups": "",
|
||||
"percent_is_the_percentage_of_the_line_width": "",
|
||||
"permanently_disables_the_preview": "",
|
||||
"personal_library": "",
|
||||
"plan": "",
|
||||
"plan_tooltip": "",
|
||||
|
@ -1508,6 +1514,7 @@
|
|||
"template_description": "",
|
||||
"template_title_taken_from_project_title": "",
|
||||
"templates": "",
|
||||
"temporarily_hides_the_preview": "",
|
||||
"terminated": "",
|
||||
"test": "",
|
||||
"test_configuration": "",
|
||||
|
|
|
@ -18,6 +18,7 @@ import {
|
|||
CodeMirrorStateContext,
|
||||
CodeMirrorViewContext,
|
||||
} from './codemirror-context'
|
||||
import MathPreviewTooltip from './math-preview-tooltip'
|
||||
|
||||
// TODO: remove this when definitely no longer used
|
||||
export * from './codemirror-context'
|
||||
|
@ -39,6 +40,7 @@ function CodeMirrorEditor() {
|
|||
const isMounted = useIsMounted()
|
||||
|
||||
const newReviewPanel = useFeatureFlag('review-panel-redesign')
|
||||
const enableMathPreview = useFeatureFlag('math-preview')
|
||||
|
||||
// create the view using the initial state and intercept transactions
|
||||
const viewRef = useRef<EditorView | null>(null)
|
||||
|
@ -78,6 +80,7 @@ function CodeMirrorEditor() {
|
|||
)}
|
||||
<CodeMirrorCommandTooltip />
|
||||
|
||||
{enableMathPreview && <MathPreviewTooltip />}
|
||||
{newReviewPanel && <ReviewTooltipMenu />}
|
||||
<ReviewPanelMigration />
|
||||
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
import { useProjectSettingsContext } from '@/features/editor-left-menu/context/project-settings-context'
|
||||
import {
|
||||
Dropdown,
|
||||
DropdownMenu,
|
||||
DropdownToggle,
|
||||
} from '@/features/ui/components/bootstrap-5/dropdown-menu'
|
||||
import OLButton from '@/features/ui/components/ol/ol-button'
|
||||
import OLModal, {
|
||||
OLModalBody,
|
||||
OLModalFooter,
|
||||
OLModalHeader,
|
||||
OLModalTitle,
|
||||
} from '@/features/ui/components/ol/ol-modal'
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
import SplitTestBadge from '@/shared/components/split-test-badge'
|
||||
import useEventListener from '@/shared/hooks/use-event-listener'
|
||||
import { FC, useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import {
|
||||
useCodeMirrorStateContext,
|
||||
useCodeMirrorViewContext,
|
||||
} from './codemirror-context'
|
||||
import { mathPreviewStateField } from '../extensions/math-preview'
|
||||
import { getTooltip } from '@codemirror/view'
|
||||
import ReactDOM from 'react-dom'
|
||||
import OLDropdownMenuItem from '@/features/ui/components/ol/ol-dropdown-menu-item'
|
||||
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
|
||||
import ControlledDropdown from '@/shared/components/controlled-dropdown'
|
||||
import {
|
||||
Dropdown as BS3Dropdown,
|
||||
MenuItem as BS3MenuItem,
|
||||
} from 'react-bootstrap'
|
||||
|
||||
const MathPreviewTooltipContainer: FC = () => {
|
||||
const state = useCodeMirrorStateContext()
|
||||
const view = useCodeMirrorViewContext()
|
||||
|
||||
const mathPreviewState = state.field(mathPreviewStateField, false)
|
||||
|
||||
if (!mathPreviewState) {
|
||||
return null
|
||||
}
|
||||
|
||||
const { tooltip, mathContent } = mathPreviewState
|
||||
|
||||
if (!tooltip || !mathContent) {
|
||||
return null
|
||||
}
|
||||
|
||||
const tooltipView = getTooltip(view, tooltip)
|
||||
|
||||
if (!tooltipView) {
|
||||
return null
|
||||
}
|
||||
|
||||
return ReactDOM.createPortal(
|
||||
<MathPreviewTooltip mathContent={mathContent} />,
|
||||
tooltipView.dom
|
||||
)
|
||||
}
|
||||
|
||||
const MathPreviewTooltip: FC<{ mathContent: HTMLDivElement }> = ({
|
||||
mathContent,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const [showDisableModal, setShowDisableModal] = useState(false)
|
||||
const { setMathPreview } = useProjectSettingsContext()
|
||||
const openDisableModal = useCallback(() => setShowDisableModal(true), [])
|
||||
const closeDisableModal = useCallback(() => setShowDisableModal(false), [])
|
||||
|
||||
const onHide = useCallback(() => {
|
||||
window.dispatchEvent(new Event('editor:hideMathTooltip'))
|
||||
}, [])
|
||||
|
||||
const mathRef = useRef<HTMLSpanElement>(null)
|
||||
|
||||
const keyDownListener = useCallback(
|
||||
(event: KeyboardEvent) => {
|
||||
if (event.key === 'Escape') {
|
||||
onHide()
|
||||
}
|
||||
},
|
||||
[onHide]
|
||||
)
|
||||
|
||||
useEventListener('keydown', keyDownListener)
|
||||
|
||||
useEffect(() => {
|
||||
if (mathRef.current) {
|
||||
mathRef.current.replaceChildren(mathContent)
|
||||
}
|
||||
}, [mathContent])
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="ol-cm-math-tooltip">
|
||||
<span ref={mathRef} />
|
||||
<SplitTestBadge
|
||||
displayOnVariants={['enabled']}
|
||||
splitTestName="math-preview"
|
||||
/>
|
||||
<BootstrapVersionSwitcher
|
||||
bs5={
|
||||
<Dropdown align="end">
|
||||
<DropdownToggle
|
||||
id="some-id"
|
||||
className="math-tooltip-options-toggle"
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
>
|
||||
<MaterialIcon
|
||||
type="more_vert"
|
||||
accessibilityLabel={t('more_options')}
|
||||
/>
|
||||
</DropdownToggle>
|
||||
<DropdownMenu flip={false}>
|
||||
<li>
|
||||
<OLDropdownMenuItem
|
||||
onClick={onHide}
|
||||
description={t('temporarily_hides_the_preview')}
|
||||
trailingIcon={
|
||||
<span className="math-tooltip-options-keyboard-shortcut">
|
||||
Esc
|
||||
</span>
|
||||
}
|
||||
>
|
||||
{t('hide')}
|
||||
</OLDropdownMenuItem>
|
||||
</li>
|
||||
<li>
|
||||
<OLDropdownMenuItem
|
||||
onClick={openDisableModal}
|
||||
description={t('permanently_disables_the_preview')}
|
||||
>
|
||||
{t('disable')}
|
||||
</OLDropdownMenuItem>
|
||||
</li>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
}
|
||||
bs3={
|
||||
<ControlledDropdown id="math-preview-tooltip-options" pullRight>
|
||||
<BS3Dropdown.Toggle
|
||||
noCaret
|
||||
bsSize="small"
|
||||
bsStyle={null}
|
||||
className="math-tooltip-options-toggle"
|
||||
>
|
||||
<MaterialIcon
|
||||
type="more_vert"
|
||||
accessibilityLabel={t('more_options')}
|
||||
/>
|
||||
</BS3Dropdown.Toggle>
|
||||
<BS3Dropdown.Menu className="math-preview-tooltip-menu">
|
||||
<BS3MenuItem
|
||||
className="math-preview-tooltip-option"
|
||||
onClick={onHide}
|
||||
>
|
||||
<div className="math-preview-tooltip-option-content">
|
||||
<div className="math-preview-tooltip-option-label">
|
||||
{t('hide')}
|
||||
</div>
|
||||
<div className="math-preview-tooltip-option-description">
|
||||
{t('temporarily_hides_the_preview')}
|
||||
</div>
|
||||
</div>
|
||||
<div className="math-preview-tooltip-option-shortcut">
|
||||
Esc
|
||||
</div>
|
||||
</BS3MenuItem>
|
||||
<BS3MenuItem
|
||||
className="math-preview-tooltip-option"
|
||||
onClick={openDisableModal}
|
||||
>
|
||||
<div className="math-preview-tooltip-option-content">
|
||||
<div className="math-preview-tooltip-option-label">
|
||||
{t('disable')}
|
||||
</div>
|
||||
<div className="math-preview-tooltip-option-description">
|
||||
{t('permanently_disables_the_preview')}
|
||||
</div>
|
||||
</div>
|
||||
</BS3MenuItem>
|
||||
</BS3Dropdown.Menu>
|
||||
</ControlledDropdown>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{showDisableModal && (
|
||||
<OLModal show onHide={closeDisableModal}>
|
||||
<OLModalHeader>
|
||||
<OLModalTitle>{t('disable_equation_preview')}</OLModalTitle>
|
||||
</OLModalHeader>
|
||||
|
||||
<OLModalBody>
|
||||
{t('disable_equation_preview_confirm')}
|
||||
<br />
|
||||
<Trans
|
||||
i18nKey="disable_equation_preview_enable"
|
||||
components={{ b: <strong /> }}
|
||||
/>
|
||||
</OLModalBody>
|
||||
|
||||
<OLModalFooter>
|
||||
<OLButton variant="secondary" onClick={closeDisableModal}>
|
||||
{t('cancel')}
|
||||
</OLButton>
|
||||
<OLButton variant="danger" onClick={() => setMathPreview(false)}>
|
||||
{t('disable')}
|
||||
</OLButton>
|
||||
</OLModalFooter>
|
||||
</OLModal>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default MathPreviewTooltipContainer
|
|
@ -9,6 +9,7 @@ import {
|
|||
Compartment,
|
||||
EditorState,
|
||||
Extension,
|
||||
StateEffect,
|
||||
StateField,
|
||||
TransactionSpec,
|
||||
} from '@codemirror/state'
|
||||
|
@ -22,13 +23,11 @@ import {
|
|||
import { documentCommands } from '../languages/latex/document-commands'
|
||||
import { debugConsole } from '@/utils/debugging'
|
||||
import { isSplitTestEnabled } from '@/utils/splitTestUtils'
|
||||
import ReactDOM from 'react-dom'
|
||||
import { SplitTestProvider } from '@/shared/context/split-test-context'
|
||||
import SplitTestBadge from '@/shared/components/split-test-badge'
|
||||
import { nodeHasError } from '../utils/tree-operations/common'
|
||||
import { documentEnvironments } from '../languages/latex/document-environments'
|
||||
|
||||
const REPOSITION_EVENT = 'editor:repositionMathTooltips'
|
||||
const HIDE_TOOLTIP_EVENT = 'editor:hideMathTooltip'
|
||||
|
||||
export const mathPreview = (enabled: boolean): Extension => {
|
||||
if (!isSplitTestEnabled('math-preview')) {
|
||||
|
@ -40,38 +39,91 @@ export const mathPreview = (enabled: boolean): Extension => {
|
|||
)
|
||||
}
|
||||
|
||||
export const hideTooltipEffect = StateEffect.define<null>()
|
||||
|
||||
const mathPreviewConf = new Compartment()
|
||||
|
||||
export const setMathPreview = (enabled: boolean): TransactionSpec => ({
|
||||
effects: mathPreviewConf.reconfigure(enabled ? mathPreviewStateField : []),
|
||||
})
|
||||
|
||||
const mathPreviewStateField = StateField.define<Tooltip | null>({
|
||||
create: buildTooltip,
|
||||
export const mathPreviewStateField = StateField.define<{
|
||||
tooltip: Tooltip | null
|
||||
mathContent: HTMLDivElement | null
|
||||
hide: boolean
|
||||
}>({
|
||||
create: buildInitialState,
|
||||
|
||||
update(tooltips, tr) {
|
||||
if (tr.docChanged || tr.selection) {
|
||||
tooltips = buildTooltip(tr.state)
|
||||
update(state, tr) {
|
||||
for (const effect of tr.effects) {
|
||||
if (effect.is(hideTooltipEffect)) {
|
||||
return { tooltip: null, hide: true, mathContent: null }
|
||||
}
|
||||
}
|
||||
|
||||
return tooltips
|
||||
if (tr.docChanged || tr.selection) {
|
||||
const mathContainer = getMathContainer(tr.state)
|
||||
|
||||
if (mathContainer) {
|
||||
if (state.hide) {
|
||||
return { tooltip: null, hide: true, mathContent: null }
|
||||
} else {
|
||||
const mathContent = buildTooltipContent(tr.state, mathContainer)
|
||||
|
||||
return {
|
||||
tooltip: buildTooltip(mathContainer, mathContent),
|
||||
mathContent,
|
||||
hide: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { tooltip: null, hide: false, mathContent: null }
|
||||
}
|
||||
|
||||
return state
|
||||
},
|
||||
|
||||
provide: field => [
|
||||
showTooltip.compute([field], state => state.field(field)),
|
||||
showTooltip.compute([field], state => state.field(field).tooltip),
|
||||
|
||||
ViewPlugin.define(view => {
|
||||
const listener = () => repositionTooltips(view)
|
||||
const hideTooltip = () => {
|
||||
view.dispatch({
|
||||
effects: hideTooltipEffect.of(null),
|
||||
})
|
||||
}
|
||||
|
||||
window.addEventListener(REPOSITION_EVENT, listener)
|
||||
window.addEventListener(HIDE_TOOLTIP_EVENT, hideTooltip)
|
||||
|
||||
return {
|
||||
destroy() {
|
||||
window.removeEventListener(REPOSITION_EVENT, listener)
|
||||
window.removeEventListener(HIDE_TOOLTIP_EVENT, hideTooltip)
|
||||
},
|
||||
}
|
||||
}),
|
||||
],
|
||||
})
|
||||
|
||||
function buildInitialState(state: EditorState) {
|
||||
const mathContainer = getMathContainer(state)
|
||||
|
||||
if (mathContainer) {
|
||||
const mathContent = buildTooltipContent(state, mathContainer)
|
||||
|
||||
return {
|
||||
tooltip: buildTooltip(mathContainer, mathContent),
|
||||
mathContent,
|
||||
hide: false,
|
||||
}
|
||||
}
|
||||
|
||||
return { tooltip: null, hide: false, mathContent: null }
|
||||
}
|
||||
|
||||
const renderMath = async (
|
||||
content: string,
|
||||
displayMode: boolean,
|
||||
|
@ -96,17 +148,11 @@ const renderMath = async (
|
|||
element.append(math)
|
||||
}
|
||||
|
||||
function buildTooltip(state: EditorState): Tooltip | null {
|
||||
const range = state.selection.main
|
||||
|
||||
if (!range.empty) {
|
||||
return null
|
||||
}
|
||||
|
||||
const mathContainer = getMathContainer(state, range.from)
|
||||
const content = buildTooltipContent(state, mathContainer)
|
||||
|
||||
if (!content || !mathContainer) {
|
||||
function buildTooltip(
|
||||
mathContainer: MathContainer,
|
||||
mathContent: HTMLDivElement | null
|
||||
): Tooltip | null {
|
||||
if (!mathContent || !mathContainer) {
|
||||
return null
|
||||
}
|
||||
|
||||
|
@ -117,19 +163,22 @@ function buildTooltip(state: EditorState): Tooltip | null {
|
|||
arrow: false,
|
||||
create() {
|
||||
const dom = document.createElement('div')
|
||||
dom.append(content)
|
||||
const badge = renderSplitTestBadge()
|
||||
dom.append(badge)
|
||||
dom.className = 'ol-cm-math-tooltip'
|
||||
dom.classList.add('ol-cm-math-tooltip-container')
|
||||
|
||||
return { dom, overlap: true, offset: { x: 0, y: 8 } }
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const getMathContainer = (state: EditorState, pos: number) => {
|
||||
const getMathContainer = (state: EditorState) => {
|
||||
const range = state.selection.main
|
||||
|
||||
if (!range.empty) {
|
||||
return null
|
||||
}
|
||||
|
||||
// if anywhere inside Math, find the whole Math node
|
||||
const ancestorNode = mathAncestorNode(state, pos)
|
||||
const ancestorNode = mathAncestorNode(state, range.from)
|
||||
if (!ancestorNode) return null
|
||||
|
||||
const [node] = descendantsOfNodeWithType(ancestorNode, 'Math', 'Math')
|
||||
|
@ -182,30 +231,16 @@ const buildTooltipContent = (
|
|||
return element
|
||||
}
|
||||
|
||||
const renderSplitTestBadge = () => {
|
||||
const element = document.createElement('span')
|
||||
ReactDOM.render(
|
||||
<SplitTestProvider>
|
||||
<SplitTestBadge
|
||||
displayOnVariants={['enabled']}
|
||||
splitTestName="math-preview"
|
||||
/>
|
||||
</SplitTestProvider>,
|
||||
element
|
||||
)
|
||||
return element
|
||||
}
|
||||
|
||||
/**
|
||||
* Styles for the preview tooltip
|
||||
*/
|
||||
const mathPreviewTheme = EditorView.baseTheme({
|
||||
'&light .ol-cm-math-tooltip': {
|
||||
'&light .ol-cm-math-tooltip-container': {
|
||||
boxShadow: '0px 2px 4px 0px #1e253029',
|
||||
border: '1px solid #e7e9ee !important',
|
||||
backgroundColor: 'white !important',
|
||||
},
|
||||
'&dark .ol-cm-math-tooltip': {
|
||||
'&dark .ol-cm-math-tooltip-container': {
|
||||
boxShadow: '0px 2px 4px 0px #1e253029',
|
||||
border: '1px solid #2f3a4c !important',
|
||||
backgroundColor: '#1b222c !important',
|
|
@ -1,9 +1,74 @@
|
|||
.ol-cm-math-tooltip {
|
||||
.ol-cm-math-tooltip-container {
|
||||
position: relative;
|
||||
border-radius: 4px;
|
||||
max-height: 400px;
|
||||
max-width: 800px;
|
||||
overflow: auto;
|
||||
padding: 8px;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.ol-cm-math-tooltip {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
overflow: auto;
|
||||
padding: 8px;
|
||||
|
||||
.dropdown {
|
||||
position: static;
|
||||
}
|
||||
}
|
||||
|
||||
.math-tooltip-options-toggle {
|
||||
border: none;
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: transparent;
|
||||
color: black !important;
|
||||
|
||||
&:focus {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:active {
|
||||
background-color: @neutral-20;
|
||||
}
|
||||
}
|
||||
|
||||
.math-preview-tooltip-menu {
|
||||
top: 28px;
|
||||
right: 8px;
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
.math-preview-tooltip-option {
|
||||
a {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
div {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.math-preview-tooltip-option-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.math-preview-tooltip-option-label {
|
||||
color: @content-primary;
|
||||
}
|
||||
|
||||
.math-preview-tooltip-option-description {
|
||||
color: @content-secondary;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.math-preview-tooltip-option-shortcut {
|
||||
color: @content-secondary;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
@import 'editor/review-panel';
|
||||
@import 'editor/chat';
|
||||
@import 'editor/history';
|
||||
@import 'editor/math-preview';
|
||||
@import 'subscription';
|
||||
@import 'editor/pdf';
|
||||
@import 'editor/compile-button';
|
||||
|
@ -26,6 +25,7 @@
|
|||
@import 'editor/tags-input';
|
||||
@import 'editor/review-panel-new';
|
||||
@import 'editor/table-generator-column-width-modal';
|
||||
@import 'editor/math-preview';
|
||||
@import 'website-redesign';
|
||||
@import 'group-settings';
|
||||
@import 'templates-v2';
|
||||
|
|
|
@ -1,9 +1,34 @@
|
|||
.ol-cm-math-tooltip {
|
||||
.ol-cm-math-tooltip-container {
|
||||
position: relative;
|
||||
border-radius: var(--border-radius-base);
|
||||
max-height: 400px;
|
||||
max-width: 800px;
|
||||
overflow: auto;
|
||||
padding: var(--spacing-04);
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.ol-cm-math-tooltip {
|
||||
display: flex;
|
||||
gap: var(--spacing-04);
|
||||
overflow: auto;
|
||||
padding: var(--spacing-04);
|
||||
|
||||
.dropdown {
|
||||
position: static;
|
||||
}
|
||||
}
|
||||
|
||||
.math-tooltip-options-toggle {
|
||||
border: none;
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
|
||||
&::after {
|
||||
content: none;
|
||||
}
|
||||
}
|
||||
|
||||
.math-tooltip-options-keyboard-shortcut {
|
||||
color: $content-secondary;
|
||||
font-size: var(--font-size-02);
|
||||
}
|
||||
|
|
|
@ -468,6 +468,10 @@
|
|||
"details_provided_by_google_explanation": "Your details were provided by your Google account. Please check you’re happy with them.",
|
||||
"dictionary": "Dictionary",
|
||||
"did_you_know_institution_providing_professional": "Did you know that __institutionName__ is providing <0>free __appName__ Professional features</0> to everyone at __institutionName__?",
|
||||
"disable": "Disable",
|
||||
"disable_equation_preview": "Disable equation preview",
|
||||
"disable_equation_preview_confirm": "This will disable equation preview for you in all projects.",
|
||||
"disable_equation_preview_enable": "You can enable it again from the <b>Menu</b>.",
|
||||
"disable_single_sign_on": "Disable single sign-on",
|
||||
"disable_sso": "Disable SSO",
|
||||
"disable_stop_on_first_error": "Disable “Stop on first error”",
|
||||
|
@ -884,6 +888,7 @@
|
|||
"help_articles_matching": "Help articles matching your subject",
|
||||
"help_improve_overleaf_fill_out_this_survey": "If you would like to help us improve Overleaf, please take a moment to fill out <0>this survey</0>.",
|
||||
"help_improve_screen_reader_fill_out_this_survey": "Help us improve your experience using a screen reader with __appName__ by filling out this quick survey.",
|
||||
"hide": "Hide",
|
||||
"hide_configuration": "Hide configuration",
|
||||
"hide_deleted_user": "Hide deleted users",
|
||||
"hide_document_preamble": "Hide document preamble",
|
||||
|
@ -1510,6 +1515,7 @@
|
|||
"per_year": "per year",
|
||||
"percent_discount_for_groups": "__appName__ offers a __percent__% educational discount for groups of __size__ or more.",
|
||||
"percent_is_the_percentage_of_the_line_width": "% is the percentage of the line width",
|
||||
"permanently_disables_the_preview": "Permanently disables the preview",
|
||||
"personal": "Personal",
|
||||
"personal_library": "Personal library",
|
||||
"personalized_onboarding": "Personalized onboarding",
|
||||
|
@ -2102,6 +2108,7 @@
|
|||
"templates_lowercase": "templates",
|
||||
"templates_page_summary": "Start your projects with quality LaTeX templates for journals, CVs, resumes, papers, presentations, assignments, letters, project reports, and more. Search or browse below.",
|
||||
"templates_page_title": "Templates - Journals, CVs, Presentations, Reports and More",
|
||||
"temporarily_hides_the_preview": "Temporarily hides the preview",
|
||||
"ten_collaborators_per_project": "10 collaborators per project",
|
||||
"ten_per_project": "10 per project",
|
||||
"terminated": "Compilation cancelled",
|
||||
|
|
Loading…
Reference in a new issue