superblocks-lab icon indicating copy to clipboard operation
superblocks-lab copied to clipboard

Unexpected page reload when switching networks in metamask while the Deploy window is open

Open filippsen opened this issue 6 years ago • 5 comments

Description

While having the network set to an external network, for example Rinkeby, whenever a network switch happens in MetaMask, the extension triggers a complete page reload (forced refresh). Unsaved changes are lost in the process.

Steps to reproduce

  1. Open an existing project or create a new one e.g. Hello World template
  2. Open a file (e.g. HelloWorld.sol) and add anything to it. Leave the file open. Do not save the changes
  3. Click the Select a Network button and change the currently selected network from Default to Rinkeby
  4. Open MetaMask (unlock it first, if applicable)
  5. Change the network in MetaMask e.g. from whatever is selected, for example Ropsten, to another choice, say Rinkeby.

Expected result

Nothing. This behavior risks losing unsaved changes and progress due to a forced reload.

Actual result

Complete page reload (forced refresh) without user's consent results in unsaved data being lost.

filippsen avatar Aug 21 '18 18:08 filippsen

This is expected behavior according to MetaMask's contributor: https://github.com/MetaMask/metamask-extension/issues/3599#issuecomment-374324134

filippsen avatar Aug 29 '18 08:08 filippsen

@filippsen this means that nothing should be done on this issue?

javier-tarazaga avatar Aug 29 '18 11:08 javier-tarazaga

@javier-tarazaga I updated the description to better explain what it is, how to replicate and what are the current results.

The answer to that depends if you would like to take control over all the reload, window and tab exit/close actions, at the expense of adding intrusive alert boxes. If that is desirable, the following snippet could be added to src/components/networkAccountSelector/index.js:

beforeUnloadListener=(e) => {
    e.preventDefault();
    var message = '';
    e.returnValue = message;
    return message;
}
componentDidMount() {
    window.addEventListener("beforeunload", this.beforeUnloadListener);
}
componentWillUnmount() {
    window.removeEventListener("beforeunload", this.beforeUnloadListener);                                                                                            
}

Reference: https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload

Would result in: Applying that code would result in the following output when manually refreshing, when MetaMask sends the reload event, when closing the browser window, when closing the browser tab: studio-issue-reload studio-issue-reload-chrome studio-issues-leave-chrome

filippsen avatar Aug 30 '18 13:08 filippsen

An improvement could be that the onunload function only blocks the reload if any files in the project are unsaved.

bashlund avatar Dec 19 '18 10:12 bashlund

@Bashlund the snippet could still be installed to the App entrypoint, but there would have to be a way to check if any files in the project as not saved. Currently, projectItem::isSaved always returns true. Any suggestion that would not involve installing multiple "listeners" via canClose ?

filippsen avatar Jan 30 '19 08:01 filippsen