Update gallery_app.py

This commit is contained in:
2026-01-20 11:56:54 +01:00
parent 60d34bf315
commit 3be76cd8ab

View File

@@ -40,6 +40,7 @@ class AppState:
self._path_to_idx: Dict[str, int] = {} # Reverse index for O(1) lookups self._path_to_idx: Dict[str, int] = {} # Reverse index for O(1) lookups
self.green_dots: Set[int] = set() self.green_dots: Set[int] = set()
self.index_map: Dict[int, str] = {} self.index_map: Dict[int, str] = {}
self.committed_indexes: Set[int] = set() # NEW: Track which indexes are from persistent tags
# Staged data cache with dirty flag # Staged data cache with dirty flag
self._staged_data: Dict = {} self._staged_data: Dict = {}
@@ -230,25 +231,40 @@ def load_images():
refresh_ui() refresh_ui()
def refresh_staged_info(): def refresh_staged_info():
"""Update staged data and index maps (optimized).""" """Update staged data and index maps (optimized) - includes persistent tags."""
# Green dots using optimized O(staged) lookup # Green dots using optimized O(staged) lookup
state.green_dots = state.compute_green_dots() state.green_dots = state.compute_green_dots()
# Build index map for active category # Build index map for active category
state.index_map.clear() state.index_map.clear()
state.committed_indexes.clear() # Track which are committed vs staged
# Add staged images for current category # 1. Add staged images for current category (pending commits) - these are "yellow"
staged_indexes = set()
for orig_path, info in state.staged_data.items(): for orig_path, info in state.staged_data.items():
if info['cat'] == state.active_cat: if info['cat'] == state.active_cat:
idx = _extract_index(info['name']) idx = _extract_index(info['name'])
if idx is not None: if idx is not None:
state.index_map[idx] = orig_path state.index_map[idx] = orig_path
staged_indexes.add(idx)
# Add committed images from disk (cached) # 2. Add committed images from disk (cached scan)
disk_map = state.get_disk_index_map(state.active_cat) disk_map = state.get_disk_index_map(state.active_cat)
for idx, path in disk_map.items(): for idx, path in disk_map.items():
if idx not in state.index_map: if idx not in state.index_map:
state.index_map[idx] = path state.index_map[idx] = path
state.committed_indexes.add(idx)
# 3. Load persistent tags for this output folder (NEW)
# This shows which indexes are "taken" even if files moved elsewhere
persistent = SorterEngine.get_persistent_tags_by_category(state.output_dir, state.active_cat)
for idx, filename in persistent.items():
if idx not in state.index_map:
# Check if file still exists in output
full_path = os.path.join(state.output_dir, state.active_cat, filename)
if os.path.exists(full_path):
state.index_map[idx] = full_path
state.committed_indexes.add(idx)
def _extract_index(filename: str) -> Optional[int]: def _extract_index(filename: str) -> Optional[int]:
"""Extract numeric index from filename (e.g., 'Cat_042.jpg' -> 42).""" """Extract numeric index from filename (e.g., 'Cat_042.jpg' -> 42)."""
@@ -380,11 +396,25 @@ def render_sidebar():
with state.sidebar_container: with state.sidebar_container:
ui.label("🏷️ Category Manager").classes('text-xl font-bold mb-2 text-white') ui.label("🏷️ Category Manager").classes('text-xl font-bold mb-2 text-white')
# Number grid (1-25) # Legend for number grid colors
with ui.row().classes('gap-4 mb-2 text-xs'):
ui.label("🟢 Committed").classes('text-green-400')
ui.label("🟡 Staged").classes('text-yellow-400')
ui.label("⚫ Free").classes('text-gray-500')
# Number grid (1-25) with color coding
with ui.grid(columns=5).classes('gap-1 mb-4 w-full'): with ui.grid(columns=5).classes('gap-1 mb-4 w-full'):
for i in range(1, 26): for i in range(1, 26):
is_used = i in state.index_map is_used = i in state.index_map
color = 'green' if is_used else 'grey-9' is_committed = i in state.committed_indexes
# Color logic: green=committed, yellow=staged, grey=free
if is_committed:
color = 'green'
elif is_used:
color = 'yellow'
else:
color = 'grey-9'
def make_click_handler(num: int): def make_click_handler(num: int):
def handler(): def handler():