diff --git a/Dockerfile b/Dockerfile index 925cfc4..7f44721 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Używamy lekkiego obrazu Pythona -FROM python:3.11-slim +FROM python:3.13-slim # Ustawiamy katalog roboczy WORKDIR /app diff --git a/static/js/live.js b/static/js/live.js index 79d3245..4142b83 100644 --- a/static/js/live.js +++ b/static/js/live.js @@ -36,7 +36,6 @@ function setupList(listId, username) { item.onclick = () => { newItemInput.value = s; suggestionsBox.innerHTML = ''; - //newItemInput.focus(); }; suggestionsBox.appendChild(item); }); @@ -92,8 +91,6 @@ function setupList(listId, username) { }); socket.on('expense_added', data => { - // Osobne bo w html musi byc unikatowy a wyswietlam w dwoch miejscach - const badgeEl = document.getElementById('total-expense1'); if (badgeEl) { badgeEl.innerHTML = `💸 ${data.total.toFixed(2)} PLN`; @@ -145,13 +142,12 @@ function setupList(listId, username) { updateProgressBar(); }); - socket.on('progress_updated', function(data) { const progressBar = document.getElementById('progress-bar'); if (progressBar) { progressBar.style.width = data.percent + '%'; progressBar.setAttribute('aria-valuenow', data.percent); - progressBar.textContent = Math.round(data.percent) + '%'; + progressBar.textContent = `${Math.round(data.percent)}%`; } const progressTitle = document.getElementById('progress-title'); @@ -160,11 +156,9 @@ function setupList(listId, username) { } }); - socket.on('note_updated', data => { const itemEl = document.getElementById(`item-${data.item_id}`); if (itemEl) { - // Szukamy w całym elemencie let noteEl = itemEl.querySelector('small'); if (noteEl) { noteEl.innerHTML = `[ Notatka: ${data.note} ]`; @@ -173,12 +167,10 @@ function setupList(listId, username) { newNote.className = 'text-danger ms-4'; newNote.innerHTML = `[ Notatka: ${data.note} ]`; - // Znajdź wrapper flex-column const flexColumn = itemEl.querySelector('.d-flex.flex-column'); if (flexColumn) { flexColumn.appendChild(newNote); } else { - // fallback: dodaj do elementu itemEl.appendChild(newNote); } } @@ -199,6 +191,15 @@ function setupList(listId, username) { }); updateProgressBar(); + + // --- WAŻNE: zapisz dane do reconnect --- + window.LIST_ID = listId; + window.usernameForReconnect = username; + + socket.on('joined_confirmation', function(data) { + console.log('Dołączono do pokoju:', data.room); + showToast('Pokój ponownie dołączony ✅', 'info'); + }); } function updateItemState(itemId, isChecked) { @@ -256,7 +257,6 @@ function addItem(listId) { document.getElementById('newItem').focus(); } - function deleteItem(id) { if (confirm('Na pewno usunąć produkt?')) { socket.emit('delete_item', { item_id: id }); @@ -264,11 +264,11 @@ function deleteItem(id) { } function editItem(id, oldName, oldQuantity) { - const newName = prompt('Podaj nową nazwę (lub zostaw o):', oldName); - if (newName === null) return; // anulował + const newName = prompt('Podaj nową nazwę (lub zostaw starą):', oldName); + if (newName === null) return; const newQuantityStr = prompt('Podaj nową ilość:', oldQuantity); - if (newQuantityStr === null) return; // anulował + if (newQuantityStr === null) return; const finalName = newName.trim() !== '' ? newName.trim() : oldName; @@ -308,16 +308,6 @@ function copyLink(link) { } } -//function showToast(message) { -// const toastContainer = document.getElementById('toast-container'); -// const toast = document.createElement('div'); -// toast.className = 'toast align-items-center text-bg-primary border-0 show'; -// toast.setAttribute('role', 'alert'); -// toast.innerHTML = `
${message}
`; -// toastContainer.appendChild(toast); -// setTimeout(() => { toast.remove(); }, 1750); -//} - function showToast(message, type = 'primary') { const toastContainer = document.getElementById('toast-container'); const toast = document.createElement('div'); @@ -327,4 +317,3 @@ function showToast(message, type = 'primary') { toastContainer.appendChild(toast); setTimeout(() => { toast.remove(); }, 1750); } - diff --git a/static/js/socket_reconnect.js b/static/js/socket_reconnect.js index 3ec1098..42d5766 100644 --- a/static/js/socket_reconnect.js +++ b/static/js/socket_reconnect.js @@ -19,13 +19,23 @@ window.addEventListener("online", function() { reconnectIfNeeded(); }); +// --- Blokowanie checkboxów na czas reconnect --- +function disableCheckboxes(disable) { + document.querySelectorAll('#items input[type="checkbox"]').forEach(cb => { + cb.disabled = disable; + }); +} + // --- Toasty przy rozłączeniu i połączeniu --- let firstConnect = true; socket.on('connect', function() { if (!firstConnect) { showToast('Połączono z serwerem! 🔄', 'info'); - // Automatyczne ponowne dołączenie do pokoju + + // Zablokuj checkboxy tymczasowo + disableCheckboxes(true); + if (window.LIST_ID && window.usernameForReconnect) { console.log('Ponownie wysyłam join_list:', window.LIST_ID, window.usernameForReconnect); socket.emit('join_list', { room: window.LIST_ID, username: window.usernameForReconnect }); @@ -34,6 +44,17 @@ socket.on('connect', function() { firstConnect = false; }); +socket.on('joined_confirmation', function(data) { + console.log('Potwierdzenie joined:', data.room); + showToast('Pokój ponownie dołączony ✅', 'info'); + + // Odblokuj checkboxy + disableCheckboxes(false); +}); + socket.on('disconnect', function(reason) { showToast('Utracono połączenie z serwerem...', 'warning'); + + // Zablokuj checkboxy + disableCheckboxes(true); });