Skip to content

Commit 2931673

Browse files
captainsafiaSQL-MisterMagooSteveSandersonMS
authored
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 <[email protected]> Co-authored-by: Steve Sanderson <[email protected]>
1 parent a740737 commit 2931673

File tree

4 files changed

+31
-13
lines changed

4 files changed

+31
-13
lines changed

src/Components/Web.JS/dist/Release/blazor.server.js

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Components/Web.JS/src/Boot.Server.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,18 @@ async function boot(userOptions?: Partial<CircuitStartOptions>): Promise<void> {
5656
return true;
5757
};
5858

59-
window.addEventListener(
60-
'unload',
61-
() => {
59+
let disconnectSent = false;
60+
const cleanup = () => {
61+
if (!disconnectSent) {
6262
const data = new FormData();
6363
const circuitId = circuit.circuitId!;
6464
data.append('circuitId', circuitId);
65-
navigator.sendBeacon('_blazor/disconnect', data);
66-
},
67-
false
68-
);
65+
disconnectSent = navigator.sendBeacon('_blazor/disconnect', data);
66+
}
67+
};
68+
69+
window.addEventListener('beforeunload', cleanup, { capture: false, once: true });
70+
window.addEventListener('unload', cleanup, { capture: false, once: true });
6971

7072
window['Blazor'].reconnect = reconnect;
7173

src/Components/Web.JS/src/Platform/Circuits/DefaultReconnectDisplay.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export class DefaultReconnectDisplay implements ReconnectDisplay {
2929
'opacity: 0.8',
3030
'text-align: center',
3131
'font-weight: bold',
32+
'transition: visibility 0s linear 500ms',
3233
];
3334

3435
this.modal.style.cssText = modalStyles.join(';');
@@ -67,6 +68,14 @@ export class DefaultReconnectDisplay implements ReconnectDisplay {
6768
this.button.style.display = 'none';
6869
this.reloadParagraph.style.display = 'none';
6970
this.message.textContent = 'Attempting to reconnect to the server...';
71+
72+
// The visibility property has a transition so it takes effect after a delay.
73+
// This is to prevent it appearing momentarily when navigating away. For the
74+
// transition to take effect, we have to apply the visibility asynchronously.
75+
this.modal.style.visibility = 'hidden';
76+
setTimeout(() => {
77+
this.modal.style.visibility = 'visible';
78+
}, 0);
7079
}
7180

7281
hide(): void {

src/Components/Web.JS/tests/DefaultReconnectDisplay.test.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { DefaultReconnectDisplay } from "../src/Platform/Circuits/DefaultReconnectDisplay";
2-
import {JSDOM} from 'jsdom';
3-
import { NullLogger} from '../src/Platform/Logging/Loggers';
2+
import { JSDOM } from 'jsdom';
3+
import { NullLogger } from '../src/Platform/Logging/Loggers';
44

55
describe('DefaultReconnectDisplay', () => {
66

@@ -14,9 +14,16 @@ describe('DefaultReconnectDisplay', () => {
1414
expect(element).toBeDefined();
1515
expect(element!.id).toBe('test-dialog-id');
1616
expect(element!.style.display).toBe('block');
17+
expect(element!.style.visibility).toBe('hidden');
1718

1819
expect(display.message.textContent).toBe('Attempting to reconnect to the server...');
1920
expect(display.button.style.display).toBe('none');
21+
22+
// Visibility changes asynchronously to allow animation
23+
return new Promise(resolve => setTimeout(() => {
24+
expect(element!.style.visibility).toBe('visible');
25+
resolve();
26+
}, 1));
2027
});
2128

2229
it ('does not add element to the body multiple times', () => {

0 commit comments

Comments
 (0)