Update gallery_app.py
This commit is contained in:
@@ -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():
|
||||||
|
|||||||
Reference in New Issue
Block a user