Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: Warn user if they leave the /editor page with unsaved changes #109 #139

Closed
wants to merge 10 commits into from
2 changes: 2 additions & 0 deletions src/components/CodeAndPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { useEffect, useMemo, useState } from "react"
import { useMutation, useQueryClient } from "react-query"
import EditorNav from "./EditorNav"
import { PreviewContent } from "./PreviewContent"
import useWarnUserForUnsavedChanges from "@/hooks/useWarnUserForUnsavedChanges"

interface Props {
snippet?: Snippet | null
Expand Down Expand Up @@ -118,6 +119,7 @@ export function CodeAndPreview({ snippet }: Props) {
}

const hasUnsavedChanges = snippet?.code !== code
useWarnUserForUnsavedChanges({ hasUnsavedChanges })

if (!snippet && (urlParams.snippet_id || urlParams.should_create_snippet)) {
return (
Expand Down
12 changes: 8 additions & 4 deletions src/components/CodeEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export const CodeEditor = ({
onDtsChange?: (dts: string) => void
initialCode: string
readOnly?: boolean
manualEditsJson?: string
isStreaming?: boolean
manualEditsFileContent: string
showImportAndFormatButtons?: boolean
Expand Down Expand Up @@ -86,7 +87,6 @@ export const CodeEditor = ({
Object.entries(files).forEach(([filename, content]) => {
fsMap.set(filename, content)
})

createDefaultMapFromCDN(
{ target: ts.ScriptTarget.ES2022 },
"5.6.3",
Expand Down Expand Up @@ -128,9 +128,13 @@ export const CodeEditor = ({
.replace(registryPrefixes[2], "")
const packageName = fullPackageName.split("/")[0].replace(/\./, "/")
const pathInPackage = fullPackageName.split("/").slice(1).join("/")
const jsdelivrPath = `${packageName}${pathInPackage ? `/${pathInPackage}` : ""}`
const jsdelivrPath = `${packageName}${
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert unnecessary change here

pathInPackage ? `/${pathInPackage}` : ""
}`
return fetch(
`${apiUrl}/snippets/download?jsdelivr_resolve=${input.includes("/resolve/")}&jsdelivr_path=${encodeURIComponent(jsdelivrPath)}`,
`${apiUrl}/snippets/download?jsdelivr_resolve=${input.includes(
"/resolve/",
)}&jsdelivr_path=${encodeURIComponent(jsdelivrPath)}`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert unnecessary change here

)
}
return fetch(input, init)
Expand Down Expand Up @@ -263,7 +267,7 @@ export const CodeEditor = ({
for (let pos = from; pos < to; ) {
const line = view.state.doc.lineAt(pos)
const lineText = line.text
const matches = lineText.matchAll(/@tsci\/[\w\-.]+/g)
const matches = lineText.matchAll(/@tsci\/[\w.]+/g)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this would introduce a bug, revert

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am sorry for all this trouble i am thinking to shut this pr and create a cleaner pr that is easier to manage for you and ofcourse myself

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes that's always ok!

Copy link
Contributor

@seveibar seveibar Nov 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and no problem- my messages are short because i often type them from my phone, not because i'm angry at you 😁

for (const match of matches) {
if (match.index !== undefined) {
const start = line.from + match.index
Expand Down
23 changes: 23 additions & 0 deletions src/hooks/useWarnUserForUnsavedChanges.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useEffect } from "react";
export default function useWarnUserForUnsavedChanges({
hasUnsavedChanges,
}: {
hasUnsavedChanges: boolean;
}) {
useEffect(() => {
const handleBeforeUnload = (event: BeforeUnloadEvent) => {
if (hasUnsavedChanges) {
event.preventDefault();
event.returnValue = ""; // Shows the confirmation dialog on reload or close if there are unsaved changes
}
};

// Attach event listeners
window.addEventListener("beforeunload", handleBeforeUnload);

// Cleanup event listeners on component unmount
return () => {
window.removeEventListener("beforeunload", handleBeforeUnload);
};
}, [hasUnsavedChanges]);
}
Loading