Commit Graph
150 Commits
Author SHA1 Message Date
Jannis Braun f84b1726bf feat: add context menus to MobileSpacesScreen
Add onContextMenu handlers for space icons (invite, folder management,
transfer, leave), channel items (settings, delete), and category headers
(settings, delete). Includes full folder management handlers.
2026-03-23 19:21:14 +01:00
Jannis Braun 2c372a5d34 fix: three mobile bugs — scroll, GeneralPanel loading, activity tab
1. Chat scroll: add flex flex-col to MobileChatScreen messages wrapper
   so MessageList's flex-1 actually works (parent must be flex container)

2. Instance General panel: add fetchInstanceSettings/fetchStreamingLimits
   to MobileInstancePanel mount (mirrors desktop InstancePanel useEffect)

3. Friends activity: add Activity tab to mobile FriendsPage showing
   friends grouped by activity status (active, online, offline)
2026-03-23 14:56:07 +01:00
Jannis Braun 77a1a7920c feat: add standalone MobileMembersScreen replacing blank member panel
Create MobileMembersScreen that renders space members grouped by role
without depending on desktop memberListOpen flag or hidden md:block.
Add members button to voice full screen header for space channels.
2026-03-23 14:20:06 +01:00
Jannis Braun 54b367924d feat: add drill-down navigation for Instance settings on mobile
Replace inline InstancePanel render with MobileInstancePanel that shows
a navigation list for General, Streaming, Storage, and Users sub-panels.
Each sub-panel pushes onto the mobile screen stack with MobileScreenHeader.
2026-03-23 14:16:56 +01:00
Jannis Braun 7c40a230bc feat: add reusable MobileScreenHeader component
Extracts the back-button header pattern used across all mobile screens
into a single component. Props: title (string), rightActions (ReactNode).
2026-03-23 14:15:04 +01:00
Jannis Braun d8c5e7ff16 fix: restore mobile chat scrolling by fixing height constraint chain
Add overflow-hidden to MobileScreenStack stacked screen wrapper to
establish block formatting context. Add min-h-0 to MobileChatScreen
messages wrapper to override flex min-height: auto default.
2026-03-23 14:14:18 +01:00
Jannis Braun 313ff4ef87 feat: add Nori mascot to mobile empty states 2026-03-22 23:39:16 +01:00
Jannis Braun 4e23cb5bf9 feat: add sleeping Nori mascot to empty DM sidebar 2026-03-22 23:39:13 +01:00
Jannis Braun 895f665da9 feat(keybinds): wire useKeybinds hook into AppLayout 2026-03-22 20:37:45 +01:00
Jannis Braun 537f489432 feat: apply delayed loading to member sidebar skeleton 2026-03-22 03:17:01 +01:00
Jannis Braun 44e8b32c2f feat: apply delayed loading to app boot skeleton 2026-03-22 03:17:00 +01:00
Jannis Braun b6f4659849 feat: apply delayed loading to channel sidebar skeleton 2026-03-22 03:16:47 +01:00
Jannis Braun fcbdac7a2f fix: improve skeleton loading accessibility and consistency
- Add role="status" and aria-label to all skeleton containers
- Refactor ChannelSidebar from conditional siblings to ternary
  for consistent mutual exclusivity with MemberSidebar pattern
