Commit Graph
970 Commits
Author SHA1 Message Date
Jannis Braun 17289445bd feat: add categorySettings modal type to uiStore 2026-03-21 18:25:56 +01:00
Jannis Braun bfe317f465 feat: interleaved category override resolution in permission engine 2026-03-21 18:22:22 +01:00
Jannis Braun 1473f4f88c fix: emoji reaction picker no longer overflows viewport on bottom messages 2026-03-21 18:21:30 +01:00
Jannis Braun eb04c4ad30 feat: add category_overrides table schema and migration 2026-03-21 18:20:21 +01:00
Jannis Braun 90d702338d feat: add slideDown animation for upward-flipping popovers 2026-03-21 18:20:02 +01:00
Jannis Braun 3300ce8d5c feat: add CategoryOverride type and isPrivate to ChannelCategory 2026-03-21 18:19:45 +01:00
Jannis Braun 448ff9a59c fix: exclude desktop, installers, and other non-Docker files from deploy rsync 2026-03-21 17:42:13 +01:00
Jannis Braun fe6de6456a feat: add ffmpeg to Docker runtime for video thumbnail generation 2026-03-21 17:23:19 +01:00
Jannis Braun 80d97d72c9 feat: add backfill migration for media dimensions and video thumbnails 2026-03-21 17:22:44 +01:00
Jannis Braun 7ec61c16fd feat: use aspect-ratio and preload=none for video/image attachments 2026-03-21 17:20:54 +01:00
Jannis Braun 561c9bc4f3 feat: include width, height, duration in all attachment serialization 2026-03-21 17:20:04 +01:00
Jannis Braun 7c767b580a feat: extract media dimensions and video thumbnails on upload 2026-03-21 17:18:59 +01:00
Jannis Braun d0f33446de feat: add video thumbnail generation and media metadata extraction 2026-03-21 17:16:40 +01:00
Jannis Braun b74e33b349 feat: add width, height, duration columns to attachments schema 2026-03-21 17:15:09 +01:00
Jannis Braun 948fa6de5c feat(desktop): add remote dictionary sync engine to activity detector
Refactor loadDictionary to accept a file path and support both legacy
bare-array (version 0) and versioned object formats. Add background
sync that fetches the latest games.json from GitHub, uses ETag-based
conditional requests (304 support), atomic cache writes, and hot-swaps
processMap/gameEntries without resetting current detection state.
On startup, the best local source (cache vs bundled seed) is loaded
immediately for instant detection, then sync runs fire-and-forget.
2026-03-21 04:12:21 +01:00
Jannis Braun 228ffe4894 feat(desktop): expand game dictionary to 249 entries with versioned schema
Rewrite games.json from bare array (28 entries) to versioned format
{ version: 1, games: [...] } with 249 entries covering top Steam games,
competitive titles, AAA, indie, survival/craft, simulation, horror,
fighting, racing, MMOs, and media apps (Spotify, VLC, OBS, mpv).
Every process name is specific enough to avoid false-positive detection.
2026-03-21 04:12:15 +01:00
Jannis Braun 156189dfa2 fix: redesign activity cards with glass-pill material and accent borders
Replace bg-surface-elevated cards and inline text badges with glass-pill
rows featuring colored left borders (mint=playing, sky=listening,
lavender=watching, rose=streaming). Identical treatment in both
ActivityPanel and MemberSidebar — no more compact/full distinction.
Members with rich activities get the frosted glass row; others stay plain.
2026-03-21 03:50:09 +01:00
Jannis Braun 2c122d066e fix: add console warnings for invalid games.json entries 2026-03-21 03:00:14 +01:00
Jannis Braun 0f4f129337 feat(desktop): add automatic game/app activity detection
Add cross-platform process scanning that detects running games and apps,
then broadcasts them as Rich Presence activities via the existing Phase 1
pipeline (activityStore -> WS -> other users).

- games.json dictionary with 26 entries (games, Spotify, VLC, OBS)
- activityDetector module: polls OS process list every 15s via execFile,
  matches against dictionary, emits IPC on state change only
