# v0.2.3 - Moderation, Embeds & UI Overhaul ## Features ### Moderation System - Added server roles: Owner, Admin, Mod, Member — first registered user is automatically Owner - New `/kick`, `/ban`, `/unban`, `/mute`, `/unmute`, `/role`, `/nuke` commands for moderators and admins - `ModerationController` with full REST API for role assignment, kicks, bans, mutes, message deletion, and channel nuking - Mutes support optional duration (auto-expire) and blocked users cannot log in - Role claim included in JWT tokens; role badges shown in the online users panel ### Private Channels - Channels can be created as public or private via a checkbox in the Create Channel dialog - Public channels are visible to all users; private channels only appear for members who joined them - Persistent channel membership tracked in the database (`ChannelMembership` table) - `GET /api/channels` returns the combined list: public channels + user's joined private channels - Channel creators are automatically added as members ### OpenGraph Link Embeds - Messages containing URLs now show a rich preview below the message text - Server-side fetching: detects the first URL in a message, fetches the page, and parses OpenGraph meta tags (`og:title`, `og:description`, `og:image`, `og:site_name`) - OG images are converted to a small 24x12 colored ASCII thumbnail using the existing half-block renderer - Embeds are persisted in the database and included in channel history - TUI client renders embeds with a `▏` left border bar — site name and border in blue, title in white, description in gray, followed by the ASCII thumbnail - IRC gateway receives a text-only embed preview (site name, title, description) — no ASCII thumbnail to keep IRC output clean - Falls back to `` tag when no OG tags are present; gracefully skips if no useful metadata is found - 3-second fetch timeout ensures message delivery is never significantly delayed - SSRF protection rejects private/loopback IP addresses before fetching ### Notification Sounds - Incoming messages play a notification sound when the terminal is not focused - Embedded MP3 asset with cross-platform playback support ### Online Users Panel - Collapsible right-side panel showing online users in the current channel (toggle with F2) - Users displayed with status indicators, role badges, and their custom nickname colors - Panel updates on join, leave, and status change events ### @mention Highlighting - `@username` text rendered in orange accent color in all messages - Messages mentioning the current user get a full-line amber background highlight - Works across multi-line messages and continuation lines ### ASCII Art Improvements - Half-block character rendering (`▀`/`█`) with separate foreground + background colors for 2x vertical resolution - Switched from ANSI escape codes to printable color tags (`{F:RRGGBB}`, `{B:RRGGBB}`, `{X}`) — no control bytes in stored content - Optional size parameter for `/send` command: `-s` (40x40), `-m` (80x80, default), `-l` (120x120) - IRC gateway converts color tags back to ANSI for IRC client compatibility ### Client UI - Version number shown in the status bar - Custom colored rendering for channel list (active indicator, unread count badges) - Avatar upload field added to the profile edit dialog (file path or URL) - Profile avatar now renders with full color tag support in the profile view dialog - Update check notification on connect — shows a system message if a newer GitHub release exists - Chat messages no longer show selection/focus highlight - Exit shortcut changed from Ctrl+C to Alt+Q — frees Ctrl+C for copy - Default history increased from 50 to 100 messages on channel join ## Fixes - Fixed `#general` channel not visible after adding the `IsPublic` column — migration default changed to `true` and startup service ensures it - Fixed channels disappearing when creating a new channel — replaced full re-fetch with incremental updates - Wired `OnChannelUpdated` SignalR event so new public channels appear for all connected users in real time - Fixed color tag parser using wrong regex group numbers (6,7,8 instead of 1,2,3) — new ASCII art was rendering without colors - Full Unicode/emoji support — renderers use Terminal.Gui v2 grapheme cluster API (`GraphemeHelper`, `AddStr`) for proper wide character handling - Emoji-to-text shortcode conversion for consistent cross-platform rendering - Fixed `/send` and `/avatar` commands not handling file paths with spaces correctly, even when quoted - Server-side newline spam protection — consecutive blank/whitespace-only lines collapsed to 1 and total lines capped at 30 ## Infrastructure - New `LinkEmbedService` on the server — URL detection, HTML fetching (first 64KB), OG tag parsing via regex, image thumbnail generation - `EmbedDto` record added to shared Core DTOs; `MessageDto` extended with optional `Embed` field (backward-compatible) - `EmbedJson` nullable column on the `Message` table stores serialized embed data (max 8KB) - Dedicated `"OgFetch"` named HttpClient with bot User-Agent header and 5-second timeout - `NotificationSoundService` for cross-platform audio playback of embedded notification sounds - Startup `DataMigrationService` automatically converts old ANSI-format messages to the new color tag format on server boot, logging the count of migrated records - `EmojiHelper` utility for emoji-to-shortcode conversion - Heartbeat handling in `ServerDirectoryService` for connection health checks - Four new EF Core migrations: `AddModerationRoles`, `AddChannelIsPublic`, `AddChannelMembership`, `AddMessageEmbed` - `ChannelMembership` table with cascade delete on both channel and user removal