2026-03-22 02:51:02 +01:00
Jannis Braun 7d21f25f39 feat: replace app boot spinner with layout shell skeleton 2026-03-22 02:47:09 +01:00
Jannis Braun 9044fe5539 feat: add skeleton loading state to channel sidebar 2026-03-22 02:45:11 +01:00
Jannis Braun a2ff5cb75d feat: add skeleton loading state to member sidebar 2026-03-22 02:44:46 +01:00
Jannis Braun 0d8913f589 feat: register CategorySettingsModal in AppLayout 2026-03-21 22:18:01 +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 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 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 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 99e6f2f249 fix: normalize drop indicator to single line between channels
Port the SpaceSidebar normalization pattern: convert 'before B'
to 'after A' so only one drop indicator renders at any gap.
Fixes double-line visual glitch and unreliable drops when cursor
is between two channels. Also adjust indicator offsets from
top-0/bottom-0 to -top-[1px]/-bottom-[1px] to center in the gap.
2026-03-20 21:07:20 +01:00
Jannis Braun 439a71dc13 refactor: wire useDragManager handlers into ChannelSidebar JSX and ChannelItem 2026-03-20 20:45:30 +01:00
Jannis Braun 999c13cdab refactor: replace old drag state with useDragManager hook in ChannelSidebar 2026-03-20 20:43:41 +01:00
Jannis Braun cba19e8b20 refactor: migrate SpaceSidebar context menus to centralized store 2026-03-20 18:41:17 +01:00
Jannis Braun 15af93b979 refactor: migrate ChannelSidebar context menus to centralized store 2026-03-20 18:35:55 +01:00
Jannis Braun ba0243d88c feat: mount ContextMenuRenderer in AppLayout 2026-03-20 18:30:58 +01:00
Jannis Braun e3e3eb82ff fix: restore missing logo and fix mobile space icon URLs
Restore logo.png lost during fast-forward merge and replace broken
resolveAssetUrl pattern in MobileSpacesScreen with proven desktop logic.
2026-03-17 16:16:09 +01:00
Jannis Braun ed70099963 fix(mobile): resolve all TypeScript errors from integration
- Fix voiceStore method names (toggleMic, leaveVoice, setCurrentVoiceChannel)
- Fix MemberWithUser nested user property access
- Pass required channelId props to MessageList, TypingIndicator, MessageInput
- Fix ConfirmDialog props (isOpen, description, variant, onClose)
- Add mobileStyle prop to Modal component (fullscreen + sheet modes)
- Fix fromId/isAdmin camelCase property names
- Guard possibly undefined touch events and array accesses
- Fix notification channelId resolution
2026-03-17 15:54:39 +01:00
Jannis Braun 7619b091da feat(mobile): route user profile to pushed screen instead of popout 2026-03-17 15:49:36 +01:00
Jannis Braun 206a0491ea feat(mobile): add full-screen voice view with controls 2026-03-17 15:47:41 +01:00
Jannis Braun 183290ef07 fix(mobile): stacked Add Friend input, responsive tab bar, mobile header 2026-03-17 15:43:43 +01:00
Jannis Braun 2790e9e088 feat(mobile): add voice mini-bar with quick controls 2026-03-17 15:42:16 +01:00
Jannis Braun af84674963 feat(mobile): add MobileSettingsScreen with drill-down navigation 2026-03-17 15:41:19 +01:00
Jannis Braun 934a1b85a7 feat(mobile): add MobileYouScreen with profile card and action links 2026-03-17 15:40:23 +01:00
Jannis Braun 49e4402802 feat(mobile): add MobileDmsScreen with activity row and DM list 2026-03-17 15:39:19 +01:00
Jannis Braun 0222946f04 feat(mobile): add swipe-from-left-edge back gesture 2026-03-17 15:37:27 +01:00
Jannis Braun e45bf1927e feat(mobile): add MobileChatScreen with back nav and member list access 2026-03-17 15:36:50 +01:00
Jannis Braun eac4e5f5eb feat(mobile): add MobileSpacesScreen with space strip and channel list 2026-03-17 15:35:53 +01:00
Jannis Braun 8463ca9ba8 feat(mobile): add MobileShell and split AppLayout for mobile/desktop 2026-03-17 15:32:52 +01:00
Jannis Braun 2386f497aa feat(mobile): add 3-tab bottom nav with unread badges 2026-03-17 15:31:06 +01:00
Jannis Braun cbfff701ce feat(mobile): add MobileScreenStack transition manager 2026-03-17 15:30:10 +01:00
Jannis Braun bfecb41c66 fix: derive voice sidebar from LiveKit participants to eliminate desync
The channel sidebar voice user list was maintained by a separate
voiceUsers Map (fed by WS events + fragile hydration code) that diverged
from reality after server restarts — users shown in wrong channels,
duplicated across channels. The VoiceGrid was always correct because it
reads LiveKit participants directly.

Now VoiceChannel.tsx derives its user list from LiveKit participants for
the connected channel (single source of truth) and only falls back to
server-provided voiceUsers for channels the user is not connected to.

Removed all hydration band-aids that tried to sync the two systems:
- useLiveKit ParticipantDisconnected → removeVoiceUser
- useLiveKit ConnectionStateChanged → addVoiceUser hydration loop
- useWebSocket ready handler → dynamic import LiveKit hydration

