Files
sorting-sorted/tab_gallery_sorter.py
2026-01-18 22:54:35 +01:00

109 lines
4.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import streamlit as st
import os
import math
from engine import SorterEngine
# --- CALLBACKS ---
def cb_tag_image(img_path, selected_cat):
# Guard against tagging with a separator
if selected_cat.startswith("---") or selected_cat == "":
st.toast("⚠️ Select a valid category first!", icon="🚫")
return
staged = SorterEngine.get_staged_data()
ext = os.path.splitext(img_path)[1]
count = len([v for v in staged.values() if v['cat'] == selected_cat]) + 1
new_name = f"{selected_cat}_{count:03d}{ext}"
SorterEngine.stage_image(img_path, selected_cat, new_name)
def cb_untag_image(img_path):
SorterEngine.clear_staged_item(img_path)
def cb_delete_image(img_path):
SorterEngine.delete_to_trash(img_path)
def cb_apply_batch(current_batch, path_o, cleanup_mode):
SorterEngine.commit_batch(current_batch, path_o, cleanup_mode)
# --- FRAGMENT 1: SIDEBAR (Manager) ---
@st.fragment
def render_sidebar_content():
st.divider()
st.subheader("🏷️ Category Manager")
# 1. GET CATEGORIES & PROCESS SEPARATORS
cats = SorterEngine.get_categories()
# Setup List with Separators
processed_cats = []
last_char = ""
if cats:
for cat in cats:
current_char = cat[0].upper()
if last_char and current_char != last_char:
processed_cats.append(f"--- {current_char} ---")
processed_cats.append(cat)
last_char = current_char
# 2. RADIO SELECTION
# We default to the first real category if nothing is selected
if "t5_active_cat" not in st.session_state:
st.session_state.t5_active_cat = cats[0] if cats else "Default"
# Handle case where previously selected cat was deleted
if st.session_state.t5_active_cat not in processed_cats:
st.session_state.t5_active_cat = cats[0] if cats else "Default"
selection = st.radio("Active Tag", processed_cats, key="t5_radio_select")
# Update global state (but ignore separators)
if not selection.startswith("---"):
st.session_state.t5_active_cat = selection
st.divider()
# 3. TABS: ADD / EDIT
tab_add, tab_edit = st.tabs([" Add", "✏️ Edit"])
# --- ADD TAB ---
with tab_add:
c1, c2 = st.columns([3, 1])
new_cat = c1.text_input("New Name", label_visibility="collapsed", placeholder="New...", key="t5_new_cat")
if c2.button("Add", key="btn_add_cat"):
if new_cat:
SorterEngine.add_category(new_cat)
st.rerun()
# --- EDIT TAB (Rename & Delete) ---
with tab_edit:
# Determine target (block separators)
target_cat = st.session_state.t5_active_cat
is_valid = target_cat and not target_cat.startswith("---") and target_cat in cats
if is_valid:
st.caption(f"Editing: **{target_cat}**")
# RENAME SECTION
# TRICK: We use the category name in the key.
# This forces Streamlit to reset the input box when you switch categories.
rename_val = st.text_input("Rename to:", value=target_cat, key=f"ren_{target_cat}")
if st.button("💾 Save Name", key=f"save_{target_cat}", use_container_width=True):
if rename_val and rename_val != target_cat:
SorterEngine.rename_category(target_cat, rename_val)
st.session_state.t5_active_cat = rename_val # Update selection
st.rerun()
st.markdown("---")
# DELETE SECTION
if st.button("🗑️ Delete Category", key=f"del_cat_{target_cat}", type="primary", use_container_width=True):
SorterEngine.delete_category(target_cat)
# Fallback to first available category after delete
remaining = SorterEngine.get_categories()
st.session_state.t5_active_cat = remaining[0] if remaining else "Default"
st.rerun()
else:
st.info("Select a valid category above to edit.")