Skip to content

Commit 5714309

Browse files
Require confirmation before closing dialog if unsaved changes are present.
1 parent fe891f1 commit 5714309

File tree

2 files changed

+64
-13
lines changed

2 files changed

+64
-13
lines changed

src/popup.tsx

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {
3636
PreviewContext,
3737
SearchJsonResponseItemWithMetadata,
3838
UrlMentionContainer,
39+
FormState,
3940
} from "./types";
4041
import {
4142
getLocalSettings,
@@ -151,6 +152,8 @@ if (!document.getElementById(ROOT_CONTAINER_ID)) {
151152
const [formHeaders, setFormHeaders] = useState<Record<string, any>>({});
152153
const [formContent, setFormContent] = useState<string>("");
153154

155+
const [originalFormState, setOriginalFormState] = useState<FormState>();
156+
154157
const [compiledUrl, setCompiledUrl] = useState<string>("");
155158
const [compiledContent, setCompiledContent] = useState<string>("");
156159
const [contentIsValid, setContentIsValid] = useState<boolean>(false);
@@ -170,9 +173,21 @@ if (!document.getElementById(ROOT_CONTAINER_ID)) {
170173
>("loading");
171174

172175
const turndown = new Turndown(TurndownConfiguration);
173-
174176
turndown.use(gfm);
175177

178+
const formStateMatches = React.useCallback(
179+
(originalState: FormState, currentState: FormState) => {
180+
return (
181+
originalState.method === currentState.method &&
182+
originalState.url === currentState.url &&
183+
JSON.stringify(originalState.headers) ===
184+
JSON.stringify(currentState.headers) &&
185+
originalState.content === currentState.content
186+
);
187+
},
188+
[]
189+
);
190+
176191
useEffect(() => {
177192
if (
178193
apiKey === undefined ||
@@ -210,6 +225,13 @@ if (!document.getElementById(ROOT_CONTAINER_ID)) {
210225
setFormUrl(selectedPreset.urlTemplate);
211226
setFormHeaders(selectedPreset.headers);
212227
setFormContent(selectedPreset.contentTemplate);
228+
229+
setOriginalFormState({
230+
method: selectedPreset.method,
231+
url: selectedPreset.urlTemplate,
232+
headers: selectedPreset.headers,
233+
content: selectedPreset.contentTemplate,
234+
});
213235
}, [selectedPreset]);
214236

215237
const [mouseOverTarget, setMouseOverTarget] = useState<HTMLAnchorElement>();
@@ -596,7 +618,7 @@ if (!document.getElementById(ROOT_CONTAINER_ID)) {
596618
title: "All done!",
597619
message: "Your content was sent to Obsidian successfully.",
598620
});
599-
setTimeout(() => onFinished(), 1500);
621+
setTimeout(() => onFinished(true), 1500);
600622
} else {
601623
try {
602624
const body = result.data ?? {};
@@ -639,10 +661,27 @@ if (!document.getElementById(ROOT_CONTAINER_ID)) {
639661
setSuggestionAccepted(true);
640662
};
641663

642-
const onFinished = () => {
643-
setPopupFormDisplayed(false);
644-
setPopupDisplayed(false);
645-
setStatus(undefined);
664+
const hasNoUnsavedChangesOrConfirmed = (): boolean => {
665+
return Boolean(
666+
!originalFormState ||
667+
formStateMatches(originalFormState, {
668+
method: formMethod,
669+
url: formUrl,
670+
headers: formHeaders,
671+
content: formContent,
672+
}) ||
673+
window.confirm(
674+
"You have unsaved changes; if you continue, those changes will be lost! Continue?"
675+
)
676+
);
677+
};
678+
679+
const onFinished = (force?: boolean) => {
680+
if (force || hasNoUnsavedChangesOrConfirmed()) {
681+
setPopupFormDisplayed(false);
682+
setPopupDisplayed(false);
683+
setStatus(undefined);
684+
}
646685
};
647686

648687
return (
@@ -835,13 +874,18 @@ if (!document.getElementById(ROOT_CONTAINER_ID)) {
835874
className="preset-selector"
836875
value={selectedPresetIdx}
837876
fullWidth={true}
838-
onChange={(event) =>
839-
setSelectedPresetIdx(
840-
typeof event.target.value === "number"
841-
? event.target.value
842-
: parseInt(event.target.value, 10)
843-
)
844-
}
877+
onChange={(event) => {
878+
console.log(
879+
`Changing preset to ${event.target.value}`
880+
);
881+
if (hasNoUnsavedChangesOrConfirmed()) {
882+
setSelectedPresetIdx(
883+
typeof event.target.value === "number"
884+
? event.target.value
885+
: parseInt(event.target.value, 10)
886+
);
887+
}
888+
}}
845889
>
846890
{suggestionAccepted && searchMatchTemplate && (
847891
<option key={"___suggestion"} value={-2}>

src/types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,3 +260,10 @@ export interface GithubRelease {
260260
tag_name: string;
261261
html_url: string;
262262
}
263+
264+
export interface FormState {
265+
method: UrlOutputPreset["method"];
266+
url: string;
267+
headers: Record<string, any>;
268+
content: string;
269+
}

0 commit comments

Comments
 (0)