- IPC bridge in main.ts/preload.ts with cleanup on quit
- Frontend activityBridge subscribes to IPC and feeds activityStore
- Supports Windows (tasklist CSV), macOS (ps -c), Linux (ps)
2026-03-21 02:57:30 +01:00
Jannis Braun 568b049b22 ci: add GitHub Actions workflow for desktop release builds
Triggers on v* tag push, builds for Windows, macOS (arm64), and Linux.
Uses electron-builder --publish to upload artifacts to GitHub Releases.
2026-03-21 02:32:43 +01:00
Jannis Braun 2593f7075c feat(desktop): add version display and check-for-updates to account settings 2026-03-21 02:32:19 +01:00
Jannis Braun a9fcdb72a8 feat(desktop): add manual download fallback to UpdateToast
Extends UpdateToast to handle update-error events from the preload bridge,
showing a "Download" link to the GitHub release URL when auto-update fails.
2026-03-21 02:31:20 +01:00
Jannis Braun 6ebb124d25 feat(desktop): update preload bridge types for enhanced update-error and getVersion 2026-03-21 02:30:06 +01:00
Jannis Braun a7d5abfca9 feat(desktop): enhance update-error payload with release URL, add get-app-version IPC 2026-03-21 02:29:42 +01:00
Jannis Braun a234041210 feat(desktop): switch auto-update provider from generic to github 2026-03-21 02:29:28 +01:00
Jannis Braun 9e4878c48f fix: move showActivity toggle from Account to Privacy settings panel 2026-03-21 02:13:32 +01:00
Jannis Braun 1f4e149ee1 feat: add frontend Rich Presence — activityStore, ActivityCard, sidebar upgrades, settings toggle
- Task 7: Create activityStore (Zustand) with Map<userId, Activity[]>, showActivity toggle,
  debounced pushActivities, and reset on logout
- Task 8: Wire WS integration — presence_update propagates activities to store,
  ready payload initializes userActivities and showActivity (via setState to avoid side effects)
- Task 9: Create ActivityCard component with compact/full modes, type-colored labels,
  elapsed time display, asset images, and fallback to customStatus
- Task 10: Upgrade ActivityPanel to three groups — active friends (full cards, no header),
  online friends (compact), offline friends — using getPrimaryActivity for grouping
- Task 11: Upgrade MemberSidebar to show compact ActivityCards instead of raw customStatus
- Task 12: Add showActivity toggle in AccountPanel settings (Activity Status section)
  with API persistence and store sync
2026-03-21 01:55:17 +01:00
Jannis Braun 9403ded8da feat: add showActivity toggle to PATCH @me with activity broadcast clear
- Accept showActivity boolean in PATCH /api/users/@me body
- Validate and persist as integer in DB
- Update ConnectionManager cache on toggle
- Broadcast empty activities via presence_update when toggled off
2026-03-21 01:49:41 +01:00
Jannis Braun ceb8894d58 feat: add WS activity_update handler and enhanced presence_update with activities
- Add validateActivities() with full field validation against ACTIVITY_LIMITS
- Add handleActivityUpdate() with showActivity gate and rate limiting
- Enhance handlePresenceUpdate() to include activities in broadcast payload
- Update status cache via connectionManager.setUserStatus() on presence change
- Wire activity_update case into event router switch statement
2026-03-21 01:48:57 +01:00
Jannis Braun d4366a2207 feat: add ConnectionManager in-memory activity state and ready payload
Add Rich Presence infrastructure to ConnectionManager:
- Four new Maps: userActivities, userShowActivity, userStatuses, lastActivityUpdate
- Public accessors: set/get/clear activities, showActivity, status, rate limit check
- Cleanup in finalizeDisconnect() and forceDisconnectUser()
- Cache showActivity and status from DB at auth time in buildReadyPayload()
- Assemble userActivities snapshot in ready payload with customStatus fallback
- Include activities: [] in offline presence_update broadcast
2026-03-21 01:44:36 +01:00
Jannis Braun bc408235c9 feat: add Activity type system, DB migration, and self-only showActivity in sanitizeUser
- Add Activity, ActivityType, ActivityTimestamps, ActivityAssets types to shared types
- Add activity_update client event and activities field on presence_update server event
- Add userActivities to ready payload and showActivity to User/UpdateUserRequest
- Create shared activities.ts with ACTIVITY_LIMITS, ACTIVITY_PRIORITY, getPrimaryActivity
- Add show_activity column to users table (schema + migration)
- Update sanitizeUser with isSelf parameter; only include showActivity for self
- Fix .map(sanitizeUser) calls to use arrow wrapper to prevent index-as-boolean bug
- Mark auth routes (register/login) as isSelf=true since they return own user data
2026-03-21 01:38:36 +01:00
Jannis Braun ce981ee5fc fix: prevent metadata fetch from overwriting fallback thumbnail with null
Use logical OR when merging fetched metadata so null values from
failed og: extraction don't destroy valid defaults (e.g. YouTube
thumbnail set before the fetch).
2026-03-21 00:35:44 +01:00
Jannis Braun 1c7d8557c6 fix: use predictable YouTube thumbnail URL as fallback for embed poster
YouTube may block og:image extraction via BackspaceBot user-agent.
Use img.youtube.com/vi/{ID}/hqdefault.jpg as a guaranteed thumbnail
that doesn't require metadata fetching. If og:image is successfully
fetched, it overwrites the fallback.
2026-03-21 00:31:59 +01:00
Jannis Braun a3db74c7f7 fix: resolve YouTube Error 153 by adding origin param and removing no-referrer
YouTube's embed API requires knowing the embedding origin to authorize
playback. The referrerPolicy="no-referrer" was stripping the Referer
header, and the missing origin param meant youtube-nocookie.com couldn't
verify the embed source, causing Error 153 (video player configuration
error). Fix: pass origin param explicitly and let the browser send the
default referrer.
2026-03-21 00:26:32 +01:00
Jannis Braun c0133397e3 fix: resolve 4 media embed bugs from testing
1. Video aspect ratio: remove container border/overflow-hidden, use
   preload="metadata" so browser knows dimensions before play
