The "Connection to server has been lost" behaves oddly, doesn't handle reconnections
Hi!
So, we all probably have seen that "Connection to server has been lost" dialog on the bottom-right of the screen. It stays there until interacted with.
I was trying to get rid of it and/or improve the behavior, but it's honestly just left me with confusion...
For reference, here's the code that spawns the dialog: https://activitypub.software/TransFem-org/Sharkey/-/blob/develop/packages/frontend/src/boot/main-boot.ts?ref_type=heads#L48
So, when the "disconnected" event is received (corresponding to a "close" event on the websocket), this dialog pops up, and stays there until interacted.
There are some points I'm confused by:
- That dialog sometimes seemed to just semi-permanently reside on my screen at times, other times it's gone.
- The "disconnected" event never seems to fire, even when I kill the network connection. The heartbeats don't seem to do much, there.
- The confirm() function discards the "dispose" function, so even if the websocket reconnects (which it might; it uses ReconnectingWebsocket), the dialog just kinda stays there.
Instead, I propose something like thist:
// A reference to the function to close the "reconnecting" dialog; null if the dialog is not open.
let reloadDialogDisposeFn : Function | null = null;
// When the stream is disconnected, show a dialog to reload the page.
stream.on('_disconnected_', async () => {
// TODO: Where's that setting?
if (defaultStore.state.serverDisconnectedBehavior === 'dialog') {
// If the dialog is already open, do nothing.
if (reloadDialogDisposeFn) return;
// Show a popup dialog with a warning message and a "reload" button.
const {dispose} = popup(MkDialog, {
...({
type: 'warning',
title: i18n.ts.disconnectedFromServer,
text: i18n.ts.reloadConfirm,
}),
showCancelButton: true, // Show a "cancel" button; this dismisses the dialog without reloading the page.
}, {
// If the user clicks one of the buttons, and it's the "positive" button (in this case, the "reload" button),
done: result => {
if (!result) location.reload();
},
// If the dialog is closed, dispose of the dialog.
closed: () => dispose(),
});
// Save the function to close the dialog so that it can be called later.
reloadDialogDisposeFn = dispose;
}
});
// When the stream is (re)connected, close the "reconnecting" dialog if it's open.
stream.on('_connected_', () => {
if (reloadDialogDisposeFn) {
reloadDialogDisposeFn();
reloadDialogDisposeFn = null;
toast("Reconnected to server.");
}
});
But... I'm having trouble testing it, since that "disconnect" event never even seems to fire, even with the connection cut.
What's going on here? Are we trying to handle accidental disconnections? Server shutdowns?