feat: add confirm dialog for leaving the page if an upload is in progress

This commit is contained in:
Elias Schneider
2024-11-14 18:04:11 +01:00
parent e1a5d19544
commit d8084e401d
4 changed files with 60 additions and 3 deletions

View File

@@ -0,0 +1,42 @@
import { useRouter } from "next/router";
import { useEffect } from "react";
const useConfirmLeave = ({
message,
enabled,
}: {
message: string;
enabled: boolean;
}) => {
const router = useRouter();
useEffect(() => {
if (!enabled) return;
// Show confirmation dialog when route changes
const handleRouteChange = () => {
const confirmLeave = window.confirm(message);
if (!confirmLeave) {
router.events.emit("routeChangeError");
throw "Route change aborted.";
}
};
// Show confirmation when the user tries to leave or reload the page
const handleBeforeUnload = (event: BeforeUnloadEvent) => {
event.preventDefault();
event.returnValue = message;
return message;
};
router.events.on("routeChangeStart", handleRouteChange);
window.addEventListener("beforeunload", handleBeforeUnload);
return () => {
router.events.off("routeChangeStart", handleRouteChange);
window.removeEventListener("beforeunload", handleBeforeUnload);
};
}, [router, message, enabled]);
};
export default useConfirmLeave;

View File

@@ -286,6 +286,8 @@ export default {
// /upload
"upload.title": "Upload",
"upload.notify.confirm-leave":
"Are you sure you want to leave this page? Your upload will be canceled.",
"upload.notify.generic-error":
"An error occurred while finishing your share.",
"upload.notify.count-failed": "{count} files failed to upload. Trying again.",

View File

@@ -2,12 +2,13 @@ import { LoadingOverlay } from "@mantine/core";
import { useModals } from "@mantine/modals";
import { GetServerSidePropsContext } from "next";
import { useEffect, useState } from "react";
import Meta from "../../../components/Meta";
import showErrorModal from "../../../components/share/showErrorModal";
import EditableUpload from "../../../components/upload/EditableUpload";
import useConfirmLeave from "../../../hooks/confirm-leave.hook";
import useTranslate from "../../../hooks/useTranslate.hook";
import shareService from "../../../services/share.service";
import { Share as ShareType } from "../../../types/share.type";
import useTranslate from "../../../hooks/useTranslate.hook";
import EditableUpload from "../../../components/upload/EditableUpload";
import Meta from "../../../components/Meta";
export function getServerSideProps(context: GetServerSidePropsContext) {
return {
@@ -18,9 +19,15 @@ export function getServerSideProps(context: GetServerSidePropsContext) {
const Share = ({ shareId }: { shareId: string }) => {
const t = useTranslate();
const modals = useModals();
const [isLoading, setIsLoading] = useState(true);
const [share, setShare] = useState<ShareType>();
useConfirmLeave({
message: t("upload.notify.confirm-leave"),
enabled: isLoading,
});
useEffect(() => {
shareService
.getFromOwner(shareId)

View File

@@ -11,6 +11,7 @@ import FileList from "../../components/upload/FileList";
import showCompletedUploadModal from "../../components/upload/modals/showCompletedUploadModal";
import showCreateUploadModal from "../../components/upload/modals/showCreateUploadModal";
import useConfig from "../../hooks/config.hook";
import useConfirmLeave from "../../hooks/confirm-leave.hook";
import useTranslate from "../../hooks/useTranslate.hook";
import useUser from "../../hooks/user.hook";
import shareService from "../../services/share.service";
@@ -39,6 +40,11 @@ const Upload = ({
const [files, setFiles] = useState<FileUpload[]>([]);
const [isUploading, setisUploading] = useState(false);
useConfirmLeave({
message: t("upload.notify.confirm-leave"),
enabled: isUploading,
});
const chunkSize = useRef(parseInt(config.get("share.chunkSize")));
maxShareSize ??= parseInt(config.get("share.maxSize"));