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
+43
View File
@@ -1,5 +1,46 @@
import { Alpine } from "./alpine";
import { showToast } from "./toast";
import { createWebSocket } from "./websocket";
function initializeScanWebSocket(): void {
createWebSocket({
onMessage: (message) => {
switch (message.type) {
case "scan_progress":
updateScanProgress(message.data);
break;
case "scan_complete":
showScanComplete(message.data);
break;
case "scan_error":
showScanError(message.data);
break;
}
},
enableReconnect: true,
reconnectDelay: 5000,
});
}
function updateScanProgress(data: { progress: number; files_scanned: number; new_items: number }): void {
const progressBar = document.getElementById("scan-progress-bar");
if (progressBar) {
progressBar.style.width = (data.progress * 100) + "%";
}
const progressText = document.getElementById("scan-progress-text");
if (progressText) {
progressText.textContent = `${data.files_scanned} files scanned (${data.new_items} new)`;
}
}
function showScanComplete(_data: unknown): void {
console.log("Scan complete:", _data);
}
function showScanError(_data: unknown): void {
console.error("Scan error:", _data);
}
async function triggerLibraryScan(): Promise<void> {
const token = localStorage.getItem("token");
@@ -339,6 +380,7 @@ function stopScanStatusPolling(): void {
export {
hideScanProgress,
initializeScanWebSocket,
loadSystemStats,
loadWatchStatus,
scanAllLibraries,
@@ -349,6 +391,7 @@ export {
Alpine.data("admin", () => ({
hideScanProgress,
initializeScanWebSocket,
loadSystemStats,
loadWatchStatus,
scanAllLibraries,
+47
View File
@@ -1,5 +1,50 @@
import { Alpine } from "./alpine";
import { showToast } from "./toast";
import { createWebSocket } from "./websocket";
let collectionId: string | null = null;
function initializeCollectionWebSocket(): void {
const dataEl = document.getElementById("collection-data");
if (!dataEl) return;
collectionId = dataEl.dataset.id || null;
if (!collectionId) return;
createWebSocket({
onMessage: (message) => {
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";
showToast(actionText, "info");
const activeElement = document.activeElement;
const isUserActive =
activeElement &&
(activeElement.tagName === "INPUT" ||
activeElement.tagName === "TEXTAREA" ||
activeElement.tagName === "SELECT" ||
activeElement.getAttribute("contenteditable") === "true");
if (!isUserActive) {
setTimeout(() => {
location.reload();
}, 1000);
}
}
},
enableReconnect: true,
reconnectDelay: 5000,
});
}
async function loadCollections(): Promise<void> {
const token = localStorage.getItem("token");
@@ -410,6 +455,7 @@ export {
deleteRule,
filterIcons,
initColorSelection,
initializeCollectionWebSocket,
loadCollectionRules,
loadCollections,
navigateToCollection,
@@ -426,6 +472,7 @@ Alpine.data("collections", () => ({
deleteRule,
filterIcons,
initColorSelection,
initializeCollectionWebSocket,
loadCollectionRules,
loadCollections,
navigateToCollection,