- usePermissions ORs current user roles + @everyone only (not all server roles)
- cache myRolesByServer; load on active server; refresh after self role edit
- gate/notify @everyone and @channel; plain @username push; special mention UI
- refresh FEATURE_PARITY (DMs exist; drop stale critical gaps)
- README production deploy notes dumpster.service
- unit tests for permission bits and broadcast mention tokens
Members API appends server bots (is_bot). Sidebar groups ONLINE / OFFLINE / BOTS.
Bots get green BOT badge, no kick menu or profile. Mentions and DMs skip bots.
Root cause of "not anonymous":
1. Confess deleted via raw SQL with no MESSAGE_DELETE broadcast
2. Frontend extractIds only accepted message_id, but deletes send id
so live clients never removed deleted messages without refresh
Fix:
- Intercept /confess at message create: never store or broadcast the
original; post only the anonymous bot message
- Accept both id and message_id on MESSAGE_DELETE in the WS store
- Include both fields on delete broadcasts
- MobileBottomNav: [SERVERS] [CHAT] [MEMBERS] tab bar, always visible
- Servers tab opens sidebar overlay, chat/members switch views
- Removed hamburger + members toggle from mobile top bar
- Top bar compact on mobile (no redundant buttons)
- safe-area-inset-bottom on nav, clean inset on frame
- Desktop status bar hidden on mobile, preserved on desktop
- Dead MobileNav/MobileDrawer left in place (unused, can prune later)
Moved thread and forum-tag routes from nested /servers/{sid}/channels/ to
top-level /channels/{id}/... to match frontend API calls. Forum posts were
getting SPA HTML fallback instead of JSON.
Added orange notification dots to DM and server buttons in ServerBar.
Triggers on v* tags. Builds AppImage/deb/rpm on Linux runner,
MSI/NSIS on Windows runner, then creates a release with all assets.
Requires self-hosted runners registered in Gitea Actions.
- src-tauri/ with Rust backend, Cargo.toml, main.rs, lib.rs
- tauri.conf.json: Linux deb bundle with webkit2gtk deps
- package.json: added tauri script
- Build on a machine with Rust: cd web && npm run tauri build
- Read states store: smarter hasUnread compares against latest message
- ConversationList: orange dot + bold name for unread DMs
- DMChat: auto-mark-read when viewing conversation
- WS handler: mark DM read on new message while active+focused
- VideoGrid: add screen share track display with proper sizing
- participantToVoice: detect ScreenShare + ScreenShareAudio tracks
- VoicePanel: flex layout, no scroll, tiles dynamically fill space
- VoiceChannel: show screen/camera icons in participant list
- vite.config: inject git SHA into SW CACHE_VERSION on build
FormatToolbar component: B I S ` || buttons that wrap selected text
with markdown syntax. Added to both channel and DM input areas.
Keyboard shortcuts: Ctrl+B bold, Ctrl+I italic already work via
browser defaults on the rendered markdown.