AudioPlaybackService enhanced with pause/resume, volume control, and playback-finished events
Fixed: wrapped audio/file messages now remain clickable on all lines (attachment metadata propagated through word-wrap)
IRC gateway formats audio messages as ♪ [Audio: filename] url
Server detects audio files by extension via FileValidationHelper.IsAudioFile()
File Downloads
Press Enter on a file message in the TUI client to download and open it with the system default application
ApiClient.DownloadFileAsync() streams file downloads from the server
File and audio messages in the chat list now show colored indicators with interaction hints
File Cleanup Service
FileCleanupService (BackgroundService) periodically removes old uploaded files
Configurable via Storage:CleanupIntervalHours (default 1h) and Storage:RetentionDays (default 30d)
Data Migration Service
DataMigrationService runs at startup to handle schema/data evolution
Ensures #general channel and pre-existing channels are marked public
Migrates legacy ANSI escape codes in image messages to printable color tags ({F:RRGGBB}, {B:RRGGBB}, {X})
Migrates legacy single-object EmbedJson to array format
Promotes usernames listed in Server:Admins config to Admin role
True Transparent Background
Transparent theme now uses the terminal's native background instead of solid black
Powered by Color.None (alpha=0) which emits ANSI CSI 49m (default background) instead of explicit RGB
Terminal transparency, acrylic, wallpaper effects now show through the TUI
Dialogs retain solid DarkGray background for readability
Uses local Terminal.Gui fork (submodule) with transparent color support pending upstream merge (gui-cs/Terminal.Gui#4234)
Enhanced Status Bar
Status bar now shows EchoHub branding at the start
Connection state is color-coded: green (Connected), red (Disconnected), yellow (transitional states like Connecting, Reconnecting, Authenticating)
Current channel shows its type: #channel - public or #channel - private
Remember Me (Session Persistence)
"Remember me" checkbox in the connect dialog — saves a 30-day refresh token so users can reconnect without entering their password
Saved servers with active sessions show [session] indicator in the connect dialog and saved servers list
Token-based login: selecting a saved server with a session lets you click Login with an empty password
Graceful expiry handling: if the saved session is expired or revoked, shows an error and prompts for password
Refresh token rotation: rotated tokens are automatically persisted to config so the session stays valid across refreshes
New "Logout" menu item (Server menu): revokes the refresh token server-side and clears the saved session
Removed dead SavedServer.Token field (stored 15-min access token that was never read back)
Automatic Update Checking
UpdateChecker rewritten to use the AlwaysUpToDate library for self-updating
Polls the EchoHub version manifest hourly (active only in RELEASE builds)
UpdateConfirmDialog shows current vs. available version with Update/Cancel buttons
UpdateProgressDialog displays real-time download progress bar
Errors are logged via Serilog instead of being silently swallowed
Windows Installer
New Inno Setup script (installer/Installer.iss) to build a Windows installer
Auto-reads product version from the built EXE
User-level install by default (no admin required), with admin override option
Creates desktop and quick-launch shortcuts (optional)
Supports English and German languages
Application Icons
New hue_icon branding assets (ICO, PNG, SVG) in assets/
Application icon set on both Client and Server projects
#general Channel Protection
#general channel is now auto-recreated if somehow missing (both in GetChannels endpoint and JoinChannel flow)
Users cannot /leave the #general channel (client-side guard)
Connecting while already connected now prompts to disconnect first instead of silently leaking the previous connection
Fixes
IRC Gateway
Fixed: IRC JOIN history replay showed encrypted gibberish — IrcCommandHandler.HandleJoinAsync now decrypts channel history before formatting for IRC clients (history was encrypted for SignalR transport but sent raw to IRC)
Fixed: JoinedChannels race condition — IrcClientConnection.JoinedChannels replaced with thread-safe methods (JoinChannel, LeaveChannel, IsInChannel, GetJoinedChannels) using lock synchronization; prevents crashes when broadcaster threads read while the command handler writes
Fixed: RequireRegistered fire-and-forget — converted from sync bool to async Task<bool> (RequireRegisteredAsync) so the error reply is properly awaited before the handler returns
ChannelService Extraction
Extracted channel management logic from ChannelsController and ChatService into a dedicated IChannelService / ChannelService
ChannelsController is now a thin adapter — delegates CRUD operations to IChannelService and maps ChannelError to HTTP status codes
ChatService.JoinChannelAsync delegates channel validation + membership to IChannelService.EnsureChannelMembershipAsync()
New ChannelOperationResult result type with ChannelError enum for typed error handling across service boundaries
IRC gateway uses IChannelService for topic queries and channel listing (instead of IChatService)
EchoHub Branding
Status bar "EchoHub" text now uses golden color (218, 165, 32)
Extracted ChatMessageManager from MainWindow — message storage, formatting, and mutation logic now in a dedicated class, reducing MainWindow complexity
Test helpers: TestDuplexStream, TestIrcConnectionFactory, FakeChatService, FakeChannelService, FakeEncryptionService for IRC unit testing without network I/O