Commit Graph
34 Commits
Author SHA1 Message Date
Jannis Braun 0d652a72cd fix(desktop): base set-auto-launch-settings on OS truth, not stale disk 2026-04-27 12:49:00 +02:00
Jannis Braun cd00da07d8 fix(desktop): make get-auto-launch-settings OS-authoritative on Windows 2026-04-27 12:46:10 +02:00
Jannis Braun 622b9a6929 fix(desktop): pass enabled/path/args/name to setLoginItemSettings per platform
macOS: add args:[--hidden] alongside openAsHidden for defence-in-depth detection on macOS 13+.
Windows: add enabled/path/args/name so re-enabling the toggle clears the StartupApproved\Run disable marker.
Linux: add deterministic name:'backspace' so the .desktop filename is stable across Electron/AppImage updates.
2026-04-27 12:40:44 +02:00
Jannis Braun 495cad717d refactor(desktop): tighten autoLaunch helpers per code review 2026-04-27 12:38:33 +02:00
Jannis Braun 191ba5f248 feat(desktop): add pure auto-launch helpers with tests 2026-04-27 12:33:52 +02:00
Jannis Braun 4574a99f2a chore(desktop): add vitest for pure-helper tests 2026-04-27 12:29:38 +02:00
Jannis Braun cc30080ba8 chore: sync repo with deployed state — clean up old specs/plans, desktop tweaks 2026-03-24 04:33:23 +01:00
Jannis Braun 1bdd9a387a revert: remove ineffective GPU encoding flags from Electron
Hardware H.264 encoding in Electron's WebRTC requires SDP profile
negotiation changes (NVENC rejects Constrained Baseline), not
command-line flags. VP9 via libvpx is the correct default — proven
by empirical benchmarks (CS2: VP9 60fps vs H.264 30fps).
2026-03-24 02:00:43 +01:00
Jannis Braun 6844f8d8fd fix: clean up GPU flags — hardware H.264 encoding not available on Win/Mac
AcceleratedVideoEncoder only enables VA-API encoding on Linux.
Windows/macOS hardware H.264 encoding in Chromium's WebRTC is not
reliably controllable — VP9 via libvpx remains the recommended codec.
2026-03-24 01:55:18 +01:00
Jannis Braun e4f6f9a4c4 fix: translate uiohook keycodes to match web UI keybind hashes
The web UI records keybinds as djb2 hashes of DOM event.code strings
(e.g. "KeyM" → 2090563626), but uiohook fires native scan codes
(e.g. M → 50). These never matched, so global keybinds only worked
in-focus via the web fallback, never out-of-focus via the native hook.

Add a uiohook-to-DOM-code mapping table and pre-compute the djb2
hashes so pressedKeys uses the same numbering as the keybind store.
2026-03-22 23:50:02 +01:00
Jannis Braun e5bf5f71ab fix: unpack native .node binaries from asar for uiohook-napi
Removed blanket !node_modules exclusion and added asarUnpack for .node
files so uiohook-napi's native binary can be loaded at runtime.
2026-03-22 22:27:10 +01:00
Jannis Braun 3ce9ee0db0 feat(desktop): add KeybindManager with uiohook-napi for global shortcuts
Installs uiohook-napi for OS-level non-consuming input hooks, creates
KeybindManager class that receives keybind configs from the renderer,
matches the OS-wide key/mouse event stream, and sends matched actions
back via IPC. Exposes syncKeybinds, onKeybindAction, onAccessibilityStatus,
onKeybindHookError, and checkAccessibility APIs through the preload bridge.
2026-03-22 20:47:41 +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 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 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 ac7d3cb71b feat: add start-at-boot setting and fix tray icon to use app logo
Add auto-launch settings (start at boot + start minimized) to the
Desktop section in Account settings, using Electron's built-in
setLoginItemSettings API across macOS, Windows, and Linux.

