PHP Classes

File: docs/proposals/TelnetChatClient.md

Recommend this page to a friend!
  Packages of Matthew Asham   Binkterm PHP   docs/proposals/TelnetChatClient.md   Download  
File: docs/proposals/TelnetChatClient.md
Role: Auxiliary data
Content type: text/markdown
Description: Auxiliary data
Class: Binkterm PHP
Bulletin board system based on the Web
Author: By
Last change:
Date: 1 month ago
Size: 12,553 bytes
 

Contents

Class file image Download

This proposal is a draft, was generated by AI, and may not have been reviewed for accuracy.

Terminal Local Chat Client

Summary

BinktermPHP already has a web-side local chat system with chat rooms, direct messages, online user presence, moderation commands, Matterbridge room relays, and incremental polling endpoints. The terminal server does not currently expose that system from the shared Telnet/SSH main menu.

This proposal adds a terminal local chat client that lets a user:

  • enter local chat from the main menu
  • select a message room
  • see who is online
  • read recent messages in a dedicated message pane
  • type and send new messages from an input box

The implementation should remain consistent with the existing terminal architecture: terminal-side code stays in telnet/src/, uses REST APIs only, and is shared by both the Telnet and SSH daemons.

Current implementation note

The feature has since been implemented. The shipped terminal client differs from this draft in a few important ways:

  • the current wide layout uses a left navigation pane, a larger message pane, and a full-width compose box
  • online users are summarized in the left navigation pane rather than in a separate right-hand sidebar
  • chat message bodies are rendered with the shared terminal Markdown renderer used by echomail and netmail viewers
  • the terminal client uses polling for live updates rather than SSE

Treat the remainder of this document as design history rather than an exact description of the current UI.

Goals

  • Add a main-menu entry for local chat in terminal services
  • Support room selection from the terminal client
  • Display online users alongside the active room
  • Display recent room messages in a dedicated pane
  • Provide a text-entry box for sending messages
  • Reuse the existing local chat database and web/API business logic
  • Keep Telnet and SSH behavior aligned through the shared `BbsSession` flow

Non-Goals

  • Replacing the existing web chat UI
  • Rewriting the terminal UI framework globally
  • Building a full terminal clone of the browser chat feature set on day one
  • Introducing direct database access from `telnet/src/`
  • Designing a new real-time protocol for terminal chat in the first iteration

Current State

Existing chat backend

The web/API side already provides:

  • `GET /api/chat/rooms`
  • `GET /api/chat/online`
  • `GET /api/chat/messages`
  • `POST /api/chat/send`
  • `GET /api/chat/poll`
  • `POST /api/chat/moderate`

It also already stores:

  • room messages
  • DM messages
  • chat room bans
  • AI bot participation
  • Matterbridge-linked room traffic

This means the terminal feature can be implemented as a client over existing APIs, not as a new chat subsystem.

Existing terminal integration points

The shared terminal menu is in telnet/src/BbsSession.php. It already instantiates feature handlers such as:

  • `ShoutboxHandler`
  • `BulletinsHandler`
  • `PollsHandler`
  • `DoorHandler`
  • `FileHandler`
  • `InterestsHandler`
  • `QwkMenuHandler`

The main menu already has a Community section with options like:

  • `W` Who's Online
  • `P` Polls
  • `S` Shoutbox
  • `D` Door Games

That is the right place to add a Local Chat entry.

Existing terminal UI constraints

The terminal side already supports:

  • resize-aware redraws in `BbsSession`
  • ANSI-aware rendering
  • line drawing / boxed layouts
  • blocking key loops
  • prompt-based text entry

It does not currently have a reusable split-pane widget system. A chat client will therefore need a dedicated handler that owns its own screen redraw loop.

Proposed Feature

1. Add a Local Chat menu entry

Add a new option to the terminal main menu, likely in the Community section:

  • `C) Local Chat`

Behavior:

  • only show it when `BbsConfig::isFeatureEnabled('chat')` is true
  • instantiate a new terminal-side handler, for example `telnet/src/ChatHandler.php`
  • wire the handler into both `telnet/telnet_daemon.php` and `ssh/ssh_daemon.php` include lists if a new shared class is added

This keeps the entry point consistent with how ShoutboxHandler and other menu features are exposed today.

2. Room picker screen

The first screen inside terminal chat should be a room selector rather than dropping the user straight into a hard-coded room.

Suggested contents:

  • header/title
  • numbered list of active rooms from `GET /api/chat/rooms`
  • room description when available
  • current selection marker
  • shortcut to refresh room list
  • shortcut to return to the main menu

Suggested actions:

  • number key or arrow-key selection
  • `Enter` to open selected room
  • `R` refresh
  • `Q` quit back to the main menu

Direct messages can be deferred to a later phase. The user request is centered on room chat and online presence, so room support should come first.

3. Split-pane terminal chat screen

Inside a selected room, present a dedicated full-screen chat view with three functional regions:

  • left pane or top strip: room list / current room name
  • main pane: scrolling message area
  • side pane: users online
  • bottom input box: text entry field

The exact layout should adapt to terminal width:

  • wide terminals: room list on the left, online users on the right, messages in the center, input at bottom
  • medium terminals: messages full width with online users in a narrow right pane
  • narrow terminals: stacked layout, with users-online summarized in a compact bar or modal list

Minimum required user-visible behavior:

  • user can tell which room is active
  • user can read recent room messages without losing context
  • user can see who is online
  • user can type and send a message without leaving the screen

4. Message display behavior

