diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 5fd995c59..12c1a983f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -352,7 +352,7 @@ class extends HTMLElement {
The class property `_states` can then be used in the JavaScript component code:
```javascript
-this._state = this._states.FETCH_FROM_URL;
+this._state = this._states.INITIALIZING;
```
We then use CSS rules based on the `state` attribute to control the component's appearance:
@@ -388,6 +388,16 @@ This ensures that the elements in the `
` only appear when
Prefer to change a web component's appearance based on attributes and CSS rules as opposed to JavaScript that manipulates the `.style` attributes of elements within the component.
+We can then initialize the component when the dialog is opened by listening for the `overlay-shown` event:
+
+```javascript
+connectedCallback() {
+ this.addEventListener("overlay-shown", () => {
+ this._state = this._states.INITIALIZING);
+ };
+}
+```
+
### Disable closing a dialog
For a component that is used within an overlay, there might be certain states that should prevent the user from closing the dialog. That’s typically the case when we are waiting for an action to complete (for example when loading something).
diff --git a/app/static/js/app.js b/app/static/js/app.js
index e8e54ef26..f9c3c6e30 100644
--- a/app/static/js/app.js
+++ b/app/static/js/app.js
@@ -230,8 +230,11 @@ document.onload = document.getElementById("app").focus();
document.addEventListener("keydown", onKeyDown);
document.addEventListener("keyup", onKeyUp);
-document.addEventListener("overlay-toggled", (evt) => {
- overlayTracker.trackStatus(evt.target, evt.detail.isShown);
+document.addEventListener("overlay-shown", (evt) => {
+ overlayTracker.trackStatus(evt.detail.overlay, /*isShown=*/ true);
+});
+document.addEventListener("overlay-hidden", (evt) => {
+ overlayTracker.trackStatus(evt.detail.overlay, /*isShown=*/ false);
});
document.addEventListener("video-streaming-mode-changed", (evt) => {
document.getElementById("status-bar").videoStreamIndicator.mode =
@@ -314,35 +317,21 @@ menuBar.addEventListener("update-dialog-requested", () => {
document.getElementById("update-dialog").checkVersion();
});
menuBar.addEventListener("change-hostname-dialog-requested", () => {
- // Note: we have to call `initialize()` after `show()`, to ensure that the
- // dialog is able to focus the main input element.
- // See https://github.com/tiny-pilot/tinypilot/issues/1770
document.getElementById("change-hostname-overlay").show();
- document.getElementById("change-hostname-dialog").initialize();
});
menuBar.addEventListener("wifi-dialog-requested", () => {
- // Note: we have to call `initialize()` after `show()`, to ensure that the
- // dialog is able to focus the main input element.
- // See https://github.com/tiny-pilot/tinypilot/issues/1770
document.getElementById("wifi-overlay").show();
- document.getElementById("wifi-dialog").initialize();
});
menuBar.addEventListener("network-status-dialog-requested", () => {
- // Note: we have to call `initialize()` after `show()`, to ensure that the
- // dialog is able to focus the main input element.
- // See https://github.com/tiny-pilot/tinypilot/issues/1770
document.getElementById("network-status-overlay").show();
- document.getElementById("network-status-dialog").initialize();
});
menuBar.addEventListener("fullscreen-requested", () => {
document.getElementById("remote-screen").fullscreen = true;
});
menuBar.addEventListener("debug-logs-dialog-requested", () => {
- document.getElementById("debug-dialog").retrieveLogs();
document.getElementById("debug-overlay").show();
});
menuBar.addEventListener("about-dialog-requested", () => {
- document.getElementById("about-dialog").initialize();
document.getElementById("about-overlay").show();
});
menuBar.addEventListener("mass-storage-dialog-requested", () => {
@@ -355,15 +344,10 @@ menuBar.addEventListener("static-ip-dialog-requested", () => {
document.getElementById("feature-pro-overlay").show();
});
menuBar.addEventListener("video-settings-dialog-requested", () => {
- document.getElementById("video-settings-dialog").initialize();
document.getElementById("video-settings-overlay").show();
});
menuBar.addEventListener("paste-dialog-requested", () => {
- // Note: we have to call `initialize()` after `show()`, to ensure that the
- // dialog is able to focus the main input element.
- // See https://github.com/tiny-pilot/tinypilot/issues/1770
document.getElementById("paste-overlay").show();
- document.getElementById("paste-dialog").initialize();
});
menuBar.addEventListener("ctrl-alt-del-requested", () => {
// Even though only the final keystroke matters, send them one at a time to
diff --git a/app/templates/custom-elements/about-dialog.html b/app/templates/custom-elements/about-dialog.html
index d4d2a6cd6..7682c897e 100644
--- a/app/templates/custom-elements/about-dialog.html
+++ b/app/templates/custom-elements/about-dialog.html
@@ -82,6 +82,7 @@
About TinyPilot
this.attachShadow({ mode: "open" }).appendChild(
template.content.cloneNode(true)
);
+ this.addEventListener("overlay-shown", () => this._initialize());
this.shadowRoot
.querySelector(".close-btn")
.addEventListener("click", () =>
@@ -89,7 +90,7 @@ About TinyPilot
);
}
- initialize() {
+ _initialize() {
this._checkVersion();
this._populateCredits();
}
diff --git a/app/templates/custom-elements/change-hostname-dialog.html b/app/templates/custom-elements/change-hostname-dialog.html
index 6166f2469..5af1b237a 100644
--- a/app/templates/custom-elements/change-hostname-dialog.html
+++ b/app/templates/custom-elements/change-hostname-dialog.html
@@ -125,6 +125,7 @@ Changing Hostname
futureLocation: this.shadowRoot.getElementById("future-location"),
};
+ this.addEventListener("overlay-shown", () => this._initialize());
this._elements.hostnameInput.addEventListener("input", () => {
this._onInputChanged();
});
@@ -162,7 +163,7 @@ Changing Hostname
this.setAttribute("initial-hostname", initialHostname);
}
- initialize() {
+ _initialize() {
this._elements.inputError.hide();
this._state = this._states.INITIALIZING;
determineHostname()
diff --git a/app/templates/custom-elements/debug-dialog.html b/app/templates/custom-elements/debug-dialog.html
index 24d2ff3a3..af6715a66 100644
--- a/app/templates/custom-elements/debug-dialog.html
+++ b/app/templates/custom-elements/debug-dialog.html
@@ -82,9 +82,6 @@ Debug Logs
constructor() {
super();
this.attachShadow({ mode: "open" });
- // Ensure that these methods always refer to the correct "this",
- // regardless of where they are called.
- this.retrieveLogs = this.retrieveLogs.bind(this);
}
connectedCallback() {
@@ -106,6 +103,8 @@ Debug Logs
shareLogsButton:
this.shadowRoot.querySelector("#share-logs-button"),
};
+
+ this.addEventListener("overlay-shown", () => this._initialize());
this._elements.includeSensitiveData.addEventListener(
"input",
(event) => {
@@ -145,7 +144,7 @@ Debug Logs
return this.hasAttribute("include-sensitive-data");
}
- retrieveLogs() {
+ _initialize() {
this._state = this._states.LOGS_LOADING;
getDebugLogs()
.then((text) => {
diff --git a/app/templates/custom-elements/network-status-dialog.html b/app/templates/custom-elements/network-status-dialog.html
index 960476742..22f7516fa 100644
--- a/app/templates/custom-elements/network-status-dialog.html
+++ b/app/templates/custom-elements/network-status-dialog.html
@@ -66,21 +66,20 @@ Network Status
};
this._shouldAutoUpdate = false;
this._updateTicker = null;
+
+ this.addEventListener("overlay-shown", () => this._initialize());
+ this.addEventListener("overlay-hidden", () => {
+ // Stop the update ticker when the dialog is closed, otherwise the
+ // status requests would continue to be fired even when the dialog
+ // is not visible anymore.
+ this._shouldAutoUpdate = false;
+ clearTimeout(this._updateTicker);
+ });
this.shadowRoot
.querySelector("#close-button")
.addEventListener("click", () => {
this.dispatchEvent(new DialogClosedEvent());
});
-
- // For all events that terminate the dialog, make sure to stop the
- // update ticker, otherwise the status requests would continue to be
- // fired even when the dialog is not visible anymore.
- ["dialog-closed", "dialog-failed"].forEach((evtName) => {
- this.addEventListener(evtName, () => {
- this._shouldAutoUpdate = false;
- clearTimeout(this._updateTicker);
- });
- });
}
get _state() {
@@ -96,7 +95,7 @@ Network Status
);
}
- async initialize() {
+ async _initialize() {
this._state = this._states.INITIALIZING;
await this._update();
this._state = this._states.DISPLAY;
diff --git a/app/templates/custom-elements/overlay-panel.html b/app/templates/custom-elements/overlay-panel.html
index d6f6a3d69..23c85bf04 100644
--- a/app/templates/custom-elements/overlay-panel.html
+++ b/app/templates/custom-elements/overlay-panel.html
@@ -66,8 +66,6 @@