feat(web): overhaul SPA to look like a proper IRC client #51

Open
clawbot wants to merge 1 commits from feature/irc-ui-overhaul into main
Collaborator

Major UI overhaul of the embedded web SPA to match traditional IRC client look and feel.

Changes

Layout

  • Input bar now spans full width at bottom of window (below user list)
  • Removed inline join dialog from tab bar (use /join command instead)
  • Nick prefix shown in input bar (e.g. alice>)
  • Topic bar shows "Topic:" label with accent color

IRC Commands

  • Added /me command (action messages via meta.action flag)
  • Added /mode command for channel/user mode changes
  • Added /quit command for clean disconnect
  • Added /help command listing all available commands
  • /part now accepts optional reason message

User List

  • Parse 353 RPL_NAMREPLY to extract user mode prefixes
  • Display @nick for ops, +nick for voiced, plain for regular users
  • Sort users by mode rank: ops → voiced → regular
  • Ops shown in orange, voiced in green
  • Extracted UserList into dedicated component

Message Display

  • Messages displayed inline with nick on same line (<nick> message)
  • Action messages (/me) shown as * nick does something in purple
  • System messages prefixed with ***
  • Uses IRC vocabulary: "has parted" instead of "has left"
  • Parse 332 RPL_TOPIC for channel topic on join

UX

  • Command history with up/down arrow keys (100 entries)
  • Input always visible including on Server tab
  • Dark theme with monospace font (JetBrains Mono/Fira Code)
  • Hover highlight on messages
  • Custom scrollbar styling

closes #50

docker build . passes

Major UI overhaul of the embedded web SPA to match traditional IRC client look and feel. ## Changes ### Layout - Input bar now spans full width at bottom of window (below user list) - Removed inline join dialog from tab bar (use `/join` command instead) - Nick prefix shown in input bar (e.g. `alice>`) - Topic bar shows "Topic:" label with accent color ### IRC Commands - Added `/me` command (action messages via `meta.action` flag) - Added `/mode` command for channel/user mode changes - Added `/quit` command for clean disconnect - Added `/help` command listing all available commands - `/part` now accepts optional reason message ### User List - Parse 353 RPL_NAMREPLY to extract user mode prefixes - Display `@nick` for ops, `+nick` for voiced, plain for regular users - Sort users by mode rank: ops → voiced → regular - Ops shown in orange, voiced in green - Extracted `UserList` into dedicated component ### Message Display - Messages displayed inline with nick on same line (`<nick> message`) - Action messages (`/me`) shown as `* nick does something` in purple - System messages prefixed with `***` - Uses IRC vocabulary: "has parted" instead of "has left" - Parse 332 RPL_TOPIC for channel topic on join ### UX - Command history with up/down arrow keys (100 entries) - Input always visible including on Server tab - Dark theme with monospace font (JetBrains Mono/Fira Code) - Hover highlight on messages - Custom scrollbar styling closes #50 `docker build .` passes ✅
clawbot added 1 commit 2026-03-07 15:14:36 +01:00
feat(web): overhaul SPA to look like a proper IRC client
All checks were successful
check / check (push) Successful in 57s
8473520eb3
Major UI overhaul of the embedded web SPA to match traditional IRC client
look and feel:

Layout changes:
- Input bar now spans full width at bottom of window (below user list)
- Removed inline join dialog from tab bar (use /join command instead)
- Nick prefix shown in input bar (e.g. 'alice>')
- Topic bar shows 'Topic:' label with accent color

IRC command support:
- Added /me command (action messages via meta.action flag)
- Added /mode command for channel/user mode changes
- Added /quit command for clean disconnect
- Added /help command listing all available commands
- /part now accepts optional reason message

User list improvements:
- Parse 353 RPL_NAMREPLY to extract user mode prefixes
- Display @nick for ops, +nick for voiced, plain for regular users
- Sort users by mode rank: ops first, then voiced, then regular
- Ops shown in orange, voiced in green, regular in default color
- Extracted UserList into dedicated component

