update listy jak sie zmieni
This commit is contained in:
19
app.py
19
app.py
@@ -1141,7 +1141,7 @@ def handle_join(data):
|
||||
emit('user_joined', {'username': username}, to=room)
|
||||
emit('user_list', {'users': list(active_users[room])}, to=room)
|
||||
emit('joined_confirmation', {'room': room, 'list_title': list_title})
|
||||
|
||||
|
||||
@socketio.on('disconnect')
|
||||
def handle_disconnect(sid):
|
||||
global active_users
|
||||
@@ -1220,6 +1220,23 @@ def handle_uncheck_item(data):
|
||||
'percent': percent
|
||||
}, to=str(item.list_id))
|
||||
|
||||
@socketio.on('request_full_list')
|
||||
def handle_request_full_list(data):
|
||||
list_id = data['list_id']
|
||||
items = Item.query.filter_by(list_id=list_id).all()
|
||||
|
||||
items_data = []
|
||||
for item in items:
|
||||
items_data.append({
|
||||
'id': item.id,
|
||||
'name': item.name,
|
||||
'quantity': item.quantity,
|
||||
'purchased': item.purchased,
|
||||
'note': item.note or ''
|
||||
})
|
||||
|
||||
emit('full_list', {'items': items_data}, to=request.sid)
|
||||
|
||||
@socketio.on('update_note')
|
||||
def handle_update_note(data):
|
||||
item_id = data['item_id']
|
||||
|
@@ -216,6 +216,11 @@ socket.on('user_list', function(data) {
|
||||
showToast(`Obecni: ${userList}`, 'info');
|
||||
});
|
||||
|
||||
socket.on('full_list', function(data) {
|
||||
updateListSmoothly(data.items);
|
||||
showToast('🔄 Lista została zaktualizowana', 'info');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function updateItemState(itemId, isChecked) {
|
||||
@@ -333,3 +338,72 @@ function showToast(message, type = 'primary') {
|
||||
toastContainer.appendChild(toast);
|
||||
setTimeout(() => { toast.remove(); }, 1750);
|
||||
}
|
||||
|
||||
function updateListSmoothly(newItems) {
|
||||
const itemsContainer = document.getElementById('items');
|
||||
const existingItems = Array.from(itemsContainer.querySelectorAll('li'));
|
||||
const existingIds = existingItems.map(li => parseInt(li.id.replace('item-', ''), 10));
|
||||
const newIds = newItems.map(item => item.id);
|
||||
|
||||
// Usuń elementy, które nie istnieją w nowej liście
|
||||
existingItems.forEach(li => {
|
||||
const id = parseInt(li.id.replace('item-', ''), 10);
|
||||
if (!newIds.includes(id)) {
|
||||
li.remove();
|
||||
}
|
||||
});
|
||||
|
||||
// Przejdź przez nowe elementy
|
||||
newItems.forEach(item => {
|
||||
const li = document.getElementById(`item-${item.id}`);
|
||||
let quantityBadge = '';
|
||||
if (item.quantity && item.quantity > 1) {
|
||||
quantityBadge = `<span class="badge bg-secondary">x${item.quantity}</span>`;
|
||||
}
|
||||
|
||||
if (li) {
|
||||
// Jeśli istnieje — sprawdź i ewentualnie zaktualizuj nazwę, badge, notatkę
|
||||
const nameSpan = li.querySelector(`#name-${item.id}`);
|
||||
let newNameHtml = `${item.name} ${quantityBadge}`;
|
||||
if (nameSpan && nameSpan.innerHTML.trim() !== newNameHtml.trim()) {
|
||||
nameSpan.innerHTML = newNameHtml;
|
||||
}
|
||||
|
||||
const noteEl = li.querySelector('small');
|
||||
if (item.note && (!noteEl || noteEl.innerText !== `[ ${item.note} ]`)) {
|
||||
if (!noteEl) {
|
||||
const newNote = document.createElement('small');
|
||||
newNote.className = 'text-danger ms-4';
|
||||
newNote.innerHTML = `[ <b>${item.note}</b> ]`;
|
||||
nameSpan.insertAdjacentElement('afterend', newNote);
|
||||
} else {
|
||||
noteEl.innerHTML = `[ <b>${item.note}</b> ]`;
|
||||
}
|
||||
} else if (!item.note && noteEl) {
|
||||
noteEl.remove();
|
||||
}
|
||||
|
||||
} else {
|
||||
// Jeśli brak — dodaj nowy
|
||||
const newLi = document.createElement('li');
|
||||
newLi.className = `list-group-item d-flex justify-content-between align-items-center flex-wrap ${item.purchased ? 'bg-success text-white' : 'item-not-checked'}`;
|
||||
newLi.id = `item-${item.id}`;
|
||||
|
||||
newLi.innerHTML = `
|
||||
<div class="d-flex align-items-center flex-wrap gap-2">
|
||||
<input class="large-checkbox" type="checkbox" ${item.purchased ? 'checked' : ''}>
|
||||
<span id="name-${item.id}" class="text-white">${item.name} ${quantityBadge}</span>
|
||||
${item.note ? `<small class="text-danger ms-4">[ <b>${item.note}</b> ]</small>` : ''}
|
||||
</div>
|
||||
<div class="mt-2 mt-md-0">
|
||||
<button class="btn btn-sm btn-outline-warning me-1" onclick="editItem(${item.id}, '${item.name}', ${item.quantity || 1})">✏️</button>
|
||||
<button class="btn btn-sm btn-outline-danger" onclick="deleteItem(${item.id})">🗑️</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
itemsContainer.appendChild(newLi);
|
||||
}
|
||||
});
|
||||
|
||||
updateProgressBar();
|
||||
}
|
||||
|
@@ -20,7 +20,7 @@
|
||||
|
||||
<ul id="items" class="list-group mb-3">
|
||||
{% for item in items %}
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center flex-wrap clickable-item {% if item.purchased %}bg-success text-white{% else %}item-not-checked{% endif %}" id="item-{{ item.id }}"> <div class="d-flex align-items-center gap-3 flex-grow-1">
|
||||
<li data-name="{{ item.name|lower }}" id="item-{{ item.id }}" class="list-group-item d-flex justify-content-between align-items-center flex-wrap clickable-item {% if item.purchased %}bg-success text-white{% else %}item-not-checked{% endif %}" id="item-{{ item.id }}"> <div class="d-flex align-items-center gap-3 flex-grow-1">
|
||||
<input class="large-checkbox" type="checkbox" {% if item.purchased %}checked{% endif %} {% if list.is_archived %}disabled{% endif %}>
|
||||
<span id="name-{{ item.id }}" class="{% if item.purchased %}text-white{% else %}text-white{% endif %}">
|
||||
{{ item.name }}
|
||||
|
@@ -1,7 +1,6 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}Logowanie{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center flex-wrap mb-4">
|
||||
<h2 class="mb-2">🔒 Logowanie</h2>
|
||||
</div>
|
||||
@@ -10,10 +9,10 @@
|
||||
<div class="card-body">
|
||||
<form method="post">
|
||||
<div class="mb-3">
|
||||
<input type="text" name="username" placeholder="Login" class="form-control" required>
|
||||
<input type="text" name="username" placeholder="Login" class="form-control bg-dark text-white border-secondary rounded" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<input type="password" name="password" placeholder="Hasło" class="form-control" required>
|
||||
<input type="password" name="password" placeholder="Hasło" class="form-control bg-dark text-white border-secondary rounded" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success w-100">🔑 Zaloguj</button>
|
||||
</form>
|
||||
|
@@ -10,7 +10,7 @@
|
||||
<div class="card-body">
|
||||
<form method="post">
|
||||
<div class="mb-3">
|
||||
<input type="password" name="password" placeholder="Hasło" class="form-control rounded" required>
|
||||
<input type="password" name="password" placeholder="Hasło" class="form-control bg-dark text-white border-secondary rounded" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success w-100">🔓 Wejdź</button>
|
||||
</form>
|
||||
|
Reference in New Issue
Block a user