← Whispering

feat: Implement dynamic show/hide for text panels

6122a076eae89545e8f2011529f9ecbf8745e5d5 · Claude · Dec 1, 2025 20:38

- Always create output panels but control visibility with state
- Toggle button now actually shows/hides panels dynamically
- Panels slide in/out smoothly without recreating the UI
- Window layout updates properly when toggling visibility

This fixes the issue where clicking 'Show/Hide Text' didn't do anything.

+20 −6 · 3 files changed

  • src/whispering_ui/components/output.py +5 −0
  • src/whispering_ui/components/sidebar.py +9 −3
  • src/whispering_ui/main.py +6 −3
diff --git a/src/whispering_ui/components/output.py b/src/whispering_ui/components/output.py
index bf4ad34..80025f8 100644
--- a/src/whispering_ui/components/output.py
+++ b/src/whispering_ui/components/output.py
@@ -14,6 +14,9 @@ def create_output_panels(state: AppState):
 
     Args:
         state: Application state
+
+    Returns:
+        The output container element for visibility control
     """
 
     output_container = ui.column().classes('flex-grow p-4 gap-3')
@@ -70,3 +73,5 @@ def create_output_panels(state: AppState):
             trans_count.text = f'{tc} chars, {tw} words'
 
         ui.timer(0.2, update_outputs)
+
+    return output_container
diff --git a/src/whispering_ui/components/sidebar.py b/src/whispering_ui/components/sidebar.py
index 47cac1f..4e6b048 100644
--- a/src/whispering_ui/components/sidebar.py
+++ b/src/whispering_ui/components/sidebar.py
@@ -10,13 +10,14 @@ from whispering_ui.state import AppState
 from whispering_ui.bridge import ProcessingBridge
 
 
-def create_sidebar(state: AppState, bridge: ProcessingBridge):
+def create_sidebar(state: AppState, bridge: ProcessingBridge, output_container=None):
     """
     Create the sidebar control panel with simplified bindings.
 
     Args:
         state: Application state
         bridge: Processing bridge
+        output_container: Optional output container for show/hide control
     """
 
     # Container for all controls
@@ -44,7 +45,7 @@ def create_sidebar(state: AppState, bridge: ProcessingBridge):
         # === TOGGLE TEXT BUTTON ===
         toggle_btn = ui.button(
             'Show Text ▶' if not state.text_visible else 'Hide Text ◀',
-            on_click=lambda: _toggle_text(state, toggle_btn)
+            on_click=lambda: _toggle_text(state, toggle_btn, output_container)
         ).classes('w-full mb-2')
 
         ui.separator().classes('my-2')
@@ -193,10 +194,15 @@ def create_sidebar(state: AppState, bridge: ProcessingBridge):
         ui.timer(0.1, update_ui)
 
 
-def _toggle_text(state: AppState, btn):
+def _toggle_text(state: AppState, btn, output_container):
     """Toggle text visibility."""
     state.text_visible = not state.text_visible
     btn.text = 'Hide Text ◀' if state.text_visible else 'Show Text ▶'
+
+    # Show/hide the output container
+    if output_container:
+        output_container.set_visibility(state.text_visible)
+
     ui.notify(f'Text panels {"shown" if state.text_visible else "hidden"}')
 
 
diff --git a/src/whispering_ui/main.py b/src/whispering_ui/main.py
index 7ba0945..49a65c2 100644
--- a/src/whispering_ui/main.py
+++ b/src/whispering_ui/main.py
@@ -109,9 +109,12 @@ def main():
         # Sidebar (always visible)
         create_sidebar(state, bridge)
 
-        # Output panels (conditionally visible)
-        if state.text_visible:
-            create_output_panels(state)
+        # Output panels (always created, visibility controlled by state)
+        output_container = create_output_panels(state)
+
+        # Set initial visibility
+        if not state.text_visible:
+            output_container.set_visibility(False)
 
     # === SAVE SETTINGS ON EXIT ===
     def save_settings_on_exit():