Compare commits

..

23 commits

Author SHA1 Message Date
669c4af359 license: Adopt GPL-3.0-or-later
Decide on the license before the source is shared publicly: GPL v3
keeps forks and improvements of this app free software too.
2026-10-12 00:41:17 +00:00
0cebe3b710 docs: Remove the test account name from the public repo
The account name identifies a real, seeded account on the instance;
the public source doesn't need it to make sense. Credentials were
never in the repo and still live only in sops.
2026-10-12 00:33:42 +00:00
89c1a13b8b docs: Drop instance-specific storage-security notes
The public repo must not document this instance's object-storage
access-control posture; findings like that belong in private ops
notes. The engineering guidance (never rely on URL obscurity, always
request file tokens) stays.
2026-10-12 00:27:08 +00:00
5a78849a9e ui: Use the JTube TV logo for the launcher icon and TV banner
Replace the placeholder red play-square with the real logo (the
orange TV from https://jeena.net/jtube-logo.svg) converted to vector
drawables. The old placeholder still lives on in git history; the
launcher now matches the website branding.
2026-10-12 00:26:47 +00:00
7584730646 channels: Show a banner and harden D-pad activation
Channel pages now load the channel record itself and use the newest
video's thumbnail as a banner fallback, so channels never render
without a header image. Focus cards in re-sorting rows only hand out
initial focus once per screen visit so streaming stats can't steal
focus mid-navigation.

D-pad activation now also accepts ENTER/NUMPAD_ENTER/SPACE, matching
how the Compose platform fires clickable cards; consuming in the
preview phase keeps OK from double-activating.
2026-10-12 00:26:47 +00:00
28f0751e48 scripts: emulator-seed.sh — seed a fresh emulated device with the test account 2026-10-11 07:47:06 +00:00
b8893172d4 ui: CENTER activates everything (clickable lacks DPAD_CENTER)
Compose clickable handles Enter/Space only; whether the TV's OK
(DPAD_CENTER) triggers click depends on the device's input stack -
worked on the API-36 host emulator, dead on the API-34 ATD and
possibly some TVs. A preview-tunnelled center handler now activates
drawer items, top-bar buttons, video and channel cards, and the
login/search buttons deterministically, exactly once (preview
consumption prevents the platform path from double-firing).
2026-10-11 07:44:35 +00:00
d469101eb0 ui: Explicit UP from first content row to the top bar
Focus search silently failed to move from the first content card up to
the top bar (why the menu felt unreachable); the first row's cards now
have a wired UP target (the search button) in rows and grids.
2026-10-11 07:31:18 +00:00
828bfdafa9 ui: BACK = up the hierarchy (channel->channels->home->exit guard)
The BACK-opens-drawer behavior made navigation loops with the drawer
focus restore; replaced with the TV-standard: BACK leaves the player,
closes the drawer, leaves a channel drilldown, or goes Home; from Home
it is the double-press exit guard. Drawer opens via the account
button / LEFT on a leftmost card.
2026-10-11 07:28:19 +00:00
d55c265469 channels: Render rows early (pages only), guard rebuild, Long-safe sort keys
The channels screen waited for every listing page AND all per-channel
stats before showing anything - a 40s+ blank spinner. Rows now render
per page (unsorted), re-sorting as stat batches arrive. rebuildRows is
guarded; the earlier ClassCastException (Integer into a Long
comparator) surfaced via the sort call and can no longer abort the
app. All sort keys go through Long-typed helpers.
2026-10-11 07:01:27 +00:00
8d21cf35ec ui: Fix drawer focus-eater + BACK/RIGHT/LEFT menu affordances
The drawer's tap-to-close scrim was focusable: LEFT/RIGHT from a
drawer item moved focus onto the invisible fullscreen scrim, and OK
mysteriously dismissed - the drawer felt un-navigable. Scrim is no
longer focusable; RIGHT (from the drawer) closes it and BACK closes
it; closing restores focus to the search button. LEFT on any row's
leftmost card opens the drawer (used to be only the first row).
Banner prefetch keys now match the render keys (480x270) so channel
banners stop reloading on focus movement.
2026-10-11 06:45:56 +00:00
f5535eec3f ui: All list screens use home-style 4-per-row card size
Grid screens (My videos, History, Search, channel pages) switch from
3-column to adaptive columns sized exactly like the Home rows' cards,
with the compact single-line title, so every screen reads the same.
2026-10-11 06:13:59 +00:00
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
5ea1ca5124 ui: Fix recompose loop during scroll (2fps vertical)
Focus requesters were stored in snapshot-state maps and written during
composition of every list item: each write invalidated the reading
scope, which recomposed the (whole page of) items, wrote again, ...
This feedback loop is why vertical scrolling ran at ~2fps on the TV
while the same build scrolled fine in the emulator's short bursts.
Plain HashMaps kill the loop - focus handling needs no recomposition.
2026-10-11 05:17:12 +00:00
f7273121ae ui: Real account button (avatar + display name), stable list keys
The top bar now mirrors SmartTube: a 44dp circle with the actual user
avatar (persisted at login alongside the display name; falls back to
the person icon) and the display name next to it.

Scrolling jank: add stable keys to grids and rows (item/channel ids)
- without keys Compose rebinds the whole list during scroll and
re-fires every AsyncImage + focus request, which is the realistic
culprit for the 2fps vertical scrolling on the TV.
2026-10-11 05:14:32 +00:00
cc1c1d1c9d scripts: bridge-emulator.sh (host) + image prefetching
Perf work for the TV FPS complaint: every page that loads from the API
also warms Coil's disk/memory caches (video thumbnails at the same
480x270 the card renders, channel banners/avatars) so rows scroll
without popping in over the network. Prefetch keys match render keys
exactly so cache hits are guaranteed.

