refactor: remove inline WebSocket code from templates

collections.templ:
- Removed ~75 lines of inline WebSocket JS
- Added initializeCollectionWebSocket using websocket.ts utility
- Updated template to use x-init for WebSocket init

admin.templ:
- Removed ~55 lines of inline WebSocket JS
- Added initializeScanWebSocket using websocket.ts utility
- Updated template to use x-init for WebSocket init

Both now use the shared websocket.ts createWebSocket function
This commit is contained in:
2026-03-13 12:51:11 -04:00
parent 7068fabbee
commit 41e7445524
6 changed files with 110 additions and 155 deletions
+2 -80
View File
@@ -12,86 +12,8 @@ templ Collection(user User, collections []CollectionData, errorMessage string) {
<script src="/static/htmx.min.js"></script>
<script src="/static/main.js" defer></script>
<link href="/static/style.css" rel="stylesheet"/>
<script>
let ws = null;
let collectionId = null;
let libraryId = null;
function connectWebSocket() {
const protocol =
window.location.protocol === "https:" ? "wss:" : "ws:";
const wsUrl = `${protocol}//${window.location.host}/ws/sync?token={ user.Token }`;
ws = new WebSocket(wsUrl);
ws.onopen = function () {
console.log("WebSocket connected");
};
ws.onmessage = function (event) {
try {
const message = JSON.parse(event.data);
if (
message.type === "collection_updated" &&
message.data.collection_id === collectionId
) {
const actionText =
message.data.action === "books_added"
? `Added ${message.data.count || 0} book(s)`
: message.data.action === "book_removed"
? "Removed a book"
: message.data.action === "books_bulk_removed"
? `Removed ${message.data.count || 0} book(s)`
: "Collection updated";
// Show toast notification
if (window.showToast) {
window.showToast(actionText, "info");
}
// Check if user is actively typing
const activeElement = document.activeElement;
const isUserActive =
activeElement &&
(activeElement.tagName === "INPUT" ||
activeElement.tagName === "TEXTAREA" ||
activeElement.tagName === "SELECT" ||
activeElement.getAttribute("contenteditable") === "true");
if (!isUserActive) {
setTimeout(function () {
location.reload();
}, 1000);
} else {
console.log("User actively typing - skipping auto-reload");
}
}
} catch (error) {
console.error("Failed to parse WebSocket message:", error);
}
};
ws.onclose = function () {
console.log("WebSocket disconnected, reconnecting in 5s...");
setTimeout(connectWebSocket, 5000);
};
ws.onerror = function (error) {
console.error("WebSocket error:", error);
};
}
document.addEventListener("DOMContentLoaded", function () {
// Get collection and library IDs from data attributes
const dataEl = document.getElementById("collection-data");
if (dataEl) {
collectionId = dataEl.dataset.id || "";
libraryId = dataEl.dataset.libraryId || "";
connectWebSocket();
}
});
</script>
</head>
<body x-data="collections" class="theme-{ user.Theme }">
<body x-data="collections" x-init="initializeCollectionWebSocket" class="theme-{ user.Theme }">
@Header(user, "/collections")
<!-- Modal Container -->
<div id="modal-container"></div>
@@ -190,7 +112,7 @@ templ CollectionDetail(user User, collection CollectionData, books []handlers.Bo
<script src="/static/main.js" defer></script>
<link href="/static/style.css" rel="stylesheet"/>
</head>
<body x-data="collections" class="theme-{ user.Theme }">
<body x-data="collections" x-init="initializeCollectionWebSocket" class="theme-{ user.Theme }">
@Header(user, "/collections")
<div class="w-full px-4 sm:px-6 lg:px-8 py-8">
<div class="mb-6">