Replace the fallback colored-circle tray icon with proper B logo assets:
template images for macOS (adapts to light/dark menu bar) and colored
icons for Windows/Linux. Fix BGRA channel order bug in fallback generator
and move tray icons to resources/ so they're packaged into the app.
2026-03-17 02:28:38 +01:00
Jannis Braun 26f2e2a817 fix: remove experimental useSystemPicker causing double-picker and no audio on macOS
useSystemPicker triggers applyConstraints to re-open the system picker
(Electron #44684) and doesn't reliably pass audio capture. All platforms
now use the custom Aether Drift picker with explicit loopback control.
2026-03-16 19:13:14 +01:00
Jannis Braun bda7930e61 fix: restore setDisplayMediaRequestHandler with useSystemPicker
Electron requires setDisplayMediaRequestHandler for getDisplayMedia() to
work — removing it broke screen sharing entirely. Restored the handler
with useSystemPicker: true, which on macOS 15+ uses the native system
picker (honoring restrictOwnAudio), while Windows/Linux fall back to
the custom picker with the shareAudio toggle for echo control.
2026-03-16 18:34:50 +01:00
Jannis Braun 9ff3761640 fix: remove setDisplayMediaRequestHandler to let restrictOwnAudio work natively
The custom screen share picker intercepted getDisplayMedia() and created
a raw loopback stream, bypassing Chromium's constraint pipeline entirely.
restrictOwnAudio was silently discarded. Removing the handler lets
Chromium 144's native getDisplayMedia run end-to-end with restrictOwnAudio
applied, eliminating the audio feedback loop in the desktop app.
2026-03-16 18:18:42 +01:00
Jannis Braun 46f55643ae fix: eliminate screen share audio feedback loop + upgrade Electron 33→40
Screen sharing with audio captured the app's own voice playback, causing
users to hear themselves echoed back. Fixed via two layers:

- Add restrictOwnAudio constraint (Chrome 141+/Chromium 144) to exclude
  the app's own audio from system audio capture
- Add shareAudio toggle so users can disable system audio entirely
- Remove outdated macOS audio block (now supported via ScreenCaptureKit)
- Upgrade Electron 33→40 (Chromium 130→144) so restrictOwnAudio works
  natively in the desktop app
- Add NSAudioCaptureUsageDescription for macOS 14.2+ audio capture
- Add GTK 3 fallback for Linux GNOME compatibility (Electron 36+)
2026-03-16 18:01:40 +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 cd2f1e52ef fix: proper macOS dock icon via .icns bundle replacement
Replace the Swift squircle hack with the correct Apple approach:
generate a proper .icns using sips + iconutil, then replace
electron.icns in the Electron bundle before launch. macOS applies
its native squircle mask + shadow from the .icns automatically.
2026-03-16 04:29:09 +01:00
Jannis Braun c176ea801a feat: squircle dock icon for macOS dev mode
macOS only applies the squircle mask to packaged .app bundles. For dev
mode, generate a pre-masked icon-dock.png via Swift/AppKit at launch
and set it with app.dock.setIcon(). Silently skipped on non-macOS.
2026-03-16 04:15:09 +01:00
Jannis Braun da05eb3262 fix: replace placeholder purple square icons with actual Backspace logo
Regenerate all web icons (favicon, PWA, apple-touch) from master 1024x1024
icon.png. Add BrowserWindow icon property for Windows/Linux taskbar icon
in Electron dev mode.
2026-03-16 04:01:52 +01:00
Jannis Braun 2e919445c1 feat: wire up master app icon for Electron builds
Point prebuild script at the 1024x1024 master icon.png at project root.
electron-builder auto-generates .icns (macOS), .ico (Windows), and
multi-size PNGs (Linux) from build/icon.png during packaging.
2026-03-16 03:57:30 +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 4d230711fc feat: launch readiness — PWA, API hardening, memory leak fixes, sticker removal
- Add PWA infrastructure: vite-plugin-pwa, manifest, service worker,
  SW update prompt component, placeholder icons, Apple meta tags
- Harden API client: 401 auto-logout, AbortController timeouts
  (30s standard, 120s uploads), onUnauthorized callback
- Fix memory leaks: clear voice user status on leave, clean up all
  Maps (channelToSpaceMap, permissions, etc.) on removeSpace
- Upgrade error boundary to Aether Drift design with Try Again button,
  collapsible stack trace, and componentDidCatch logging
- Configure desktop icon paths in electron-builder.yml
- Remove sticker feature (server routes, schema, types, UI components)
- Fix Docker build: use **/node_modules in .dockerignore to prevent
  COPY from clobbering pnpm-installed workspace dependencies
- Add vite-env.d.ts declarations for noise suppressor wasm imports
- Exclude test files from tsc build via tsconfig
2026-03-15 15:41:22 +01:00
Jannis Braun e219229b63 feat: add Backspace design prototype and rebrand from Opencord
- Add Backspace-design-prototype.html: finalized "Aether Drift" design
  language with warm matte surfaces and subtle frosted glass accents
- Update CLAUDE.md with DESIGN SYSTEM section and remove Discord clone references
- Rename all Opencord references to Backspace across the full codebase
- Archive outdated design experiments and Discord-specific assets
- Add science-backed accessibility fallback (prefers-reduced-transparency)
2026-03-01 21:26:57 +01:00
Jannis Braun 4fd17084a5 chore: Initial commit of Opencord base state 2026-02-18 02:49:21 +01:00