visual fixes

This commit is contained in:
Mateusz Gruszczyński
2026-05-26 10:40:23 +02:00
parent 172b46ad07
commit 6a89f20384
4 changed files with 115 additions and 12 deletions
+2 -1
View File
@@ -10,4 +10,5 @@ db/pgsql/*
db/shopping.db
*.swp
version.txt
deploy/varnish/default.vcl
deploy/varnish/default.vcl
*.zip
+70
View File
@@ -0,0 +1,70 @@
#!/usr/bin/env python3
import os
import sys
import zipfile
import subprocess
from pathlib import Path
def run_git_command(args, repo_path: Path) -> bytes:
result = subprocess.run(
["git", *args],
cwd=repo_path,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=True,
)
return result.stdout
def get_files_to_archive(repo_path: Path) -> list[str]:
output = run_git_command(
["ls-files", "--cached", "--others", "--exclude-standard", "-z"],
repo_path,
)
files = output.decode("utf-8", errors="surrogateescape").split("\0")
return [f for f in files if f]
def make_zip(repo_path: Path, output_zip: Path) -> None:
files = get_files_to_archive(repo_path)
output_zip = output_zip.resolve()
if output_zip.exists():
output_zip.unlink()
with zipfile.ZipFile(output_zip, "w", compression=zipfile.ZIP_DEFLATED) as zf:
for rel_path in files:
abs_path = repo_path / rel_path
if not abs_path.exists():
continue
if abs_path.resolve() == output_zip:
continue
zf.write(abs_path, arcname=rel_path)
print(f"Utworzono archiwum: {output_zip}")
print(f"Added files: {len(files)}")
def main():
repo_path = Path.cwd()
if len(sys.argv) > 1:
output_zip = Path(sys.argv[1])
else:
output_zip = repo_path / f"{repo_path.name}.zip"
try:
run_git_command(["rev-parse", "--show-toplevel"], repo_path)
except subprocess.CalledProcessError:
print("Error: this directory is not a Git repository.", file=sys.stderr)
sys.exit(1)
make_zip(repo_path, output_zip)
if __name__ == "__main__":
main()
+34 -9
View File
@@ -139,6 +139,13 @@ function setupList(listId, username) {
note: ''
};
// Note: store newly added items locally so later edits do not depend on a full page refresh.
if (Array.isArray(window.currentItems)) {
window.currentItems.push(item);
} else {
window.currentItems = [item];
}
const isOwnFreshShareItem = Boolean(
window.IS_SHARE &&
data.added_by &&
@@ -216,22 +223,40 @@ function setupList(listId, username) {
});
socket.on('item_edited', data => {
const idx = window.currentItems.findIndex(i => i.id === data.item_id);
if (idx !== -1) {
window.currentItems[idx].name = data.new_name;
window.currentItems[idx].quantity = data.new_quantity;
const itemId = Number(data.item_id);
const oldItem = document.getElementById(`item-${itemId}`);
const currentItems = Array.isArray(window.currentItems) ? window.currentItems : [];
const idx = currentItems.findIndex(item => Number(item.id) === itemId);
const cachedItem = idx !== -1 ? currentItems[idx] : {};
const newItem = renderItem(window.currentItems[idx], window.IS_SHARE);
const oldItem = document.getElementById(`item-${data.item_id}`);
if (oldItem && newItem) {
oldItem.replaceWith(newItem);
}
// Note: keep the edited item visible immediately, even when the local list cache is stale.
const updatedItem = {
...cachedItem,
id: itemId,
name: data.new_name,
quantity: data.new_quantity,
purchased: oldItem ? oldItem.classList.contains('bg-success') : !!cachedItem.purchased,
not_purchased: oldItem ? oldItem.classList.contains('bg-warning') : !!cachedItem.not_purchased,
not_purchased_reason: cachedItem.not_purchased_reason || '',
note: cachedItem.note || ''
};
if (idx !== -1) {
currentItems[idx] = updatedItem;
window.currentItems = currentItems;
}
if (oldItem) {
oldItem.replaceWith(renderItem(updatedItem, window.IS_SHARE));
} else if (window.LIST_ID) {
socket.emit('request_full_list', { list_id: window.LIST_ID });
}
showToast(`Zaktualizowano produkt: ${data.new_name} (x${data.new_quantity})`, 'success');
updateProgressBar();
toggleEmptyPlaceholder();
applyHidePurchased();
});
// --- WAŻNE: zapisz dane do reconnect ---
+9 -2
View File
@@ -1,9 +1,16 @@
document.addEventListener("DOMContentLoaded", function () {
new TomSelect("#categories", {
const categoriesSelect = document.querySelector("#categories");
if (!categoriesSelect || typeof TomSelect === 'undefined') {
return;
}
new TomSelect(categoriesSelect, {
plugins: ['remove_button'],
maxItems: 1,
placeholder: 'Wybierz jedną kategorie...',
placeholder: 'Wybierz jedną kategorię...',
create: false,
dropdownParent: 'body',
sortField: {
field: "text",
direction: "asc"