forked from 2sys/phonograph
118 lines
2.7 KiB
TypeScript
118 lines
2.7 KiB
TypeScript
import { css, html, LitElement } from "lit";
|
|
import { customElement, property, state } from "lit/decorators.js";
|
|
import { classMap } from "lit/directives/class-map.js";
|
|
|
|
@customElement("dev-reloader")
|
|
export class DevReloader extends LitElement {
|
|
@property({ attribute: true })
|
|
ws = "";
|
|
|
|
@property({ attribute: true, type: Boolean, reflect: true })
|
|
auto = false;
|
|
|
|
@state()
|
|
private _connected = false;
|
|
|
|
private _armed = false;
|
|
|
|
private _socket?: WebSocket;
|
|
|
|
static override styles = css`
|
|
button {
|
|
appearance: none;
|
|
background: none;
|
|
border: none;
|
|
padding: none;
|
|
}
|
|
|
|
.widget {
|
|
position: fixed;
|
|
z-index: 999;
|
|
bottom: 1rem;
|
|
left: 1rem;
|
|
border: solid 1px #0002;
|
|
padding: 1rem;
|
|
border-radius: 9999px;
|
|
cursor: pointer;
|
|
display: flex;
|
|
align-items: center;
|
|
box-shadow: 0 0.5rem 1rem #0002;
|
|
opacity: 0.5;
|
|
|
|
&:hover {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
.indicator {
|
|
width: 8px;
|
|
height: 8px;
|
|
border-radius: 9999px;
|
|
background: #f60;
|
|
|
|
&.connected {
|
|
background: #06f;
|
|
}
|
|
}
|
|
|
|
.label {
|
|
margin-left: 1rem;
|
|
}
|
|
`;
|
|
|
|
override connectedCallback() {
|
|
super.connectedCallback();
|
|
this._connected = true;
|
|
this._handleDisconnect();
|
|
}
|
|
|
|
private _handleDisconnect() {
|
|
if (this._connected) {
|
|
console.log("dev-reloader: disconnected");
|
|
this._connected = false;
|
|
this._socket = undefined;
|
|
const intvl = setInterval(() => {
|
|
if (!this._socket || this._socket.readyState === WebSocket.CLOSED) {
|
|
try {
|
|
this._socket = new WebSocket(this.ws);
|
|
this._socket.addEventListener("open", () => {
|
|
if (this.auto && this._armed) {
|
|
globalThis.location.reload();
|
|
}
|
|
console.log("dev-reloader: connected");
|
|
this._connected = true;
|
|
this._armed = true;
|
|
clearInterval(intvl);
|
|
});
|
|
this._socket.addEventListener(
|
|
"close",
|
|
this._handleDisconnect.bind(this),
|
|
);
|
|
this._socket.addEventListener(
|
|
"error",
|
|
this._handleDisconnect.bind(this),
|
|
);
|
|
} catch { /* no-op */ }
|
|
}
|
|
}, 500);
|
|
}
|
|
}
|
|
|
|
private _toggleAuto() {
|
|
this.auto = !this.auto;
|
|
}
|
|
|
|
protected override render() {
|
|
return html`
|
|
<button type="button" class="widget" @click="${this._toggleAuto}">
|
|
<div class="${classMap({
|
|
indicator: true,
|
|
connected: this._connected,
|
|
})}"></div>
|
|
<div class="label">
|
|
${this.auto ? "Disable" : "Enable"} auto-reload
|
|
</div>
|
|
</button>
|
|
`;
|
|
}
|
|
}
|