feat: notify document updates over websocket
This commit is contained in:
35
apps/server/internal/httpserver/static/realtime.js
Normal file
35
apps/server/internal/httpserver/static/realtime.js
Normal file
@@ -0,0 +1,35 @@
|
||||
(function () {
|
||||
const notice = document.querySelector("[data-version-notice]");
|
||||
const reload = document.querySelector("[data-version-reload]");
|
||||
const documentShell = document.querySelector("[data-document-path][data-document-hash]");
|
||||
|
||||
if (!notice || !reload || !documentShell || !window.WebSocket) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentPath = documentShell.getAttribute("data-document-path");
|
||||
const currentHash = documentShell.getAttribute("data-document-hash");
|
||||
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
|
||||
const socket = new WebSocket(protocol + "//" + window.location.host + "/ws");
|
||||
|
||||
socket.addEventListener("message", function (event) {
|
||||
let payload;
|
||||
try {
|
||||
payload = JSON.parse(event.data);
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
if (payload.type !== "document_version" || !payload.data) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (payload.data.path === currentPath && payload.data.hash !== currentHash) {
|
||||
notice.hidden = false;
|
||||
}
|
||||
});
|
||||
|
||||
reload.addEventListener("click", function () {
|
||||
window.location.reload();
|
||||
});
|
||||
})();
|
||||
@@ -177,6 +177,41 @@ code {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.version-notice {
|
||||
position: fixed;
|
||||
right: 1rem;
|
||||
bottom: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.85rem;
|
||||
max-width: min(28rem, calc(100vw - 2rem));
|
||||
padding: 0.75rem 0.85rem;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
background: var(--panel-strong);
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.version-notice[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.version-notice p {
|
||||
margin: 0;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.version-notice button {
|
||||
min-height: 2.2rem;
|
||||
padding: 0 0.8rem;
|
||||
border: 0;
|
||||
border-radius: var(--radius-sm);
|
||||
color: white;
|
||||
background: var(--accent);
|
||||
font: 700 0.9rem/1 ui-monospace, SFMono-Regular, monospace;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
.site-header__inner {
|
||||
flex-direction: column;
|
||||
@@ -191,4 +226,3 @@ code {
|
||||
padding: 1.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user