Add support of showing confirmation when leaving settings page with unsaved changes

pull/1930/head v1.1.1-beta.18
LASER-Yi 2 years ago
parent 0d39928a7b
commit 8eef455cc5

@ -3,9 +3,10 @@ import { Toolbox } from "@/components";
import { LoadingProvider } from "@/contexts";
import { useOnValueChange } from "@/utilities";
import { LOG } from "@/utilities/console";
import { usePrompt } from "@/utilities/routers";
import { useUpdateLocalStorage } from "@/utilities/storage";
import { faSave } from "@fortawesome/free-solid-svg-icons";
import { Container, Group, LoadingOverlay } from "@mantine/core";
import { Badge, Container, Group, LoadingOverlay } from "@mantine/core";
import { useDocumentTitle, useForm } from "@mantine/hooks";
import { FunctionComponent, ReactNode, useCallback, useMemo } from "react";
import { enabledLanguageKey, languageProfileKey } from "../keys";
@ -84,6 +85,11 @@ const Layout: FunctionComponent<Props> = (props) => {
return Object.keys(object).length;
}, [form.values.settings, form.values.storages]);
usePrompt(
totalStagedCount > 0,
`You have ${totalStagedCount} unsaved changes, are you sure you want to leave?`
);
useDocumentTitle(`${name} - Bazarr (Settings)`);
if (settings === undefined) {
@ -101,6 +107,11 @@ const Layout: FunctionComponent<Props> = (props) => {
icon={faSave}
loading={isMutating}
disabled={totalStagedCount === 0}
rightIcon={
<Badge size="xs" radius="sm" hidden={totalStagedCount === 0}>
{totalStagedCount}
</Badge>
}
>
Save
</Toolbox.Button>

@ -0,0 +1,40 @@
// A workaround of built-in hooks in React-Router v6
// https://gist.github.com/rmorse/426ffcc579922a82749934826fa9f743
import type { Blocker, History, Transition } from "history";
import { useContext, useEffect } from "react";
import { UNSAFE_NavigationContext } from "react-router-dom";
export function useBlocker(blocker: Blocker, when = true) {
const navigator = useContext(UNSAFE_NavigationContext).navigator as History;
useEffect(() => {
if (!when) return;
const unblock = navigator.block((tx: Transition) => {
const autoUnblockingTx = {
...tx,
retry() {
// Automatically unblock the transition so it can play all the way
// through before retrying it. TODO: Figure out how to re-enable
// this block if the transition is cancelled for some reason.
unblock();
tx.retry();
},
};
blocker(autoUnblockingTx);
});
return unblock;
}, [navigator, blocker, when]);
}
// TODO: Replace with Mantine's confirmation modal
export function usePrompt(when: boolean, message: string) {
useBlocker((tx) => {
if (window.confirm(message)) {
tx.retry();
}
}, when);
}
Loading…
Cancel
Save