Commit Graph

29 Commits

Author SHA1 Message Date
Kingkor Roy Tirtho
45a7758eb0 feat(jam): harden the room server, add device bans and friendly names
Security:
- Participants connect with a per-room key derived from a random per-install
  secret; others only see an id derived from it, so nobody can reconnect as
  someone else (including the host).
- "create" only works on a fresh code or for the room's own host, so empty
  rooms can't be taken over.
- Per-socket message and queue budgets disconnect clients that flood; the
  host throttles itself well under them.
- Bans also cover the device: a hashed digest of device traits combined with
  the network, stored only as an opaque per-room value. Earlier members are
  never caught by someone else's ban.
- Peer queue items and suggestions are sanitized (streaming tracks only, no
  URLs, https covers); suggestions are credited to the server-attested sender;
  local file paths go out as opaque ids. Names are cleaned server-side.
- Room codes and keys use a secure random source; the deploy workflow is
  read-only.

Names:
- Participants get a stable generated name ("Mellow Otter") per install, and
  can pick their own on the Jam screen or in Jam settings. The participant
  list marks "(you)".

Also translate the Jam strings into all locales and add tests for the above.
2026-10-31 18:14:45 +06:00
Kingkor Roy Tirtho
0a0b0c9374 feat(jam): replace MQTT with a Durable Object room server and synced playback
- Add jam-server/: a Cloudflare Worker with one Durable Object per room code.
  It tracks membership, host handoff and kicks/bans, keeps the queue for late
  joiners, routes guest commands to the host and serves the room clock.
- Sync playback: devices estimate the server clock, the host sends position
  anchors in server time, guests follow by nudging playback rate (seeking only
  when far off) and stream the host's audio source when they share a plugin.
- Seek, play/pause, skip and jump apply to the whole room.
- Recover from network loss instead of crashing: socket failures reconnect
  with backoff, silent sockets are detected, and an expired room is recreated
  by its host.
- Keep cost and battery low: anchors only on change (plus host drift and a
  60 s heartbeat), kept in memory rather than storage, free runtime keep-alives
  once a minute, rare clock re-syncs, and no polling while paused or buffering.
- Remove the MQTT broker settings and libraries.
- Add sync unit tests, client/session integration tests (JAM_TEST_URL) and a
  network-loss test, plus a deploy workflow for the server.
