mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-12 13:13:45 +01:00
Merge pull request #35725 from overleaf/ds-unable-to-sync-modal
[WEB] adds unable-to-sync modal for intermittent connection improvements GitOrigin-RevId: 4cd85cf742cb3f36cc0c97f83bdeab09bb6f7c53
This commit is contained in:
@@ -543,6 +543,7 @@
|
||||
"download_as_source_zip": "",
|
||||
"download_csv": "",
|
||||
"download_file": "",
|
||||
"download_local_version": "",
|
||||
"download_metadata": "",
|
||||
"download_pdf": "",
|
||||
"download_zip_file": "",
|
||||
@@ -1358,6 +1359,7 @@
|
||||
"of": "",
|
||||
"off": "",
|
||||
"official": "",
|
||||
"offline_edits_couldnt_be_synced_detail": "",
|
||||
"ok": "",
|
||||
"ok_continue_to_project": "",
|
||||
"ok_join_project": "",
|
||||
@@ -2551,6 +2553,7 @@
|
||||
"your_name_and_email_address_will_be_visible_to_project_editors": "",
|
||||
"your_name_and_email_address_will_be_visible_to_the_project_owner_and_other_editors": "",
|
||||
"your_new_plan": "",
|
||||
"your_offline_edits_couldnt_be_synced": "",
|
||||
"your_password_was_detected": "",
|
||||
"your_plan": "",
|
||||
"your_plan_is_changing_at_term_end": "",
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { memo, useCallback } from 'react'
|
||||
import OLButton from '@/shared/components/ol/ol-button'
|
||||
import {
|
||||
OLModal,
|
||||
OLModalBody,
|
||||
OLModalFooter,
|
||||
OLModalHeader,
|
||||
OLModalTitle,
|
||||
} from '@/shared/components/ol/ol-modal'
|
||||
import { downloadFileContent } from '@/utils/download-file'
|
||||
|
||||
export type UnableToSyncModalProps = {
|
||||
editorContent: string
|
||||
docName: string | null
|
||||
show: boolean
|
||||
onHide: () => void
|
||||
}
|
||||
|
||||
function UnableToSyncModal({
|
||||
editorContent,
|
||||
docName,
|
||||
show,
|
||||
onHide,
|
||||
}: UnableToSyncModalProps) {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const handleDownload = useCallback(() => {
|
||||
downloadFileContent(editorContent, docName ?? 'document.txt')
|
||||
}, [editorContent, docName])
|
||||
|
||||
return (
|
||||
<OLModal
|
||||
show={show}
|
||||
onHide={onHide}
|
||||
backdrop="static"
|
||||
keyboard={false}
|
||||
centered
|
||||
>
|
||||
<OLModalHeader>
|
||||
<OLModalTitle>{t('your_offline_edits_couldnt_be_synced')}</OLModalTitle>
|
||||
</OLModalHeader>
|
||||
<OLModalBody>{t('offline_edits_couldnt_be_synced_detail')}</OLModalBody>
|
||||
<OLModalFooter>
|
||||
<OLButton variant="primary" onClick={handleDownload}>
|
||||
{t('download_local_version')}
|
||||
</OLButton>
|
||||
</OLModalFooter>
|
||||
</OLModal>
|
||||
)
|
||||
}
|
||||
|
||||
export default memo(UnableToSyncModal)
|
||||
@@ -12,6 +12,9 @@ import GenericMessageModal, {
|
||||
import OutOfSyncModal, {
|
||||
OutOfSyncModalProps,
|
||||
} from '@/features/ide-react/components/modals/out-of-sync-modal'
|
||||
import UnableToSyncModal, {
|
||||
UnableToSyncModalProps,
|
||||
} from '@/features/ide-react/components/modals/unable-to-sync-modal'
|
||||
import GenericConfirmModal, {
|
||||
GenericConfirmModalOwnProps,
|
||||
} from '../components/modals/generic-confirm-modal'
|
||||
@@ -26,6 +29,10 @@ type ModalsContextValue = {
|
||||
showOutOfSyncModal: (
|
||||
editorContent: OutOfSyncModalProps['editorContent']
|
||||
) => void
|
||||
showUnableToSyncModal: (
|
||||
editorContent: UnableToSyncModalProps['editorContent'],
|
||||
docName: UnableToSyncModalProps['docName']
|
||||
) => void
|
||||
}
|
||||
|
||||
const ModalsContext = createContext<ModalsContextValue | undefined>(undefined)
|
||||
@@ -50,6 +57,16 @@ export const ModalsContextProvider: FC<React.PropsWithChildren> = ({
|
||||
editorContent: '',
|
||||
})
|
||||
|
||||
const [shouldShowUnableToSyncModal, setShouldShowUnableToSyncModal] =
|
||||
useState(false)
|
||||
const [unableToSyncModalData, setUnableToSyncModalData] = useState<{
|
||||
editorContent: string
|
||||
docName: string | null
|
||||
}>({
|
||||
editorContent: '',
|
||||
docName: null,
|
||||
})
|
||||
|
||||
const handleHideGenericModal = useCallback(() => {
|
||||
setShowGenericModal(false)
|
||||
}, [])
|
||||
@@ -91,18 +108,32 @@ export const ModalsContextProvider: FC<React.PropsWithChildren> = ({
|
||||
setShouldShowOutOfSyncModal(true)
|
||||
}, [])
|
||||
|
||||
const handleHideUnableToSyncModal = useCallback(() => {
|
||||
setShouldShowUnableToSyncModal(false)
|
||||
}, [])
|
||||
|
||||
const showUnableToSyncModal = useCallback(
|
||||
(editorContent: string, docName: string | null) => {
|
||||
setUnableToSyncModalData({ editorContent, docName })
|
||||
setShouldShowUnableToSyncModal(true)
|
||||
},
|
||||
[]
|
||||
)
|
||||
|
||||
const value = useMemo<ModalsContextValue>(
|
||||
() => ({
|
||||
showGenericMessageModal,
|
||||
showGenericConfirmModal,
|
||||
genericModalVisible: showGenericModal,
|
||||
showOutOfSyncModal,
|
||||
showUnableToSyncModal,
|
||||
}),
|
||||
[
|
||||
showGenericMessageModal,
|
||||
showGenericConfirmModal,
|
||||
showGenericModal,
|
||||
showOutOfSyncModal,
|
||||
showUnableToSyncModal,
|
||||
]
|
||||
)
|
||||
|
||||
@@ -125,6 +156,11 @@ export const ModalsContextProvider: FC<React.PropsWithChildren> = ({
|
||||
show={shouldShowOutOfSyncModal}
|
||||
onHide={handleHideOutOfSyncModal}
|
||||
/>
|
||||
<UnableToSyncModal
|
||||
{...unableToSyncModalData}
|
||||
show={shouldShowUnableToSyncModal}
|
||||
onHide={handleHideUnableToSyncModal}
|
||||
/>
|
||||
</ModalsContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
+2
-9
@@ -3,6 +3,7 @@ import { useCodeMirrorViewContext } from '../codemirror-context'
|
||||
import { useCallback } from 'react'
|
||||
import { useEditorOpenDocContext } from '@/features/ide-react/context/editor-open-doc-context'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { downloadFileContent } from '@/utils/download-file'
|
||||
|
||||
const DownloadFileButton = () => {
|
||||
const view = useCodeMirrorViewContext()
|
||||
@@ -11,15 +12,7 @@ const DownloadFileButton = () => {
|
||||
|
||||
const downloadFile = useCallback(() => {
|
||||
const doc = view.state.doc.toString()
|
||||
const blob = new Blob([doc], { type: 'application/octet-stream' })
|
||||
const url = URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = openDocName ?? 'document.txt'
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
setTimeout(() => URL.revokeObjectURL(url), 0)
|
||||
downloadFileContent(doc, openDocName ?? 'document.txt')
|
||||
}, [view, openDocName])
|
||||
|
||||
return (
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
export function downloadFileContent(content: string, filename: string) {
|
||||
const blob = new Blob([content], { type: 'application/octet-stream' })
|
||||
const url = URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = filename
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
setTimeout(() => URL.revokeObjectURL(url), 0)
|
||||
}
|
||||
@@ -701,6 +701,7 @@
|
||||
"download_as_source_zip": "Download as source (.zip)",
|
||||
"download_csv": "Download CSV",
|
||||
"download_file": "Download file",
|
||||
"download_local_version": "Download local version",
|
||||
"download_metadata": "Download Overleaf metadata",
|
||||
"download_pdf": "Download PDF",
|
||||
"download_zip_file": "Download .zip file",
|
||||
@@ -1764,6 +1765,7 @@
|
||||
"october": "October",
|
||||
"off": "Off",
|
||||
"official": "Official",
|
||||
"offline_edits_couldnt_be_synced_detail": "This file changed while you were offline, so we’ve loaded the latest version. Download your local copy below to add back any changes you made.",
|
||||
"ok": "OK",
|
||||
"ok_continue_to_project": "OK, continue to project",
|
||||
"ok_join_project": "OK, join project",
|
||||
@@ -3214,6 +3216,7 @@
|
||||
"your_name_and_email_address_will_be_visible_to_project_editors": "Your name and email address will be visible to project editors.",
|
||||
"your_name_and_email_address_will_be_visible_to_the_project_owner_and_other_editors": "Your name and email address will be visible to the project owner and other editors.",
|
||||
"your_new_plan": "Your new plan",
|
||||
"your_offline_edits_couldnt_be_synced": "Your offline edits couldn’t be synced",
|
||||
"your_password_has_been_reset": "Your password has been reset",
|
||||
"your_password_has_been_successfully_changed": "Your password has been successfully changed",
|
||||
"your_password_was_detected": "Your password is on a <0>public list of known compromised passwords</0>. Keep your account safe by changing your password now.",
|
||||
|
||||
Reference in New Issue
Block a user