Commit Graph
378 Commits
Author SHA1 Message Date
Jannis Braun a9a676bc70 feat: expand admin streaming pills, add high-end resource warning
Replaces hardcoded 3-resolution/3-framerate arrays with ALL_RESOLUTIONS
and STANDARD_FRAMERATES from shared constants (540p–Native, 30–120 fps).
Adds amber warning banner when high-end options (≥1440p or ≥75 fps) are
enabled, and fixes toggleResolution to handle 'native' with correct sort.
2026-03-21 23:30:46 +01:00
Jannis Braun 5ac0917d81 feat: dynamic resolution/framerate pills from instance limits 2026-03-21 23:30:14 +01:00
Jannis Braun 57b192533d feat: add Copy Role button to duplicate roles with permissions 2026-03-21 23:30:12 +01:00
Jannis Braun cb34bfc8ea feat: expand bitrate matrix, add native mode with pixel-proportional fallback 2026-03-21 23:26:54 +01:00
Jannis Braun 3fe9f774a1 feat: add client-side role name uniqueness validation with 409 handling 2026-03-21 23:26:06 +01:00
Jannis Braun b9f11489fe feat: update server validation for expanded resolutions and framerates
Replace hardcoded VALID_RESOLUTIONS/VALID_FRAMERATES with shared STANDARD_RESOLUTIONS/STANDARD_FRAMERATES constants. Update rowToLimits to handle the 'native' resolution value in DB parsing, and update all PATCH validation blocks to accept the expanded resolution/framerate sets and the 'native' option.
2026-03-21 23:23:25 +01:00
Jannis Braun a02b098fa7 feat: widen ScreenShareConfig types, bump persist to v12 2026-03-21 23:22:49 +01:00
Jannis Braun ec71dd2c50 feat: widen InstanceStreamingLimits.allowedResolutions to support 'native' 2026-03-21 23:22:46 +01:00
Jannis Braun bc1d92f853 feat: add shared streaming constants module 2026-03-21 23:20:58 +01:00
Jannis Braun 05fe1df5f0 feat: enforce case-insensitive unique role names per space 2026-03-21 23:20:40 +01:00
Jannis Braun 7fb87de09a feat: default new roles to @everyone permissions instead of null 2026-03-21 23:17:16 +01:00
Jannis Braun f7657e3adb fix: prevent duplicate messages when sending image without text
Optimistic message used content: '' while the server normalized it to
null, causing the content-based dedup to fail and leaving both the
empty temp message and the real attachment message in the list.
2026-03-21 22:46:01 +01:00
Jannis Braun 0d8913f589 feat: register CategorySettingsModal in AppLayout 2026-03-21 22:18:01 +01:00
Jannis Braun cc7d1c191c feat: add CategorySettingsModal with overview and permissions tabs 2026-03-21 22:08:47 +01:00
Jannis Braun edb050fd39 feat: add category settings context menu, lock icon, empty category hiding 2026-03-21 18:38:47 +01:00
Jannis Braun 892164f3a5 refactor: use extracted PermissionsEditor in ChannelSettingsModal 2026-03-21 18:35:38 +01:00
Jannis Braun c43afc23a8 feat: extract TriStateToggle, OverrideEntry, PermissionsEditor shared components 2026-03-21 18:35:35 +01:00
Jannis Braun 637e083e9a feat: add category override API endpoints, fix channel categoryId reassignment, include isPrivate on categories
- Add GET/PUT/DELETE /api/categories/:id/overrides endpoints with
  privilege escalation guard matching existing channel override pattern
- Add isCategoryPrivate() and broadcastCategoryOverrideChange() helpers
  that cascade visibility changes to all channels in a category
- Fix PATCH /api/channels/:id to recompute permissions via
  broadcastOverrideChange when categoryId changes (different category
  overrides may apply)
- Include isPrivate flag on categories in GET /api/spaces/:id payload
  using batch-fetched @everyone overrides
- Include isPrivate on categories in broadcastChannelLayout and
  PATCH /api/categories/:id broadcasts
2026-03-21 18:29:25 +01:00
Jannis Braun b5ac7d3ee4 feat: add category override API client methods 2026-03-21 18:29:16 +01:00
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 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 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