A PeerTube client for Android TV.
Find a file
Jeena b3b39976fe channels: Per-user rows, empty-channels row, redesigned stats card, subs detail
Channels now render as SmartTube rows and scroll vertically
(LazyColumn - the unscrollable Column hid rows 2+). Local channels
group one row per ownerAccount, sorted by total video count, with all
zero-video channels merged into a final 'No videos yet' row.
Followed-instance channels group per platform. The channel card
matches the video-card language: banner center-cropped, round avatar
bottom-left, channel name, 'owner display name - platform display
name' (instance names via /config, local cached at login; no domain
strings), and an icon stat line (videos | subscribers | plays); counts
load per channel in the background since the listing endpoint doesn't
carry them (verified on the live API).

Subscriptions destination switches to per-channel rows, matching the
Home card size.
2026-10-11 05:42:02 +00:00
app channels: Per-user rows, empty-channels row, redesigned stats card, subs detail 2026-10-11 05:42:02 +00:00
gradle app: Scaffold Android TV PeerTube client (MVP) 2026-10-10 10:20:02 +00:00
scripts scripts: bridge-emulator.sh (host) + image prefetching 2026-10-11 01:15:51 +00:00
.gitignore player,ui: Fix the remote-blocking bugs from the Claude UX run 2026-10-10 12:23:11 +00:00
AGENTS.md test: Add e2e release gate (script + manual checklist) 2026-10-10 11:02:22 +00:00
BACKLOG.md ui: SmartTube-style home rows, focus memory and UX-review fixes 2026-10-10 11:29:08 +00:00
build.gradle.kts app: Scaffold Android TV PeerTube client (MVP) 2026-10-10 10:20:02 +00:00
gradle.properties app: Scaffold Android TV PeerTube client (MVP) 2026-10-10 10:20:02 +00:00
gradlew app: Scaffold Android TV PeerTube client (MVP) 2026-10-10 10:20:02 +00:00
gradlew.bat app: Scaffold Android TV PeerTube client (MVP) 2026-10-10 10:20:02 +00:00
README.md app: Scaffold Android TV PeerTube client (MVP) 2026-10-10 10:20:02 +00:00
settings.gradle.kts app: Scaffold Android TV PeerTube client (MVP) 2026-10-10 10:20:02 +00:00
TESTS.md player,ui: Fix the remote-blocking bugs from the Claude UX run 2026-10-10 12:23:11 +00:00

JTube TV

An Android TV client for PeerTube instances, inspired by how SmartTube works for YouTube. It talks to any PeerTube instance (the default is JTube — my own instance) over the PeerTube REST API.

Features (v0.1)

  • Setup flow — enter instance URL, username and password once; the app exchanges them for OAuth tokens via POST /api/v1/users/token and stores only the tokens (never the password), encrypted with the Android Keystore (EncryptedSharedPreferences).
  • Local videos — list public videos of the instance (GET /api/v1/videos?isLocal=true).
  • My videos — all of the logged-in user's own videos, every privacy level included (private, internal, unlisted — GET /api/v1/users/me/videos). Non-public entries carry a privacy badge.
  • Channels — list channels local to the instance (GET /api/v1/video-channels?search=…&searchTarget=local) and browse each channel's videos.
  • Search — search local videos by title.
  • Subscriptions — the videos in the user's subscription feed (GET /api/v1/users/me/subscriptions/videos).
  • History — the user's watch history as tracked by the server (GET /api/v1/users/me/history/videos).
  • Playback — HLS (or progressive MP4 fallback) playback with ExoPlayer/Media3. Viewing is reported to the server (POST /api/v1/videos/{shortUuid}/watching) so it shows up in server-side history. Private/internal media is streamed with the OAuth token attached to every playlist/segment request.

Out of scope for now (see BACKLOG.md): uploading, editing, subscribing/unsubscribing, deleting, creating anything other than history entries.

Build

Requirements: JDK 17+ (JDK 21 recommended), Android SDK platform 35. local.properties with sdk.dir=… is picked up automatically if present (standard Android Gradle Plugin behavior).

./gradlew :app:assembleDebug

Install on a TV device:

adb connect <tv-ip>:<port>
adb install -r app/build/outputs/apk/debug/app-debug.apk

Building requires a JDK; the Gradle wrapper is checked in, so no local Gradle installation is needed.

Architecture overview

Single-module Android TV app (app/):

  • data/api — Retrofit interface + kotlinx-serialization DTOs for the PeerTube API.
  • data/auth — TokenStore (EncryptedSharedPreferences), token acquisition/refresh.
  • data/network — OkHttp/Retrofit wiring: dynamic base-URL interceptor, bearer-token interceptor, single-flight token refresh authenticator.
  • data/PeerTubeRepository.kt — one suspend-call surface used by all view models.
  • ui/ — Compose for TV screens: Setup, Home (sidebar + list content), VideoList (local / my videos / subscriptions / history / search / channel), Channels, Player. MainActivity is the only activity.
  • JTubeApp.kt — tiny service locator (AppGraph); no DI framework on purpose.

License

Not decided yet — TBD before first public release.