photo_server_json_flutter_c.../public/js/sync.js
2026-03-23 12:31:01 +01:00

247 lines
No EOL
7.1 KiB
JavaScript

// ===============================================
// JWT PARSER
// ===============================================
function parseJwt(token) {
if (!token) return {};
try {
const base64 = token.split('.')[1];
const json = atob(base64);
return JSON.parse(json);
} catch (e) {
console.error("parseJwt error:", e);
return {};
}
}
// ===============================================
// GET PHOTO BY ID — con log puliti
// ===============================================
async function getPhotoById(id) {
const token = localStorage.getItem("token");
const payload = parseJwt(token);
const user = payload.name || "Common";
const url = `${BASE_URL}/photos/byIds?id=${encodeURIComponent(id)}&user=${encodeURIComponent(user)}`;
console.log(`📥 [getPhotoById] Richiedo foto id=${id}`);
let res;
try {
res = await fetch(url, {
headers: { "Authorization": "Bearer " + token }
});
} catch (e) {
console.error("❌ [getPhotoById] ERRORE FETCH:", e);
return [];
}
if (!res.ok) {
console.error("❌ [getPhotoById] ERRORE HTTP:", res.status, res.statusText);
return [];
}
try {
const json = await res.json();
console.log(`📤 [getPhotoById] id=${id} → trovate ${json.length} foto`);
return json;
} catch (e) {
console.error("❌ [getPhotoById] ERRORE JSON:", e);
return [];
}
}
// ===============================================
// INCREMENTAL SYNC — versione completa e pulita
// ===============================================
async function incrementalSync() {
console.log("==============================================");
console.log("🚀 incrementalSync() START");
const payload = parseJwt(localStorage.getItem("token"));
const user = payload.name || "Common";
let lastSync = getLastSync();
const currentPhotos = getLocalPhotos();
console.log(`👤 Utente: ${user}`);
console.log(`🕒 lastSync: ${lastSync}`);
console.log(`📸 Foto locali attuali: ${currentPhotos.length}`);
// ============================================================
// 1) FULL LOAD
// ============================================================
if (!lastSync || currentPhotos.length === 0) {
console.log("🟦 FULL LOAD → caricamento completo del DB");
try {
const photos = await getAllPhotos();
console.log(`📥 FULL LOAD → ricevute ${photos.length} foto`);
saveLocalState();
refreshGallery();
const now = new Date().toISOString();
setLastSync(now);
console.log(`🕒 FULL LOAD → setLastSync = ${now}`);
console.log("🏁 incrementalSync() COMPLETATO (fullLoad)");
console.log("==============================================");
return;
} catch (err) {
console.error("❌ [incrementalSync] ERRORE in fullLoad:", err);
return;
}
}
// ============================================================
// 2) SYNC INCREMENTALE
// ============================================================
console.log("🟩 INCREMENTAL SYNC → controllo cambiamenti");
let changes;
try {
changes = await getChanges(lastSync, user);
} catch (err) {
console.error("❌ [incrementalSync] ERRORE getChanges:", err);
return;
}
console.log(`📥 Cambiamenti ricevuti: ${changes?.changes?.length || 0}`);
if (!changes || !changes.changes || changes.changes.length === 0) {
console.log("🟨 Nessun cambiamento → lastSync NON aggiornato");
return;
}
// ============================================================
// 3) APPLICA CAMBIAMENTI
// ============================================================
for (const ch of changes.changes) {
console.log("----------------------------------------------");
console.log(`🔄 Cambio:`, ch);
// FOTO AGGIUNTA
if (ch.change_type === "added") {
console.log(`🟢 Foto aggiunta → id=${ch.photo_id}`);
try {
const arr = await getPhotoById(ch.photo_id);
if (arr.length) {
console.log(`📸 Aggiungo foto id=${ch.photo_id} a localPhotos`);
addPhotoLocal(arr[0]);
} else {
console.warn(`⚠️ Foto NON trovata nel server remoto per id=${ch.photo_id}`);
}
} catch (err) {
console.error("❌ [incrementalSync] ERRORE getPhotoById:", err);
}
}
// FOTO RIMOSSA
if (ch.change_type === "removed") {
console.log(`🔴 Foto rimossa → id=${ch.photo_id}`);
removePhotoLocal(ch.photo_id);
const el = document.getElementById("photo_" + ch.photo_id);
if (el) {
console.log(`🗑️ Rimuovo elemento DOM: ${el.id}`);
el.remove();
}
}
}
console.log(`📸 Foto locali dopo sync: ${getLocalPhotos().length}`);
// ============================================================
// 4) REFRESH UI
// ============================================================
console.log("🔄 refreshGallery()");
refreshGallery();
// ============================================================
// 5) AGGIORNA lastSync
// ============================================================
const lastTimestamp = changes.changes.at(-1).timestamp || new Date().toISOString();
console.log(`🕒 Aggiorno lastSync → ${lastTimestamp}`);
setLastSync(lastTimestamp);
console.log("🏁 incrementalSync() COMPLETATO");
console.log("==============================================");
}
// ===============================================
// WEBSOCKET REAL-TIME — versione pulita
// ===============================================
function startWebSocket() {
const token = localStorage.getItem("token");
if (!token) {
console.error("❌ [WS] Nessun token JWT trovato");
return;
}
const payload = parseJwt(token);
const user = payload.name || "Common";
console.log("🔌 [WS] Connessione a wss://prova-ws.patachina.it ...");
const ws = new WebSocket("wss://prova-ws.patachina.it");
ws.onopen = () => {
console.log("🟢 [WS] Connesso → invio token JWT");
ws.send(JSON.stringify({
type: "auth",
token
}));
};
ws.onmessage = async (ev) => {
let msg;
try {
msg = JSON.parse(ev.data);
} catch (e) {
console.error("❌ [WS] Errore parsing JSON:", e);
return;
}
console.log("📩 [WS] Messaggio ricevuto:", msg);
if (msg.type === "photo_added") {
console.log(`🟢 [WS] Foto aggiunta → id=${msg.photo_id}`);
try {
const arr = await getPhotoById(msg.photo_id);
if (arr.length) {
console.log("📸 [WS] Foto trovata → aggiorno localPhotos");
addPhotoLocal(arr[0]);
refreshGallery();
} else {
console.warn("⚠️ [WS] Foto non trovata nel server remoto");
}
} catch (err) {
console.error("❌ [WS] Errore getPhotoById:", err);
}
}
};
ws.onclose = () => {
console.warn("❌ [WS] Connessione chiusa → ritento tra 3s...");
setTimeout(startWebSocket, 3000);
};
ws.onerror = (err) => {
console.error("⚠️ [WS] Errore WebSocket:", err);
};
}
// Avvio automatico del WebSocket
startWebSocket();
window.incrementalSync = incrementalSync;
window.parseJwt = parseJwt;