13 Commits
Author SHA1 Message Date
Storm Dragon 6817ecd90b Touch ups and additional capabilities added to fifo functionality. Sample Fenrir scripts in extra 2026-09-06 17:55:21 -04:00
Storm Dragon 97fcde7e96 Add mnemonic mute controls 2026-09-05 00:57:37 -04:00
Storm Dragon ef19a558d2 Redesign default tree controls 2026-09-05 00:34:40 -04:00
Brandon McGintyandClaude Opus 5 07c923c4c9 bound the tree rebuild against a cyclic channel graph
rebuild_rec followed parent/child links with no depth limit, so a channel
graph in which a channel is its own ancestor recursed until the process ran
out of memory.

Cap the depth and give the whole rebuild a single node budget. Accumulating
into one slice rather than returning a new slice per node makes that budget
apply to the tree as a whole instead of to each level, and removes an
allocation per node.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 12:30:29 -04:00
Brandon McGintyandClaude Opus 5 314b838e33 bound the chat scrollback and wrap only new lines
AddLine re-wrapped every stored line on each append, and the buffer it
re-wrapped had no upper bound, so the work a session did grew as the square
of its length. Wrapping also built each display line by concatenating one
rune at a time, reallocating per character.

Wrap just the line being added, build it with a strings.Builder, and cap the
retained history. Trimming is done a block at a time because it forces a
rebuild; discarding a single line per append would re-wrap the whole buffer
again.

Measured over the same benchmark, 4000 lines went from 42s and 18.8GB
allocated to 4ms and 1MB, and 20000 lines now complete in 85ms.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 12:30:23 -04:00
Brandon McGintyandClaude Opus 5 872149c977 run all terminal work on the UI goroutine and lock shared client state
Route network and audio callbacks through a bounded UI queue.
Protocol handlers, the audio thread, and key handlers all drew to
termbox widgets directly, which is a data race against the render
loop. postUI is now the only path from a callback to a widget, work is
dropped during shutdown, and the queue never blocks the caller.

Guard the mutable client state with mutexes.
Connection and transmission flags, the selected user, the muted
channel set, and the audio stream pointer were each read and written
from at least two goroutines. Lookups that walk the client's user and
channel maps take the client lock and copy what they need.

Snapshot the display string when a tree item is built.
Tree items held live pointers and formatted themselves during
rendering, so a user removed between rebuild and draw was dereferenced
on the render path.

Cancel reconnect retries on shutdown and release audio before
reconnecting.
Quitting during a retry left the goroutine sleeping until its timer
expired, and a reconnect built a second OpenAL stream on top of the
first. Cleanup is idempotent so repeated disconnect events are safe.

Make UI shutdown idempotent and join the event poller.
Close could be called more than once, and the polling goroutine could
be left trying to deliver an event after Run had returned. Run now
also reports a termbox initialization failure instead of returning nil.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 14:42:52 -04:00
Brandon McGintyandClaude Opus 5 17a4662c6c strip terminal control sequences from server-supplied text
Remove control, DEL, and bidi characters before display.
HTML escaping was the only filter, which leaves ANSI and OSC escape
sequences intact. A remote user could move the cursor, recolour the
screen, or reorder what was shown by putting escape codes in a
message, a nickname, or a channel name. Names rendered in the channel
tree go through the same filter now.

Keep the text box cursor and the prompt on rune boundaries.
Both indexed by byte, so editing a line containing multi-byte
characters could split one and render replacement characters.

Handle text view lines that carry no timestamp.
Toggling timestamps assumed every stored line had one and sliced past
the end of lines that did not.

Ignore key events on an empty tree.
The handlers indexed the item list before checking that it had any
items.

Remove the beep helpers.
They shelled out to an optional "beep" binary and panicked when it was
absent.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 14:42:52 -04:00
Storm Dragon 7fed25e8d0 Fix chat redraw and input history 2026-07-14 19:08:38 -04:00
Storm Dragon 342f934029 Improve action menu escape handling
Make the F11 action menu close through a shared close action so Escape and the explicit Close actions menu item follow the same path. Treat Escape-prefixed Up and Down events as close inputs while the action menu is active, which handles termbox InputAlt behavior after pressing Escape. Preserve and restore the user/channel tree selection across action menu open and close, and preserve selection across live tree rebuilds.

Tested with: GOCACHE=/tmp/barnard-go-cache go test ./...
2026-06-28 23:57:29 -04:00
Storm Dragon cc483685ef Add actions menu admin features 2026-05-19 01:06:01 -04:00
Storm Dragon dd425563ba Experimental changes, switched to toml instead of yaml. Hopefully everyone will like this as much as I do. 2025-12-10 20:52:37 -05:00
Storm Dragon 2e337db3c5 Updated everything for dependencies. All sub packages are now part of the project. This was a massive update, hopefully won't have to be reverted. 2025-01-16 17:03:01 -05:00
Storm Dragon 3f0246a4f8 Initial commit, lots of cleanup and stuff to do, it may not work. 2025-01-15 23:43:44 -05:00