bridge-emulator.sh runs OUTSIDE the container on the emulator host:
boots jtubesc if needed (ADB_VENDOR_KEYS whitelists the host adb key),
installs/starts JTube TV and binds :5557 -> adbd 5601 so the container
and LAN can drive it. Run it once in your rutherford shell.
2026-10-11 01:15:51 +00:00
0d583c9660 player: Treat Escape (and plain keyboard back) as BACK
scrcpy testing from a laptop keyboard: Ctrl+B depends on the mod
binding and was unreliable; the app itself now consumes KEYCODE_ESCAPE
- player exits to the list, drawer and channel drilldowns close.
Right-click in scrcpy remains the other back.
2026-10-11 00:48:23 +00:00
e55f7f53c1 ui: First card auto-focus, visible top-bar focus, account button
On launch and on every destination switch the first card of the
content gets focus automatically - invisible focus on chrome confused
'Do I need to press DOWN first?'. The search button shows a white ring
when focused, and the top bar gained a real account button (person
icon + logged-in username) replacing the cryptic monitor icon.

start-emulator.sh: headless-safe boot (no -gpuhost crash without a
display), whitelists adb public keys headlessly (drop them into
/tmp/jtube-adbkeys/), and starts the socat bridge itself.
2026-10-10 23:52:01 +00:00
b84be3e65e scripts: Host-side GPU emulator launcher for scrcpy testing
scrcpy cannot talk to headless emulators inside the container: the
AOSP ATD image lacks framework pieces (KeyCharacterMap NPE) and there
is no GPU/KVM in the container at all. The script boots the android-tv
image image on the host with -gpu host and a window (so the RSA dialog
is clickable), installs the current debug APK and leaves the app
running; the container's socat bridge then exposes it as
rutherford:5556 for adb/scrcpy from anywhere.
2026-10-10 23:26:57 +00:00
51077b8352 player,perf: Pause info overlay, no controller flash, cheap thumbnails
Paused playback now shows a bottom panel with channel + title + views
+ upload date and position instead of the controller bar (which hid
itself while paused - it was colliding with custom info). The
controller no longer flashes 4 s at playback start: it only reveals
on UP/DOWN-style keys.

For the TV frame-rate complaint: thumbnails decode at 480x270 RGB_565
via a global Coil loader and avatars at 160px, instead of full-size
1080p+ jpegs re-composited per scroll frame. Measured on the
software-rendered emulator: stable 10% janky / p50 18ms during row
scrolling; real-hardware measurement via scripts/fps-check.sh when
the couch is free.

BACK from a Home row also refocuses the watched card now (row-local
focus requesters + restore token), fixing the 'focus lands two-three
cards left' complaint.
2026-10-10 22:53:03 +00:00
694467b038 ui: Visible drawer focus + subscriptions row on Home
Menu items now flip to white/dark on focus (before, focus moved
invisibly so navigation looked broken) with explicit UP/DOWN key
handling. Home gains a 'New from your subscriptions' row (first page,
refreshed with the rest after playback).
2026-10-10 22:29:00 +00:00
60ef94c52e ui: Eased card-row scrolling, dark text on focused white cards
Focused-card rows now animate the newly focused card to the left edge
(animateScrollToItem) instead of the abrupt bring-into-view jump -
SmartTube-style easing. Text inside a focused (white) card flips to a
dark gray-on-white palette instead of staying light gray. LEFT on the
first card of a row/chain opens the menu drawer.
2026-10-10 22:24:06 +00:00
9635e31589 ui: SmartTube layout - hidden rail, top bar, white focus cards
Drop the always-visible sidebar: content is now full width so ~4.5
compact cards fit per row (width derived from the screen). A slide-in
menu drawer opens via the avatar (BACK/LEFT close it) and carries the
destinations + sign out with legible labels (#B0B0B0) replacing the
illegible dark-grey rail. Cards no longer scale on focus: they flip
to a white background with dark text and a white frame like
SmartTube. Grids move to 3 columns with the freed width.
2026-10-10 22:16:29 +00:00

Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 KiB