Skip to content

Commit d8084e4

Browse files
committed
feat: add confirm dialog for leaving the page if an upload is in progress
1 parent e1a5d19 commit d8084e4

File tree

4 files changed

+60
-3
lines changed

4 files changed

+60
-3
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { useRouter } from "next/router";
2+
import { useEffect } from "react";
3+
4+
const useConfirmLeave = ({
5+
message,
6+
enabled,
7+
}: {
8+
message: string;
9+
enabled: boolean;
10+
}) => {
11+
const router = useRouter();
12+
13+
useEffect(() => {
14+
if (!enabled) return;
15+
16+
// Show confirmation dialog when route changes
17+
const handleRouteChange = () => {
18+
const confirmLeave = window.confirm(message);
19+
if (!confirmLeave) {
20+
router.events.emit("routeChangeError");
21+
throw "Route change aborted.";
22+
}
23+
};
24+
25+
// Show confirmation when the user tries to leave or reload the page
26+
const handleBeforeUnload = (event: BeforeUnloadEvent) => {
27+
event.preventDefault();
28+
event.returnValue = message;
29+
return message;
30+
};
31+
32+
router.events.on("routeChangeStart", handleRouteChange);
33+
window.addEventListener("beforeunload", handleBeforeUnload);
34+
35+
return () => {
36+
router.events.off("routeChangeStart", handleRouteChange);
37+
window.removeEventListener("beforeunload", handleBeforeUnload);
38+
};
39+
}, [router, message, enabled]);
40+
};
41+
42+
export default useConfirmLeave;

frontend/src/i18n/translations/en-US.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,8 @@ export default {
286286
// /upload
287287
"upload.title": "Upload",
288288

289+
"upload.notify.confirm-leave":
290+
"Are you sure you want to leave this page? Your upload will be canceled.",
289291
"upload.notify.generic-error":
290292
"An error occurred while finishing your share.",
291293
"upload.notify.count-failed": "{count} files failed to upload. Trying again.",

frontend/src/pages/share/[shareId]/edit.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ import { LoadingOverlay } from "@mantine/core";
22
import { useModals } from "@mantine/modals";
33
import { GetServerSidePropsContext } from "next";
44
import { useEffect, useState } from "react";
5+
import Meta from "../../../components/Meta";
56
import showErrorModal from "../../../components/share/showErrorModal";
7+
import EditableUpload from "../../../components/upload/EditableUpload";
8+
import useConfirmLeave from "../../../hooks/confirm-leave.hook";
9+
import useTranslate from "../../../hooks/useTranslate.hook";
610
import shareService from "../../../services/share.service";
711
import { Share as ShareType } from "../../../types/share.type";
8-
import useTranslate from "../../../hooks/useTranslate.hook";
9-
import EditableUpload from "../../../components/upload/EditableUpload";
10-
import Meta from "../../../components/Meta";
1112

1213
export function getServerSideProps(context: GetServerSidePropsContext) {
1314
return {
@@ -18,9 +19,15 @@ export function getServerSideProps(context: GetServerSidePropsContext) {
1819
const Share = ({ shareId }: { shareId: string }) => {
1920
const t = useTranslate();
2021
const modals = useModals();
22+
2123
const [isLoading, setIsLoading] = useState(true);
2224
const [share, setShare] = useState<ShareType>();
2325

26+
useConfirmLeave({
27+
message: t("upload.notify.confirm-leave"),
28+
enabled: isLoading,
29+
});
30+
2431
useEffect(() => {
2532
shareService
2633
.getFromOwner(shareId)

frontend/src/pages/upload/index.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import FileList from "../../components/upload/FileList";
1111
import showCompletedUploadModal from "../../components/upload/modals/showCompletedUploadModal";
1212
import showCreateUploadModal from "../../components/upload/modals/showCreateUploadModal";
1313
import useConfig from "../../hooks/config.hook";
14+
import useConfirmLeave from "../../hooks/confirm-leave.hook";
1415
import useTranslate from "../../hooks/useTranslate.hook";
1516
import useUser from "../../hooks/user.hook";
1617
import shareService from "../../services/share.service";
@@ -39,6 +40,11 @@ const Upload = ({
3940
const [files, setFiles] = useState<FileUpload[]>([]);
4041
const [isUploading, setisUploading] = useState(false);
4142

43+
useConfirmLeave({
44+
message: t("upload.notify.confirm-leave"),
45+
enabled: isUploading,
46+
});
47+
4248
const chunkSize = useRef(parseInt(config.get("share.chunkSize")));
4349

4450
maxShareSize ??= parseInt(config.get("share.maxSize"));

0 commit comments

Comments
 (0)