diff --git a/client/src/ui/docs/ui_redraws.md b/client/src/ui/docs/ui_redraws.md new file mode 100644 index 0000000..4d3628b --- /dev/null +++ b/client/src/ui/docs/ui_redraws.md @@ -0,0 +1,34 @@ +# UI Redraw Logic (`needs_redraw` Flag) + +## Problem + +The main UI loop in `client/src/ui/handlers/ui.rs` uses `crossterm_event::poll` with a short timeout to remain responsive to both user input and asynchronous operations (like login results arriving via channels). However, calling `terminal.draw()` unconditionally in every loop iteration caused constant UI refreshes and high CPU usage, even when idle. + +## Solution + +A boolean flag, `needs_redraw`, was introduced in the main loop scope to control when the UI is actually redrawn. + +## Mechanism + +1. **Initialization:** `needs_redraw` is initialized to `true` before the loop starts to ensure the initial UI state is drawn. +2. **Conditional Drawing:** The `terminal.draw(...)` call is wrapped in an `if needs_redraw { ... }` block. +3. **Flag Reset:** Immediately after a successful `terminal.draw(...)` call, `needs_redraw` is set back to `false`. +4. **Triggering Redraws:** The `needs_redraw` flag is explicitly set to `true` only when a redraw is actually required. + +## When `needs_redraw` Must Be Set to `true` + +To ensure the UI stays up-to-date without unnecessary refreshes, `needs_redraw = true;` **must** be set in the following situations: + +1. **After Handling User Input:** When `crossterm_event::poll` returns `true`, indicating a keyboard/mouse event was received and processed by `event_handler.handle_event`. +2. **During Active Loading States:** If an asynchronous operation is in progress and a visual indicator (like a loading dialog) is active (e.g., checking `if app_state.ui.dialog.is_loading`). This keeps the loading state visible while waiting for the result. +3. **After Processing Async Results:** When the result of an asynchronous operation (e.g., received from an `mpsc::channel` like `login_result_receiver`) is processed and the application state is updated (e.g., dialog content changed, data updated). +4. **After Internal State Changes:** If any logic *outside* the direct event handling block modifies state that needs to be visually reflected (e.g., the position change logic loading new data into the form). + +## Rationale + +This approach balances UI responsiveness for asynchronous tasks and user input with CPU efficiency by avoiding redraws when the application state is static. + +## Maintenance Note + +When adding new asynchronous operations or internal logic that modifies UI-relevant state outside the main event handler, developers **must remember** to set `needs_redraw = true` at the appropriate point after the state change to ensure the UI updates correctly. Failure to do so can result in a stale UI. +