- Fix: PFP upload button - wrapped _initSliderFills Object.defineProperty in try-catch
so it can't crash the HavenApp constructor and prevent _setupAvatarUpload from running
- Add: Hide/show individual stream tiles - eye button on each tile, hidden-streams bar
with restore buttons, stream count label shows hidden count
- Add: Pop-out music player - opens YouTube/Spotify/SoundCloud embed in separate window,
minimizes in-app panel, shows indicator when pop-out window is active
- Fix: YouTube 'Video unavailable' for clients - added origin parameter to embed URL,
added ws: to CSP connectSrc (required for HTTP-mode Socket.IO connections)
- Fix: Slider fill tracks now use injected <style> rules targeting ::-webkit-slider-runnable-track per-slider, bypassing Chrome shadow DOM limitation
- Fix: YouTube embeds use youtube.com/embed/ (not youtube-nocookie.com) to resolve 'Video unavailable' for other users
- Fix: Removed duplicate screen share tile creation from shareScreen() in voice.js
- Fix: PiP leavepictureinpicture event now on video element (not pipWindow)
- Fix: Transparent overlay on music iframes to force synced controls
- Fix: Music panel X minimizes with reopenable indicator in channel header
- Fix: Server tracks active music per voice room and sends to late joiners
Fixed: static file caching changed from 1h maxAge to always-revalidate with ETags, preventing stale JS after server restarts
Improved: mobile message actions (react/reply/pin/edit/delete) hidden by default, revealed with a tap on the message, cleaned up phone UI significantly
Features:
- Direct messages: private 1-on-1 via DM button in member list
- User status: online/away/dnd/invisible with custom text + auto-away
- Channel topics: admin-editable topic bar below channel header
- File sharing: upload PDFs, docs, audio, video, archives (25 MB limit)
- Persistent read state: server-tracked unread counts survive refresh
Database:
- New read_positions table for unread tracking
- New columns: users.status, users.status_text
- New columns: channels.topic, channels.is_dm
- New column: messages.original_name
- All migrations are safe for existing DBs
UI:
- Status picker dropdown in sidebar
- DM section in channel list
- File attachment cards with type icons
- Inline audio/video players in chat
- Status dots colored by user status
- Topic bar with click-to-edit for admins
Server:
- /api/upload-file endpoint with expanded MIME whitelist
- set-status, set-channel-topic, start-dm, mark-read socket events
- get-channels returns topic, is_dm, unread counts
- emitOnlineUsers includes status data
- Idle detection with 5-min auto-away
Voice audio (Bug 2):
- Guard _playAudio against duplicate Web Audio graph creation
- Prevents multiple GainNodes competing for the same stream
Talking indicator (Bug 3):
- Already fixed: 300ms hysteresis hold timer in both local and remote
talk detection (prevents flicker from micro-pauses between syllables)
Screen share (Bug 4):
- Add SDP rollback in voice-offer handler for renegotiation glare
- Guard voice-answer handler against stale answers after rollback
- Use event.streams[0] in ontrack for proper stream association
- Add track.onunmute to re-trigger screen display when data arrives
- Mute all screen share video tiles (prevents browser autoplay block)
- Explicit vid.play() call as autoplay backup
GIF search (Bug 1):
- Tenor API key can now be set from the admin GIF picker UI
- Stored in server_settings DB table (no .env editing needed)
- Server checks DB first, falls back to TENOR_API_KEY env var
- Shows step-by-step setup guide when key is missing
- Non-admins see a clear 'ask your admin' message
- GIF button next to emoji picker opens search/browse panel
- Server-side proxy keeps Tenor API key hidden from clients
- Trending GIFs shown by default, live search with debounce
- Click a GIF to send it as an inline image in chat
- Tenor URLs auto-detected and rendered as inline images
- CSP updated to allow media.tenor.com images
- TENOR_API_KEY added to .env.example (optional, free)
- Full CSS theming for GIF picker panel
- Database, .env, certs, and uploads now stored outside the code directory
- Auto-migration moves existing data from old locations on first launch
- SSL certs auto-detected in data dir (no .env config needed)
- New src/paths.js module as single source of truth for all data paths
- HAVEN_DATA_DIR env var for custom data location override
- Updated Start Haven.bat, start.sh, README, GUIDE, .env.example
- Bumped version to 1.1.0