Skip to content

Commit 9fd6ca3

Browse files
committed
Dispatch reconnection state change events in UserSpecifiedDisplay
1 parent 5ec46ab commit 9fd6ca3

File tree

5 files changed

+53
-15
lines changed

5 files changed

+53
-15
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
export interface ReconnectStateChangedEvent {
3+
state: "show" | "hide" | "retrying" | "failed" | "rejected";
4+
currentAttempt?: number;
5+
secondsToNextAttempt?: number;
6+
}

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

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
import { ReconnectDisplay } from './ReconnectDisplay';
5+
import { ReconnectStateChangedEvent } from './ReconnectStateChangedEvent';
6+
57
export class UserSpecifiedDisplay implements ReconnectDisplay {
68
static readonly ShowClassName = 'components-reconnect-show';
79

@@ -19,6 +21,8 @@ export class UserSpecifiedDisplay implements ReconnectDisplay {
1921

2022
static readonly SecondsToNextAttemptId = 'components-seconds-to-next-attempt';
2123

24+
static readonly ReconnectStateChangedEventName = 'components-reconnect-state-changed';
25+
2226
constructor(private dialog: HTMLElement, private readonly document: Document, maxRetries?: number) {
2327
this.document = document;
2428

@@ -34,10 +38,7 @@ export class UserSpecifiedDisplay implements ReconnectDisplay {
3438
show(): void {
3539
this.removeClasses();
3640
this.dialog.classList.add(UserSpecifiedDisplay.ShowClassName);
37-
38-
if ((this.dialog as HTMLDialogElement).showModal) {
39-
(this.dialog as HTMLDialogElement).showModal();
40-
}
41+
this.dispatchReconnectStateChangedEvent({ state: 'show' });
4142
}
4243

4344
update(currentAttempt: number, secondsToNextAttempt: number): void {
@@ -56,25 +57,26 @@ export class UserSpecifiedDisplay implements ReconnectDisplay {
5657
if (currentAttempt > 1 && secondsToNextAttempt > 0) {
5758
this.dialog.classList.add(UserSpecifiedDisplay.RetryingClassName);
5859
}
60+
61+
this.dispatchReconnectStateChangedEvent({ state: 'retrying', currentAttempt, secondsToNextAttempt });
5962
}
6063

6164
hide(): void {
6265
this.removeClasses();
6366
this.dialog.classList.add(UserSpecifiedDisplay.HideClassName);
64-
65-
if ((this.dialog as HTMLDialogElement).close) {
66-
(this.dialog as HTMLDialogElement).close();
67-
}
67+
this.dispatchReconnectStateChangedEvent({ state: 'hide' });
6868
}
6969

7070
failed(): void {
7171
this.removeClasses();
7272
this.dialog.classList.add(UserSpecifiedDisplay.FailedClassName);
73+
this.dispatchReconnectStateChangedEvent({ state: 'failed' });
7374
}
7475

7576
rejected(): void {
7677
this.removeClasses();
7778
this.dialog.classList.add(UserSpecifiedDisplay.RejectedClassName);
79+
this.dispatchReconnectStateChangedEvent({ state: 'rejected' });
7880
}
7981

8082
private removeClasses() {
@@ -85,4 +87,9 @@ export class UserSpecifiedDisplay implements ReconnectDisplay {
8587
UserSpecifiedDisplay.FailedClassName,
8688
UserSpecifiedDisplay.RejectedClassName);
8789
}
90+
91+
private dispatchReconnectStateChangedEvent(eventData: ReconnectStateChangedEvent) {
92+
const event = new CustomEvent(UserSpecifiedDisplay.ReconnectStateChangedEventName, { detail: eventData });
93+
this.dialog.dispatchEvent(event);
94+
}
8895
}

src/Components/test/testassets/BasicTestApp/Reconnection/ReconnectionComponent.razor

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,19 @@
3535
<dialog id="components-reconnect-modal">
3636
Rejoining the server...
3737
</dialog>
38+
39+
<script>
40+
const reconnectModal = document.getElementById("components-reconnect-modal");
41+
reconnectModal.addEventListener("components-reconnect-state-changed", handleReconnectStateChanged);
42+
43+
function handleReconnectStateChanged(event) {
44+
if (event.detail.state === "show") {
45+
reconnectModal.showModal();
46+
} else if (event.detail.state === "hide") {
47+
reconnectModal.close();
48+
}
49+
}
50+
</script>
3851
}
3952

4053
@code {

src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Layout/ReconnectModal.razor.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.components-reconnect-first-attempt-s,
1+
.components-reconnect-first-attempt-visible,
22
.components-reconnect-repeated-attempt-visible,
33
.components-reconnect-failed-visible,
44
.components-rejoining-animation {
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,42 @@
11
// Set up event handlers
2+
const reconnectModal = document.getElementById("components-reconnect-modal");
3+
reconnectModal.addEventListener("components-reconnect-state-changed", handleReconnectStateChanged);
4+
25
const retryButton = document.getElementById("components-reconnect-button");
6+
retryButton.addEventListener("click", retry);
37

4-
retryButton.addEventListener('click', retry);
8+
function handleReconnectStateChanged(event) {
9+
if (event.detail.state === "show") {
10+
reconnectModal.showModal();
11+
} else if (event.detail.state === "hide") {
12+
reconnectModal.close();
13+
} else if (event.detail.state === "failed") {
14+
document.addEventListener("visibilitychange", retryWhenDocumentBecomesVisible);
15+
}
16+
}
517

618
async function retry() {
7-
document.removeEventListener('visibilitychange', retryWhenDocumentBecomesVisible);
19+
document.removeEventListener("visibilitychange", retryWhenDocumentBecomesVisible);
820

921
try {
1022
// Reconnect will asynchronously return:
1123
// - true to mean success
1224
// - false to mean we reached the server, but it rejected the connection (e.g., unknown circuit ID)
13-
// - exception to mean we didn't reach the server (this can be sync or async)
25+
// - exception to mean we didn"t reach the server (this can be sync or async)
1426
const successful = await Blazor.reconnect();
1527
if (!successful) {
1628
// We have been able to reach the server, but the circuit is no longer available.
17-
// We'll reload the page so the user can continue using the app as quickly as possible.
29+
// We"ll reload the page so the user can continue using the app as quickly as possible.
1830
location.reload();
1931
}
2032
} catch (err) {
2133
// We got an exception, server is currently unavailable
22-
document.addEventListener('visibilitychange', retryWhenDocumentBecomesVisible);
34+
document.addEventListener("visibilitychange", retryWhenDocumentBecomesVisible);
2335
}
2436
}
2537

2638
async function retryWhenDocumentBecomesVisible() {
27-
if (document.visibilityState === 'visible') {
39+
if (document.visibilityState === "visible") {
2840
await retry();
2941
}
3042
}

0 commit comments

Comments
 (0)