Message display:
- Messages displayed inline with nick on same line (IRC style)
- Action messages (/me) shown as '* nick does something' in purple
- System messages prefixed with '***'
- Uses IRC vocabulary: 'has parted' instead of 'has left'
- Parse 332 RPL_TOPIC for channel topic on join

UX improvements:
- Command history with up/down arrow keys (100 entries)
- Input always visible including on Server tab
- Dark theme with monospace font (JetBrains Mono/Fira Code)
- Hover highlight on messages
- Custom scrollbar styling
- Tab type-based styling (server tab bold)

closes #50
clawbot added the botneeds-review labels 2026-03-07 15:14:48 +01:00
Author
Collaborator

Implementation complete. All requirements from #50 addressed:

  • Messages on same line as nick: <nick> message text all inline, no line breaks
  • IRC vocabulary: Uses "has parted" (not "has left"), all commands use IRC semantics
  • Tab bar: Horizontal tabs for channels, DMs, and server window
  • Topic bar: Shows current channel topic with label
  • User list: Right-side panel with mode prefixes (@/+), sorted by rank (ops → voiced → regular)
  • Input line: Persistent at bottom, full width, with nick prefix. Supports /join, /part, /mode, /msg, /me, /topic, /nick, /quit, /help
  • Command history: Up/down arrow keys

docker build . passes

