TUI: replace mode-flag booleans with a single mode enum #2

Open
opened 2026-05-07 09:53:08 +02:00 by arne · 0 comments
Owner

Problem

The TUI model in internal/tui/tui.go tracks UI state via five booleans plus one string field:

composing        bool
addingContact    bool
searching        bool
searchActive     bool
showHelp         bool
composeInReplyTo string

Mutual exclusion is enforced only by the order of switch cases in Update. As the TUI grows (e.g. multi-line compose, message-cursor mode, modal dialogs), illegal combinations become easy to introduce — composing && searching == true is currently meaningless but representable.

Proposal

Replace the booleans with a single mode enum:

type uiMode int

const (
    modeNav uiMode = iota
    modeCompose
    modeAddContact
    modeSearchInput
    modeSearchResults
    modeHelp
)

Each mode owns its associated buffer (compose buffer, contact URL buffer, search query). Update dispatches on m.mode instead of falling through a chain of switch{} case x: flags.

Acceptance criteria

  • All five boolean flags removed; single mode field replaces them
  • Update dispatches via mode, not chained boolean checks
  • All existing TUI behavior preserved (compose, reply, add-contact, search, help)
  • No regressions in the smoke test (msg serve + msg round trip from a peer)

Context

Surfaced in the v1.0.0 self-review (issue #2 of that review, now an issue here for tracking). Not a v1 blocker; do post-ship.

## Problem The TUI model in `internal/tui/tui.go` tracks UI state via five booleans plus one string field: ```go composing bool addingContact bool searching bool searchActive bool showHelp bool composeInReplyTo string ``` Mutual exclusion is enforced only by the order of switch cases in `Update`. As the TUI grows (e.g. multi-line compose, message-cursor mode, modal dialogs), illegal combinations become easy to introduce — `composing && searching == true` is currently meaningless but representable. ## Proposal Replace the booleans with a single `mode` enum: ```go type uiMode int const ( modeNav uiMode = iota modeCompose modeAddContact modeSearchInput modeSearchResults modeHelp ) ``` Each mode owns its associated buffer (compose buffer, contact URL buffer, search query). `Update` dispatches on `m.mode` instead of falling through a chain of `switch{} case x:` flags. ## Acceptance criteria - [ ] All five boolean flags removed; single `mode` field replaces them - [ ] `Update` dispatches via `mode`, not chained boolean checks - [ ] All existing TUI behavior preserved (compose, reply, add-contact, search, help) - [ ] No regressions in the smoke test (`msg serve` + `msg` round trip from a peer) ## Context Surfaced in the v1.0.0 self-review (issue #2 of that review, now an issue here for tracking). Not a v1 blocker; do post-ship.
Sign in to join this conversation.
No labels
needs-triage
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
arne/msg#2
No description provided.