2026-10-31 16:26:41 +06:00
Kingkor Roy Tirtho
bba725a139 fix(android): fully close the app on swipe-away and avoid duplicate cookie DataStore
Initialize NewPipeDownloader once per process so recreating the Activity
no longer opens a second DataStore on spotube_cookies.preferences_pb.
Kill the process after PlaybackService shuts down on task removal so the
proxy server, MQTT client and singletons don't linger in the background.
2026-10-30 13:35:39 +06:00
Kingkor Roy Tirtho
8bbefdfb7d fix(android): app stuck on splash screen from main-thread string loading
PlaybackService.onCreate runs on the main thread and called
runBlocking { getString(...) } for its notification strings. Compose
resources share one in-flight load per strings file (AsyncCache creates the
Deferred in the caller's scope); when App()'s stringResource started that
load on the main dispatcher first, blocking main to await it deadlocked and
the first frame never rendered. Timing-dependent, so mostly seen under the
debugger.

Create the notification channel immediately under the app name and update
its localized name/description from serviceScope. The short-lived
placeholder notification no longer carries localized text.
2026-10-20 16:03:48 +06:00
Kingkor Roy Tirtho
d4961bb5ed feat: download diagnostics, live connect status, remote settings on devices screen
Downloads
- Show the real download folder: "Current folder: <path> (default)" in
  settings instead of the misleading "default music folder", and a
  "Saved to <path>" line on the Downloads screen
- Register finished downloads with Android's MediaStore (MediaScanner) so
  music players and the Files app see them immediately
- Add tagged logs across the download path to diagnose format/quality
  selection: raw NewPipe streams ([Streams]), every selection candidate
  with its rank key and fallback warnings ([Resolve]), and per-download
  enqueue prefs, resolved stream, HEAD/GET status + content type, segment
  responses and written vs expected bytes ([Download])

Connect status
- Mobile Home keeps its Devices / Group Jam / Support icons (Jam now uses
  the sound icon) and shows a slim banner only while remote-controlling a
  device or in a Jam ("Playing on krtx", "Hosting · 3 listeners")
- Sidebar Devices / Group Jam rows get a live dot and status line
- New ConnectStatusViewModel feeds both

Remote control settings
- Extract "Allow remote control" and "Device name" into shared
  remoteControlSettingCards, used by Playback settings and a new
  "This device" section on the Devices screen
2026-10-20 15:54:23 +06:00
Kingkor Roy Tirtho
b38a4f6963 feat(remote): redesign remote control and devices screens, fix connection issues
- Remove the unused "Enable Connect" setting and its strings
- Redesign RemoteControlScreen to match the expanded player: artwork sized
  to fit, side-by-side queue panel on wide screens, proper connecting /
  disconnected / error states, "Playing on <device>" subtitle
- Seek and volume sliders keep local drag state and only commit on release
  (volume throttled while dragging) instead of sending a command per frame
- Redesign DevicesScreen with the settings card components, a connected
  device card, error banner and empty state; ViewModels expose one UiState
- Fix tapping an already-connected device doing nothing; reopen its remote
  screen instead, and switch devices by disconnecting first
- Fix the controller getting stuck in Connecting after the host denies a
  request: Ktor never delivers Close frames to `incoming`, so detect the
  close reason after the receive loop ends
- Fix a UI freeze when leaving the devices screen on desktop: run discovery
  (and JmDNS's blocking close/resolve) on Dispatchers.IO
- Advertise the LAN address of the default-route interface on desktop;
  dns-sd-kt otherwise picks any site-local address, e.g. a Docker bridge
2026-10-20 15:11:10 +06:00
Kingkor Roy Tirtho
0b21eff4c7 fix(android): simplify service start logic for PlaybackService to avoid crashes on background playback 2026-10-20 13:44:30 +06:00
Kingkor Roy Tirtho
9d5854023b fix(android): update sharing functionality to use chooser intent with new task flag 2026-10-20 13:19:04 +06:00
Kingkor Roy Tirtho
75ced1285e feat(local-tracks): implement LocalFolder screen and view model for folder navigation 2026-10-18 18:04:53 +06:00
Kingkor Roy Tirtho
62c1fe7902 feat: enhance Android build configuration with stable/nightly flavors and update launcher icons 2026-10-16 21:34:44 +06:00
Kingkor Roy Tirtho
2474c26a83 refactor: move package name from dev.krtirtho to org.spotube 2026-10-16 15:37:15 +06:00
Kingkor Roy Tirtho
c9d16a25c6 fix(audio-player): android shuffle wasnt working 2026-10-16 14:36:27 +06:00
Kingkor Roy Tirtho
9f79505e1c feat(i18n): replace hardcoded strings with localized resources across multiple components 2026-10-15 14:07:56 +06:00
Kingkor Roy Tirtho
cfd472016e refactor: integrate millennium UI 2026-10-11 17:17:34 +06:00
Kingkor Roy Tirtho
a2b9f4178c feat(jam-session): integrate MQTT broker configuration and enhance jam session settings 2026-09-11 19:35:54 +06:00
Kingkor Roy Tirtho
571aea8d38 feat(remote-control): refactor service registration and cleanup logic for improved reliability 2026-09-05 09:52:06 +06:00
Kingkor Roy Tirtho
9ec7704d7b feat(jam-session): enhance jam session functionality with improved playback synchronization and error handling 2026-09-05 09:38:44 +06:00
Kingkor Roy Tirtho
df3a6dcbd2 feat(remote-control): implement remote playback functionality and UI components 2026-08-28 18:28:24 +06:00
Kingkor Roy Tirtho
f21442b1c2 feat(deeplinks): implement deep link handling for jam sessions 2026-08-28 09:33:39 +06:00
Kingkor Roy Tirtho
d3a8548661 feat(devices): add device discovery and remote control features 2026-08-21 19:50:09 +06:00
Kingkor Roy Tirtho
94903dcc33 feat: integrate Nucleus framework for enhanced window management and webview support 2026-08-14 20:40:37 +06:00
Kingkor Roy Tirtho
fe0ebb47fe Refactor webview configuration and data clearing functions for iOS and JVM platforms
- Updated `platformWebviewConfig` function to accept an optional `pluginId` parameter for both iOS and JVM implementations.
- Enhanced data directory handling in JVM to create a separate directory for each plugin.
- Implemented `platformClearWebviewData` function for both platforms to clear webview data based on the provided `pluginId`.
- Added necessary imports for iOS and JVM specific functionalities.
2026-07-30 22:53:15 +06:00
Kingkor Roy Tirtho
ec672d5f84 feat(plugin_discovery): implement GitHub plugin discovery and add logo support in UI 2026-07-25 14:57:35 +06:00
Kingkor Roy Tirtho
3448e16ed2 feat: implement blacklist functionality for tracks and artists with UI updates 2026-07-22 16:23:02 +06:00
Kingkor Roy Tirtho
a9760a711a feat: introduce AudioPlayerInterface and refactor AudioPlayer implementations for better abstraction 2026-07-20 21:45:33 +06:00
Kingkor Roy Tirtho
abeae2144c feat: enhance UI with shared element transitions and improve state management in album and playlist screens 2026-07-17 17:59:48 +06:00
Kingkor Roy Tirtho
a38b9e48cc fix: convert buildCurrentMediaItemList to a suspend function for coroutine support 2026-07-10 13:42:37 +06:00
Kingkor Roy Tirtho
2aae112cbe feat: add genre and featured browsing capabilities to MediaBrowseHelper 2026-07-10 13:31:04 +06:00
Kingkor Roy Tirtho
0c426689cb feat: migration to Compose Multiplatform 2026-06-30 17:00:13 +06:00