Also includes: voice channel settings gear icon on hover, persist
per-user volume/mute prefs across sessions, default screen share
audio off on Electron (no system audio capture support).
2026-03-16 22:10:53 +01:00
Jannis Braun 7a86cde67e feat: frameless title bar for Windows/Linux with native overlay controls
Use titleBarStyle: 'hidden' + titleBarOverlay on Win/Linux to remove the
ugly native title bar and menu bar while keeping OS-rendered min/max/close
buttons. Hidden Edit menu preserves keyboard shortcuts (Ctrl+C/V/X/Z/A).
Title bar drag region and separator line rendered via web frontend, with
colors matching the Aether Drift design system.

Also adds electron-builder metadata (description, author, homepage,
artifactName) and multi-size icons for cross-platform builds.
2026-03-16 06:16:43 +01:00
Jannis Braun 95ec3ff952 feat: Electron screen share picker, instance selector, and system audio loopback
- Custom screen share picker for Electron (ScreenSharePicker.tsx) with
  Aether Drift design: glass-bubble footer, adaptive grid, pill tabs,
  border-based selection (avoids overflow clipping), hover brightness
- Instance URL picker so Electron connects to any Backspace server
- System audio loopback on Windows/Linux via desktopCapturer callback
- macOS: video-only callback (OS blocks system audio capture)
- IPC bridge for screen source enumeration and selection
- Purge stale service worker caches on Electron launch
2026-03-16 03:50:07 +01:00
Jannis Braun 8ae3ffc912 feat: Electron desktop app — hardening, IPC bridge, and dev launch fixes
- Dev/prod URL auto-detection (Vite 5173 in dev, server 3000 in prod)
- Typed IPC bridge via preload (notifications, badge, window controls, updates, deep links)
- Native OS notifications via NotificationController with window focus suppression
- Auto-update via electron-updater with UpdateToast UI
- Deep linking (backspace:// protocol) for macOS and Windows/Linux
- Window state persistence (position, size, maximize across restarts)
- Tray icon with graceful fallback when icon asset missing
- Suppress PWA service worker polling/reloads inside Electron
- Platform detection layer (isElectron, getElectronAPI)
- Root workspace scripts (dev:desktop, build:desktop)
- Document BACKSPACE_URL and BACKSPACE_UPDATE_URL env vars
2026-03-16 00:10:47 +01:00
Jannis Braun 7c544c1ff4 feat: security hardening, DB indexes, token revocation, and input validation
- SSRF protection: DNS resolution + private IP blocking on metadata fetcher
- Upload security: CSP/X-Frame-Options headers, SVG forced download, nosniff
- Auth hardening: JWT secret min length, password min 8 chars, token revocation via password_changed_at
- Attachment ownership verification before linking to messages
- Message length limit (4000 chars) enforced on client and server
- Asset URL validation on avatar/banner updates
- Federation instance validation (domain regex, origin scheme, length limits)
- DB indexes on all FK columns for query performance
- Migrations: nullable moderator columns, dm_messages reply_to FK constraint
- File cleanup on avatar/banner replacement and space deletion
- Fastify trustProxy, AbortController on fetches, typing map size cap
2026-03-15 00:06:15 +01:00
Jannis Braun 1750f12c85 fix: input depth styling, missed fields, and header button order
- Add subtle border + inset shadow to input tiers for resting-state visibility
- Fix DmSearchBar and SearchPopover containers missing input depth treatment
- Fix focus ring clipping in settings panel scroll container
- Swap search and member list toggle button positions in channel/DM headers
2026-03-14 14:04:14 +01:00
Jannis Braun 836f0acef6 feat: standardize input styling with tier system, add depth and admin features
- Define 4 input tier CSS classes (input-standard, input-search, input-embedded, input-danger)
  in globals.css, migrating ~50 inputs across ~28 component files to use them
- Add subtle border and inset shadow to solid input tiers for resting-state visibility
- Fix focus ring clipping in settings panel scroll container
- Fix phantom Tailwind tokens (border-border-primary, placeholder-txt-muted)
- Add admin user management panel, storage management, and account deletion utilities
2026-03-14 13:49:32 +01:00
Jannis Braun 12b450b7b9 feat: inline DM search bar — find or start conversations from sidebar header
Replace the static placeholder button with a fully functional search bar
that filters existing DM conversations instantly and searches for users
via the API with debounce. Supports keyboard navigation, federation-aware
DM creation, group DM display, and portal-based glass dropdown.
2026-03-13 04:47:18 +01:00