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

Conversation

Satvik1769
Copy link
Contributor

This pr solves issue #109
Using beforeUnload and popStatus event I solved the issue and tested it in various ways manually.
I believe conflicts will not occur now
Please merge this pr as soon as possible.

Regards,
Satvik

@Satvik1769 Satvik1769 requested a review from seveibar as a code owner October 30, 2024 06:04
Copy link

vercel bot commented Oct 30, 2024

@Satvik1769 is attempting to deploy a commit to the tscircuit Team on Vercel.

A member of the Team first needs to authorize it.

@seveibar
Copy link
Contributor

@Satvik1769 failing format check, you can fix with bun format

@@ -221,7 +227,7 @@ export const CodeEditor = ({
hoverTooltip((view, pos, side) => {
const { from, to, text } = view.state.doc.lineAt(pos)
const line = text.slice(from, to)
const match = line.match(/@tsci\/[\w\-.]+/)
const match = line.match(/@tsci\/[\w.]+/)
Copy link
Contributor

Choose a reason for hiding this comment

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

you reverted some fixes here. Make sure to only commit changes that are relevent for your fix

window.removeEventListener("beforeunload", handleBeforeUnload)
window.removeEventListener("popstate", handlePopState)
}
}, [hasUnsavedChanges])
Copy link
Contributor

Choose a reason for hiding this comment

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

this component (the CodeEditor) is already really big, can you put this code in the parent component? Also can you make a dedicated hook e.g. useWarnUserForUnsavedChanges(hasUnsavedChanges)

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 created a hook for the functionality now we just have to call it. it is in hooks folder with name useWarnUserForUnsavedChanges. I also reverted this code to previous state i.e.
const match = line.match(/@tsci/[\w-.]+/)

I hope there is no more conflicts and hope it helps.

Copy link
Contributor

@seveibar seveibar left a comment

Choose a reason for hiding this comment

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

see comments, looks like in the merge conflict you reverted some fixes. Try to only change code relevant for the PR

@Satvik1769
Copy link
Contributor Author

Ok will fix the issues

@Satvik1769 Satvik1769 requested a review from seveibar November 2, 2024 05:32
@@ -323,6 +328,10 @@ export const CodeEditor = ({
}
}, [!isStreaming, currentFile, code !== ""])

useWarnUserForUnsavedChanges({
hasUnsavedChanges: hasUnsavedChanges ?? false,
})
Copy link
Contributor

Choose a reason for hiding this comment

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

why does this have to be in the CodeEditor, can you move it to CodeAndPreview? This file is already very large and I don't see why this functionality has to be in here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes it can also be moved in CodeAndPreview and it will work fine.

)
if (!userConfirmed) {
// Push the state again to stay on the same page
window.history.pushState(null, "", window.location.href)
Copy link
Contributor

Choose a reason for hiding this comment

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

do we have to push state to stay on the same page? Can we just not do anything and block the action?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

state is necessary here this solution works by storing the current url in the state and if user clicks on cancel instead of sending it to previous page it send it to the current page

Copy link
Contributor

Choose a reason for hiding this comment

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

What would happen if you removed the pushState?

Copy link
Contributor

Choose a reason for hiding this comment

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

if i understand your code correctly, preventDefault stops the page from changing, so I'm not sure why you need to pushState

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It basically stores the current url (editor page) and only allows when cancelled. Is there a problem with storing the data in the state?

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 believe to add this functionality we will need to have states involved. However, if you have better method in mind I can make it .

Copy link
Contributor

Choose a reason for hiding this comment

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

let's remove the pushStates, if we only work for reloading that's OK for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

as you wish but i will just comment out that part just in case you want to update

Copy link
Contributor

Choose a reason for hiding this comment

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

let's just remove it, i'd rather not have ghost code, people can come back and look at this PR.

Also make sure to revert the changes to files where things were accidentally changed. I'll leave some comments that indicate where that happened. There should be no changes to CodeEditor (IIUC), you can run git checkout origin/main -- path/to/file to revert a file

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok will do


// Push the initial state only once, when component mounts
if (hasUnsavedChanges) {
window.history.pushState(null, "", window.location.href)
Copy link
Contributor

Choose a reason for hiding this comment

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

why do we need to push state here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we push the states two times:

  1. At the starting of mounting if there is some unsaved changes
  2. if person goes black but cancels then we repush the state to prevent moving back

@@ -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

`${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

@@ -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 😁

@Satvik1769 Satvik1769 closed this Nov 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants