diff --git a/public/locales/de-DE/application.json b/public/locales/de-DE/application.json index ee00306..5709edb 100644 --- a/public/locales/de-DE/application.json +++ b/public/locales/de-DE/application.json @@ -459,6 +459,7 @@ "conflictDes2": "<0>Die Datei wurde nach dem Öffnen von anderer Stelle mit einer neuen Version aktualisiert.<1>Wenn Sie unter einem neuen Dateinamen oder an einem neuen Ort gespeichert haben, existiert möglicherweise bereits eine Datei mit demselben Namen.", "saveAs": "Speichern unter", "versionConflict": "Versionskonflikt", + "discardUnsavedConfirm": "Sie haben ungespeicherte Änderungen. Möchten Sie sie verwerfen?", "overwrite": "Überschreiben", "editShareLink": "Freigabe-Link bearbeiten", "clearPermissions": "Berechtigungseinstellungen löschen", diff --git a/public/locales/en-US/application.json b/public/locales/en-US/application.json index 7f9b97c..f1ffaf6 100644 --- a/public/locales/en-US/application.json +++ b/public/locales/en-US/application.json @@ -424,6 +424,7 @@ "conflictDes2": "<0>The file was updated to a new version from elsewhere after you opened it.<1>If you saved it with a new name or a new location, the file name already exists.", "saveAs": "Save as", "versionConflict": "Version conflict", + "discardUnsavedConfirm": "You have unsaved changes. Still discard?", "overwrite": "Overwrite", "editShareLink": "Edit share link", "clearPermissions": "Clear permission settings", diff --git a/public/locales/es-ES/application.json b/public/locales/es-ES/application.json index 90d9d67..6a98db8 100644 --- a/public/locales/es-ES/application.json +++ b/public/locales/es-ES/application.json @@ -459,6 +459,7 @@ "conflictDes2": "<0>El archivo fue actualizado a una nueva versión desde otro lugar después de que lo abrieras.<1>Si lo guardaste con un nuevo nombre o nueva ubicación, el nombre de archivo ya existe.", "saveAs": "Guardar como", "versionConflict": "Conflicto de versión", + "discardUnsavedConfirm": "Tienes cambios sin guardar. ¿Deseas descartarlos?", "overwrite": "Sobrescribir", "editShareLink": "Editar enlace compartido", "clearPermissions": "Limpiar configuración de permisos", diff --git a/public/locales/fr-FR/application.json b/public/locales/fr-FR/application.json index b5f7729..65d6bbe 100644 --- a/public/locales/fr-FR/application.json +++ b/public/locales/fr-FR/application.json @@ -459,6 +459,7 @@ "conflictDes2": "<0>Le fichier a été mis à jour vers une nouvelle version depuis ailleurs après que vous l'ayez ouvert.<1>Si vous l'avez enregistré avec un nouveau nom ou un nouvel emplacement, le nom de fichier existe déjà.", "saveAs": "Enregistrer sous", "versionConflict": "Conflit de version", + "discardUnsavedConfirm": "Vous avez des modifications non enregistrées. Les abandonner ?", "overwrite": "Écraser", "editShareLink": "Modifier le lien de partage", "clearPermissions": "Effacer les paramètres d'autorisation", diff --git a/public/locales/it-IT/application.json b/public/locales/it-IT/application.json index 5fef10b..4981b0a 100644 --- a/public/locales/it-IT/application.json +++ b/public/locales/it-IT/application.json @@ -459,6 +459,7 @@ "conflictDes2": "<0>Il file è stato aggiornato a una nuova versione da altrove dopo che l'hai aperto.<1>Se l'hai salvato con un nuovo nome o in una nuova posizione, il nome del file esiste già.", "saveAs": "Salva come", "versionConflict": "Conflitto di versione", + "discardUnsavedConfirm": "Hai modifiche non salvate. Vuoi scartarle?", "overwrite": "Sovrascrivi", "editShareLink": "Modifica link di condivisione", "clearPermissions": "Pulisci impostazioni permessi", diff --git a/public/locales/ja-JP/application.json b/public/locales/ja-JP/application.json index 9b04108..2f006ca 100644 --- a/public/locales/ja-JP/application.json +++ b/public/locales/ja-JP/application.json @@ -424,6 +424,7 @@ "conflictDes2": "<0>ファイルを開いた後、別の場所から新しいバージョンで更新されました。<1>新しいファイル名または新しい場所に保存した場合、同名のファイルが既に存在する可能性があります。", "saveAs": "名前を付けて保存", "versionConflict": "バージョン競合", + "discardUnsavedConfirm": "保存されていない変更があります。破棄しますか?", "overwrite": "上書き", "editShareLink": "共有リンクの編集", "clearPermissions": "権限設定のクリア", diff --git a/public/locales/ko-KR/application.json b/public/locales/ko-KR/application.json index a9bdb54..c6c2e48 100644 --- a/public/locales/ko-KR/application.json +++ b/public/locales/ko-KR/application.json @@ -459,6 +459,7 @@ "conflictDes2": "<0>파일을 연 후 다른 곳에서 새 버전으로 업데이트되었습니다.<1>새 파일명이나 새 위치로 저장한 경우 동일한 이름의 파일이 이미 존재할 수 있습니다.", "saveAs": "다른 이름으로 저장", "versionConflict": "버전 충돌", + "discardUnsavedConfirm": "저장되지 않은 변경 사항이 있습니다. 삭제하시겠습니까?", "overwrite": "덮어쓰기", "editShareLink": "공유 링크 편집", "clearPermissions": "권한 설정 지우기", diff --git a/public/locales/pt-BR/application.json b/public/locales/pt-BR/application.json index 1fde109..455f450 100644 --- a/public/locales/pt-BR/application.json +++ b/public/locales/pt-BR/application.json @@ -459,6 +459,7 @@ "conflictDes2": "<0>O arquivo foi atualizado para uma nova versão de outro lugar depois que você o abriu.<1>Se você o salvou com um novo nome ou novo local, o nome do arquivo já existe.", "saveAs": "Salvar como", "versionConflict": "Conflito de versão", + "discardUnsavedConfirm": "Você tem alterações não salvas. Descartá-las?", "overwrite": "Sobrescrever", "editShareLink": "Editar link de compartilhamento", "clearPermissions": "Limpar configurações de permissão", diff --git a/public/locales/ru-RU/application.json b/public/locales/ru-RU/application.json index 5d46904..f2b8c56 100644 --- a/public/locales/ru-RU/application.json +++ b/public/locales/ru-RU/application.json @@ -459,6 +459,7 @@ "conflictDes2": "<0>Файл был обновлён до новой версии из другого места после того, как вы его открыли.<1>Если вы сохранили его с новым именем или в новом месте, возможно, файл с таким именем уже существует.", "saveAs": "Сохранить как", "versionConflict": "Конфликт версий", + "discardUnsavedConfirm": "У вас есть несохранённые изменения. Отменить их?", "overwrite": "Перезаписать", "editShareLink": "Редактировать ссылку на публикацию", "clearPermissions": "Очистить настройки разрешений", diff --git a/public/locales/zh-CN/application.json b/public/locales/zh-CN/application.json index 44047b0..2508a25 100644 --- a/public/locales/zh-CN/application.json +++ b/public/locales/zh-CN/application.json @@ -424,6 +424,7 @@ "conflictDes2": "<0>该文件在你打开后被从它处更新了新版本。<1>如果你另存为了新文件名或新位置,可能已有同名文件存在。", "saveAs": "另存为", "versionConflict": "版本冲突", + "discardUnsavedConfirm": "有未保存的更改,确定要关闭吗?", "overwrite": "覆盖", "editShareLink": "编辑分享链接", "clearPermissions": "清除权限设置", diff --git a/public/locales/zh-TW/application.json b/public/locales/zh-TW/application.json index f5b8bf2..5f97390 100644 --- a/public/locales/zh-TW/application.json +++ b/public/locales/zh-TW/application.json @@ -424,6 +424,7 @@ "conflictDes2": "<0>該檔案在你開啟後被從它處更新了新版本。<1>如果你另存為了新檔名或新位置,可能已有同名檔案存在。", "saveAs": "另存為", "versionConflict": "版本衝突", + "discardUnsavedConfirm": "有未儲存的變更,確定要關閉嗎?", "overwrite": "覆蓋", "editShareLink": "編輯分享連結", "clearPermissions": "清除許可權設定", diff --git a/src/component/Viewers/CodeViewer/CodeViewer.tsx b/src/component/Viewers/CodeViewer/CodeViewer.tsx index 8977dd0..b32aeae 100644 --- a/src/component/Viewers/CodeViewer/CodeViewer.tsx +++ b/src/component/Viewers/CodeViewer/CodeViewer.tsx @@ -15,6 +15,7 @@ import CaretDown from "../../Icons/CaretDown.tsx"; import Checkmark from "../../Icons/Checkmark.tsx"; import Setting from "../../Icons/Setting.tsx"; import ViewerDialog, { ViewerLoading } from "../ViewerDialog.tsx"; +import { confirmOperation } from "../../../redux/thunks/dialog.ts"; const MonacoEditor = lazy(() => import("./MonacoEditor.tsx")); @@ -109,6 +110,31 @@ const CodeViewer = () => { const [wordWrap, setWordWrap] = useState<"off" | "on" | "wordWrapColumn" | "bounded">("off"); const saveFunction = useRef<() => void>(() => {}); + const closeViewer = useCallback(() => { + dispatch(closeCodeViewer()); + }, [dispatch]); + + const handleDialogClose = useCallback( + (_: React.SyntheticEvent | object, reason?: "backdropClick" | "escapeKeyDown") => { + if (!saved && supportUpdate && (reason === "backdropClick" || reason === "escapeKeyDown")) { + dispatch( + confirmOperation( + t("application:modals.discardUnsavedConfirm"), + ), + ) + .then(() => { + closeViewer(); + }) + .catch(() => {}); + + return; + } + + closeViewer(); + }, + [closeViewer, saved, supportUpdate, t, dispatch], + ); + const loadContent = useCallback( (charset?: string) => { if (!viewerState || !viewerState.open) { @@ -123,10 +149,10 @@ const CodeViewer = () => { setLoaded(true); }) .catch(() => { - onClose(); + closeViewer(); }); }, - [viewerState], + [viewerState, closeViewer], ); useEffect(() => { @@ -140,10 +166,6 @@ const CodeViewer = () => { loadContent(); }, [viewerState?.open]); - const onClose = useCallback(() => { - dispatch(closeCodeViewer()); - }, [dispatch]); - const openMore = useCallback( (e: React.MouseEvent) => { setAnchorEl(e.currentTarget); @@ -227,7 +249,7 @@ const CodeViewer = () => { fullScreenToggle dialogProps={{ open: !!(viewerState && viewerState.open), - onClose: onClose, + onClose: handleDialogClose, fullWidth: true, maxWidth: "lg", }} diff --git a/src/component/Viewers/MarkdownEditor/MarkdownViewer.tsx b/src/component/Viewers/MarkdownEditor/MarkdownViewer.tsx index e14b4fb..cdfd68d 100644 --- a/src/component/Viewers/MarkdownEditor/MarkdownViewer.tsx +++ b/src/component/Viewers/MarkdownEditor/MarkdownViewer.tsx @@ -11,6 +11,7 @@ import { saveMarkdown, uploadMarkdownImage, } from "../../../redux/thunks/viewer.ts"; +import { confirmOperation } from "../../../redux/thunks/dialog.ts"; import { SquareMenuItem } from "../../FileManager/ContextMenu/ContextMenu.tsx"; import useActionDisplayOpt, { canUpdate } from "../../FileManager/ContextMenu/useActionDisplayOpt.ts"; import CaretDown from "../../Icons/CaretDown.tsx"; @@ -35,6 +36,31 @@ const MarkdownViewer = () => { const [optionAnchorEl, setOptionAnchorEl] = useState(null); const saveFunction = useRef(() => {}); + const closeViewer = useCallback(() => { + dispatch(closeMarkdownViewer()); + }, [dispatch]); + + const handleDialogClose = useCallback( + (_: React.SyntheticEvent | object, reason?: "backdropClick" | "escapeKeyDown") => { + if (!saved && supportUpdate && (reason === "backdropClick" || reason === "escapeKeyDown")) { + dispatch( + confirmOperation( + t("application:modals.discardUnsavedConfirm"), + ), + ) + .then(() => { + closeViewer(); + }) + .catch(() => {}); + + return; + } + + closeViewer(); + }, + [closeViewer, saved, supportUpdate, t, dispatch], + ); + const loadContent = useCallback(() => { if (!viewerState || !viewerState.open) { return; @@ -50,9 +76,9 @@ const MarkdownViewer = () => { setLoaded(true); }) .catch(() => { - onClose(); + closeViewer(); }); - }, [viewerState]); + }, [viewerState, closeViewer]); useEffect(() => { if (!viewerState || !viewerState.open) { @@ -70,10 +96,6 @@ const MarkdownViewer = () => { return dispatch(markdownImageAutocompleteSuggestions()); }, [viewerState?.open]); - const onClose = useCallback(() => { - dispatch(closeMarkdownViewer()); - }, [dispatch]); - const openMore = useCallback( (e: React.MouseEvent) => { setAnchorEl(e.currentTarget); @@ -154,7 +176,7 @@ const MarkdownViewer = () => { fullScreenToggle dialogProps={{ open: !!(viewerState && viewerState.open), - onClose: onClose, + onClose: handleDialogClose, fullWidth: true, maxWidth: "lg", }} diff --git a/src/component/Viewers/ViewerDialog.tsx b/src/component/Viewers/ViewerDialog.tsx index 3c5c7fe..396ef9b 100644 --- a/src/component/Viewers/ViewerDialog.tsx +++ b/src/component/Viewers/ViewerDialog.tsx @@ -44,7 +44,7 @@ const ViewerDialog = (props: ViewerDialogProps) => { const isMobile = useMediaQuery(theme.breakpoints.down("sm")); const [fullScreen, setFullScreen] = useState(props.fullScreen || isMobile); const onClose = useCallback(() => { - props.dialogProps.onClose && props.dialogProps.onClose({}, "backdropClick"); + props.dialogProps.onClose && props.dialogProps.onClose({}, "closeButtonClick" as any); }, [props.dialogProps.onClose]); return (