2. YouTube Error 153: remove sandbox attr (too restrictive), add full
   allow permissions (encrypted-media, accelerometer, gyroscope, etc.)
3. Google Images not displaying: detect image Content-Type from HTTP
   response in metadataFetcher, override classifier to create image
   embed for URLs that serve image/* content
4. Audio seeking broken: add HTTP Range request support in uploads
   route (Accept-Ranges, Content-Range, 206 Partial Content)
2026-03-21 00:19:04 +01:00
Jannis Braun ff2decded5 fix: address code review issues for embeds implementation
- Fix ?? to || in metadataFetcher.ts to handle empty strings from Cheerio
- Fix stale embeds on message edit: delete old embeds synchronously before
  broadcast, then resolve new ones async (all 4 edit paths: REST+WS, msg+DM)
- Revert unrelated MessageList.tsx scroll threshold change (5000 not 150)
- Remove duplicate embed indexes from migrateAddIndexes (kept standalone ones)
2026-03-20 23:58:06 +01:00
Jannis Braun dcdf10c5de docs: update CLAUDE.md with embeds schema, WS events, and feature status 2026-03-20 23:50:48 +01:00
Jannis Braun 4486341007 feat: add embeds_resolved WS handlers and optimistic embeds:[] default
- chatStore: normalize embeds to [] in addMessage, addRealtimeMessage, and updateMessage to guard against missing field from older servers/federation
- useWebSocket: add embeds_resolved and dm_embeds_resolved cases that patch the in-memory message cache when the server broadcasts resolved embed data
- useWebSocket: normalize embed image URLs for remote origins in message_created, message_updated, dm_message_created, dm_message_updated, and the new embeds_resolved handlers
2026-03-20 23:49:15 +01:00
Jannis Braun 95762a1974 feat: replace Embed.tsx with AttachmentRenderer + EmbedRenderer in Message
Switches Message.tsx from client-side URL metadata fetching (old Embed.tsx)
to server-driven embed objects via message.embeds[]. Delegates attachment
rendering to AttachmentRenderer. Removes firstUrl extraction and urlRegex.
2026-03-20 23:47:16 +01:00
Jannis Braun 5a670bc6ad feat: add embed sub-components (Generic, Video, Image, Rich) and dispatcher 2026-03-20 23:45:32 +01:00
Jannis Braun a800d9ff25 feat: add AttachmentRenderer with video/audio inline playback 2026-03-20 23:43:31 +01:00
Jannis Braun 01ee7ab67a feat: wire embeds into all message query and creation paths
Integrate embed infrastructure into the complete message flow:
- messages.ts: batch-fetch embeds in GET, resolve on POST, re-resolve on PATCH
- dm.ts: same pattern for DM messages with isDm=true
- search.ts: include embeds in all 4 search/around endpoints
- events.ts: embed resolution in WS message create/edit for both space and DM
- Fix embedClassifier.ts type errors (regex match undefined → null)
- Add embeds: [] to all inline MessageWithUser/DmMessageWithUser constructions
- Add embeds: [] to chatStore optimistic message
2026-03-20 23:41:53 +01:00
Jannis Braun 5fe25fb077 feat: add embed resolver with async resolution and batch fetching 2026-03-20 23:33:21 +01:00
Jannis Braun 29cfd88a15 feat: add URL classifier for embed type detection 2026-03-20 23:30:13 +01:00
Jannis Braun de1c0b4ed8 refactor: extract metadata fetcher into reusable utility 2026-03-20 23:30:01 +01:00
Jannis Braun ebc1868dd1 feat: add embeds database table with schema and migration 2026-03-20 23:28:57 +01:00
Jannis Braun 009923a12f feat: add Embed types and extend MessageWithUser with embeds[] 2026-03-20 23:25:58 +01:00
Jannis Braun f7d388c9a8 fix: clean up redundant regex guard and differentiate copy icons 2026-03-20 22:23:15 +01:00
Jannis Braun 720a3c4553 feat: wire up enhanced message context menu with all actions 2026-03-20 22:19:12 +01:00
Jannis Braun 3aa7e93a4d feat: pass previousMessageId prop from MessageList to Message 2026-03-20 22:16:55 +01:00