Disconnect circuit on `beforeunload` event and fix display (#24592)

* Disconnect circuit on `beforeunload` event (#23224)

* Add delay before showing Reconnection UI (#24137)

* Add CSS delay before showing Reconnection UI

* rebuild yet again to try and get past the conflict

* Move reconnection delay mechanism into framework code (#24566)

Co-authored-by: SQL-MisterMagoo <mister.magoo+githubsql@gmail.com>
Co-authored-by: Steve Sanderson <SteveSandersonMS@users.noreply.github.com>
This commit is contained in:
Safia Abdalla 2020-08-13 20:17:20 +00:00 committed by GitHub
parent a740737aae
commit 2931673fb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 13 deletions

File diff suppressed because one or more lines are too long

View File

@ -56,16 +56,18 @@ async function boot(userOptions?: Partial<CircuitStartOptions>): Promise<void> {
return true;
};
window.addEventListener(
'unload',
() => {
let disconnectSent = false;
const cleanup = () => {
if (!disconnectSent) {
const data = new FormData();
const circuitId = circuit.circuitId!;
data.append('circuitId', circuitId);
navigator.sendBeacon('_blazor/disconnect', data);
},
false
);
disconnectSent = navigator.sendBeacon('_blazor/disconnect', data);
}
};
window.addEventListener('beforeunload', cleanup, { capture: false, once: true });
window.addEventListener('unload', cleanup, { capture: false, once: true });
window['Blazor'].reconnect = reconnect;

View File

@ -29,6 +29,7 @@ export class DefaultReconnectDisplay implements ReconnectDisplay {
'opacity: 0.8',
'text-align: center',
'font-weight: bold',
'transition: visibility 0s linear 500ms',
];
this.modal.style.cssText = modalStyles.join(';');
@ -67,6 +68,14 @@ export class DefaultReconnectDisplay implements ReconnectDisplay {
this.button.style.display = 'none';
this.reloadParagraph.style.display = 'none';
this.message.textContent = 'Attempting to reconnect to the server...';
// The visibility property has a transition so it takes effect after a delay.
// This is to prevent it appearing momentarily when navigating away. For the
// transition to take effect, we have to apply the visibility asynchronously.
this.modal.style.visibility = 'hidden';
setTimeout(() => {
this.modal.style.visibility = 'visible';
}, 0);
}
hide(): void {

View File

@ -1,6 +1,6 @@
import { DefaultReconnectDisplay } from "../src/Platform/Circuits/DefaultReconnectDisplay";
import {JSDOM} from 'jsdom';
import { NullLogger} from '../src/Platform/Logging/Loggers';
import { JSDOM } from 'jsdom';
import { NullLogger } from '../src/Platform/Logging/Loggers';
describe('DefaultReconnectDisplay', () => {
@ -14,9 +14,16 @@ describe('DefaultReconnectDisplay', () => {
expect(element).toBeDefined();
expect(element!.id).toBe('test-dialog-id');
expect(element!.style.display).toBe('block');
expect(element!.style.visibility).toBe('hidden');
expect(display.message.textContent).toBe('Attempting to reconnect to the server...');
expect(display.button.style.display).toBe('none');
// Visibility changes asynchronously to allow animation
return new Promise(resolve => setTimeout(() => {
expect(element!.style.visibility).toBe('visible');
resolve();
}, 1));
});
it ('does not add element to the body multiple times', () => {