The message pane should:

  • load recent history with `GET /api/chat/messages?room_id=<id>&limit=<n>`
  • render newest messages at the bottom
  • support a fixed scrollback window appropriate to terminal height
  • wrap long messages to the current pane width
  • redraw cleanly on terminal resize
  • show timestamps using terminal-side user timezone formatting

Suggested message format:

  • `[time] username: message`

Terminal v1 should render chat bodies as plain terminal text, not HTML. Any Markdown or web markup should degrade safely to text. ANSI or pipe-code handling should be explicitly decided during implementation so terminal chat does not accidentally allow disruptive escape output.

5. Online users pane

The online users pane should call GET /api/chat/online and show:

  • username
  • optional bot marker for AI bots
  • optional location if it fits

Important detail: the current API returns globally online users, not room membership. The proposal should keep that behavior for phase 1 and label the pane accordingly as Online Users, not Users In Room.

If room-specific presence becomes important later, that requires backend changes and a separate design decision.

6. Input box and sending flow

The input box should support:

  • a single-line compose field for v1
  • local editing with backspace and basic cursor movement if practical
  • `Enter` to send
  • `Esc` or `Ctrl+C` to leave chat

Sending should use POST /api/chat/send with:

  • `room_id`
  • `body`

Expected behavior:

  • optimistic local echo is acceptable if the API response succeeds
  • on failure, render a local system-status line in the message pane
  • preserve the user in the same room after sending

The terminal client should also support /help and allow room moderation commands already implemented in the API such as /kick and /ban, but only as pass-through commands. It should not reimplement moderation rules locally.

7. Incremental refresh / polling loop

For the first version, use polling rather than SSE.

Recommended model:

  • initial history load via `/api/chat/messages`
  • incremental updates via `/api/chat/poll?since_id=<lastSeenId>`
  • periodic refresh of `/api/chat/online`

Suggested cadence:

  • poll messages every 1 to 2 seconds while the chat screen is active
  • poll online users less frequently, such as every 10 to 15 seconds
  • immediately redraw when: - a new message arrives - the user sends a message - the terminal size changes - the active room changes

This fits the current synchronous terminal architecture better than introducing a background SSE client inside the Telnet/SSH session loop.

Proposed Implementation Areas

New terminal handler

Add a new handler class in telnet/src/, likely:

  • `telnet/src/ChatHandler.php`

Responsibilities:

  • fetch room list
  • manage active room selection
  • manage message history and last-seen IDs
  • poll for updates
  • draw the chat interface
  • collect user input
  • send messages through the API

Main menu wiring

Update:

  • `telnet/src/BbsSession.php`

to:

  • instantiate `ChatHandler`
  • add the new menu label and hotkey
  • dispatch the new menu option
  • show the option only when chat is enabled

Because terminal-side classes are manually included, also update:

  • `telnet/telnet_daemon.php`
  • `ssh/ssh_daemon.php`

if the new handler is shared across both transports, which it should be.

Translation work required during implementation

Implementation will need new keys in config/i18n/*/terminalserver.php for items such as:

  • chat menu label
  • room list title
  • online users title
  • message input prompt
  • refresh / quit / switch-room prompts
  • error and status text

All locales will need to stay in sync when the feature is actually built.

Documentation updates required during implementation

If the feature is implemented, update at least:

  • `docs/TerminalServer.md`

to document:

  • the new main-menu item
  • room selection
  • chat controls
  • any limitations of polling or online-user scope

API Considerations

APIs that are already sufficient

The current API is already enough for an initial room-based terminal client:

  • room listing
  • online users
  • room history
  • sending
  • incremental polling

Possible follow-up API improvements

These are optional and should not block v1:

  • a single combined endpoint for `rooms + online + current room history`
  • room-specific online presence
  • explicit plain-text rendering fields if markup sanitization becomes an issue
  • unread counts per room for terminal navigation

UX Recommendation

Phase 1

Implement a solid room-based client first:

  • main-menu link
  • room picker
  • active room chat screen
  • online users pane
  • message pane
  • single-line input box
  • incremental polling

This directly satisfies the requested workflow and avoids overreaching.

Phase 2

Enhance the client after the core flow works:

  • in-chat room switching without returning to selector
  • scrollback browsing for older messages
  • compact DM selector
  • better narrow-terminal layout
  • optional sound/beep or unread indicator behavior

Phase 3

Consider richer parity with the web UI:

  • direct messages
  • unread room badges
  • room moderation shortcuts in visible UI
  • terminal-side mention highlighting
  • a more advanced editor for multi-line messages if needed

Risks

Resize and redraw complexity

A split-pane terminal view is more complex than the existing prompt-loop handlers.

Mitigation:

  • keep all drawing logic isolated in a dedicated handler
  • treat resize as a full redraw event
  • start with simple panes and deterministic layout rules

Polling load

Frequent chat polling adds more API traffic than current terminal features.

Mitigation:

  • only poll while the user is actively inside chat
  • keep the message poll interval short but bounded
  • refresh online users less frequently than messages

Markup and terminal safety

Web chat messages may contain formatting that does not translate cleanly to a terminal.

Mitigation:

  • display plain text in v1
  • sanitize or normalize control characters before rendering
  • avoid interpreting user-supplied content as raw ANSI unless explicitly intended

Presence mismatch

The online-users API reflects global online status, not per-room occupancy.

Mitigation:

  • label the pane accurately
  • defer room-scoped presence until the backend supports it

Recommendation

Build this as a new terminal chat handler backed entirely by the existing local chat API, and add it to the shared main menu as a Community feature.

The best first implementation is a room-based polling client with:

  • room selection
  • an online users pane
  • a message pane
  • a bottom text box

That meets the stated requirement cleanly, fits the current Telnet/SSH architecture, and avoids unnecessary backend churn.