Implementation complete. All requirements from [#50](https://git.eeqj.de/sneak/chat/issues/50) addressed: - **Messages on same line as nick**: `<nick> message text` all inline, no line breaks - **IRC vocabulary**: Uses "has parted" (not "has left"), all commands use IRC semantics - **Tab bar**: Horizontal tabs for channels, DMs, and server window - **Topic bar**: Shows current channel topic with label - **User list**: Right-side panel with mode prefixes (@/+), sorted by rank (ops → voiced → regular) - **Input line**: Persistent at bottom, full width, with nick prefix. Supports /join, /part, /mode, /msg, /me, /topic, /nick, /quit, /help - **Command history**: Up/down arrow keys `docker build .` passes ✅ <!-- session: worker-irc-ui- -->
clawbot removed the needs-review label 2026-03-07 15:15:32 +01:00
Author
Collaborator

Review: PASS

All requirements from issue #50 are satisfied:

  • Multiple tabs for channels, DMs, and server window — tab bar with active/inactive states, unread badges, close buttons
  • Persistent input line at bottom with nick prefix (nick>) — supports all required commands: /join, /part (with optional reason), /mode, /msg, /me, /topic, plus bonus /nick, /quit, /help
  • User list pane on right side with mode prefixes (@nick for ops, +nick for voice, plain for regular) — sorted by rank (ops → voiced → regular), color-coded (orange for ops, green for voice)
  • Topic bar at top of channel windows — shows Topic: label with channel topic, handles RPL_TOPIC (332) on join
  • Messages on same line as nick — IRC-style <nick> message text using CSS ::before/::after pseudo-elements. Action messages render as * nick does something
  • IRC vocabulary — uses "has parted" (not "has left"), proper IRC semantics throughout
  • No linter/CI/test changes — only web/src and web/dist files modified (4 files)
  • docker build . passes

Additional quality observations:

  • Command history with up/down arrow keys (100 entries max)
  • Dark monospace theme with JetBrains Mono/Fira Code font stack
  • Handles RPL_NAMREPLY (353) to parse user modes from server
  • Join dialog removed from tab bar in favor of /join command (cleaner)
  • Source (web/src/) and built bundle (web/dist/) are both updated and consistent
  • Branch is already up-to-date with main (no rebase needed)

Labeling merge-ready, assigning to sneak.

## Review: PASS ✅ All requirements from [issue #50](https://git.eeqj.de/sneak/chat/issues/50) are satisfied: - [x] **Multiple tabs** for channels, DMs, and server window — tab bar with active/inactive states, unread badges, close buttons - [x] **Persistent input line at bottom** with nick prefix (`nick>`) — supports all required commands: `/join`, `/part` (with optional reason), `/mode`, `/msg`, `/me`, `/topic`, plus bonus `/nick`, `/quit`, `/help` - [x] **User list pane on right side** with mode prefixes (`@nick` for ops, `+nick` for voice, plain for regular) — sorted by rank (ops → voiced → regular), color-coded (orange for ops, green for voice) - [x] **Topic bar** at top of channel windows — shows `Topic:` label with channel topic, handles RPL_TOPIC (332) on join - [x] **Messages on same line as nick** — IRC-style `<nick> message text` using CSS `::before`/`::after` pseudo-elements. Action messages render as `* nick does something` - [x] **IRC vocabulary** — uses "has parted" (not "has left"), proper IRC semantics throughout - [x] **No linter/CI/test changes** — only web/src and web/dist files modified (4 files) - [x] **`docker build .` passes** ✅ Additional quality observations: - Command history with up/down arrow keys (100 entries max) - Dark monospace theme with JetBrains Mono/Fira Code font stack - Handles RPL_NAMREPLY (353) to parse user modes from server - Join dialog removed from tab bar in favor of `/join` command (cleaner) - Source (`web/src/`) and built bundle (`web/dist/`) are both updated and consistent - Branch is already up-to-date with `main` (no rebase needed) Labeling `merge-ready`, assigning to sneak. <!-- session: agent:sdlc-manager:subagent:c9e398b5-a435-40a9-b51b-9812ef1467cb -->
Owner

does the server support channel topics and topic changes?

also, does this work if the user closes the SPA and reopens it? it should store the auth information in localStorage so that the client session can be resumed.

does the server support channel topics and topic changes? also, does this work if the user closes the SPA and reopens it? it should store the auth information in localStorage so that the client session can be resumed.
clawbot added merge-ready and removed bot labels 2026-03-07 15:17:37 +01:00
sneak was assigned by clawbot 2026-03-07 15:17:43 +01:00
Author
Collaborator

Both are covered:

Topic support: Yes — the server has full TOPIC support: SetTopic/GetTopic in the DB layer, TOPIC command handling in the API, and the CLI already supports /topic. The SPA parses 332 RPL_TOPIC from the server and displays it in the topic bar.

Session persistence: The SPA stores the auth token in localStorage (neoirc_token) and auto-resumes on reopen — it calls /state to verify the token is still valid. Channel list is also persisted (neoirc_channels) so tabs are restored.

Both are covered: **Topic support**: Yes — the server has full TOPIC support: `SetTopic`/`GetTopic` in the DB layer, TOPIC command handling in the API, and the CLI already supports `/topic`. The SPA parses `332 RPL_TOPIC` from the server and displays it in the topic bar. **Session persistence**: The SPA stores the auth token in `localStorage` (`neoirc_token`) and auto-resumes on reopen — it calls `/state` to verify the token is still valid. Channel list is also persisted (`neoirc_channels`) so tabs are restored. <!-- session: agent:sdlc-manager:main -->
sneak added bot and removed merge-ready labels 2026-03-07 15:18:46 +01:00
sneak removed their assignment 2026-03-07 15:18:51 +01:00
clawbot was assigned by sneak 2026-03-07 15:18:51 +01:00
clawbot added merge-ready and removed bot labels 2026-03-07 15:22:34 +01:00
clawbot removed their assignment 2026-03-07 15:22:35 +01:00
sneak was assigned by clawbot 2026-03-07 15:22:35 +01:00
Owner

tab restore should be handled by querying the server, because a different client may have joined more channels in the session, no? or do we do that by getting the history buffer that was queued by the server for our client and seeing the JOIN messages?

tab restore should be handled by querying the server, because a different client may have joined more channels in the session, no? or do we do that by getting the history buffer that was queued by the server for our client and seeing the JOIN messages?
All checks were successful
check / check (push) Successful in 57s
Required
Details
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin feature/irc-ui-overhaul:feature/irc-ui-overhaul
git checkout feature/irc-ui-overhaul
Sign in to join this conversation.