Commit Graph
26 Commits
Author SHA1 Message Date
SadsandClaude Opus 4.8 e54179f5c3 Startup logo spinner, search-bar focus nav, resume rescan, logo + AA play
Startup: bundle the Immich logo (app0:logo.png, transparent + AA) and show a
spinning-logo loading screen while the first page loads on a thread.

Search bar: logo to the left of the field; d-pad up from the top row focuses
the bar, left/right move across field/map/cloud (indigo ring), X activates,
down or [] returns to the grid. The selection square stays hidden while focused.

Cloud: "Made by SadsArches with love" credit; the O/Back button lives on the
See-details menu (top-right, tappable). Reverted the back circle from the
image/detail view.

Resume from sleep: an RTC wall-clock jump triggers an append-only camera
re-scan (startup reserves array headroom so it can't realloc under the worker
/sync threads).

Play overlay redrawn with the AA disc + a baked play-triangle glyph.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 17:39:01 +02:00
SadsandClaude Opus 4.8 a8129d5262 SELECT opens the cloud page from grid/detail
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 16:38:19 +02:00
Sads a9ffac76e5 Grid/search polish, cloud nav, PS-button glyphs
Grid: hide the selection square while touch-scrolling, restore it on d-pad.
Square (□) slides the top search bar in/out; the grid fills the vacated strip
(escroll = scroll + bar_hidden). Smart search now requests withExif so results
carry aspect ratios and use the justified layout instead of uniform columns.
START no longer exits the running app (PS button only); dropped the HUD hints.

Cloud page: a top-right O/Back button, and PlayStation face-button glyphs beside
each control (X details, /\ upload all, [] auto-upload) drawn as anti-aliased
outline masks on flat dark discs; the search clear is a bare red O ring. Added
cov_tri/cov_sq/cov_cross/cov_circle glyphs with a shared GLYPH_W stroke, and an
anti-aliased disc helper (disc_tex/draw_disc) for the buttons and toggle knob.

goals.md: recorded the UI-polish round.
2026-06-13 16:28:10 +02:00
Sads 00483e0b41 Cloud page: auto-upload toggle for new photos
Add an "Auto-upload new photos" switch on the cloud page (tap or Square),
persisted to ux0:data/vitaimmich/autobackup.txt and loaded at launch. While
on, the main loop queues any not-backed-up local files for upload ~once a
second (covering both launch-time detection and photos found mid-session);
the sync thread drains the queue as before. Off keeps the manual flow.
2026-06-13 15:28:44 +02:00
Sads 4aef8042c4 Cloud/backup page, map+cloud buttons, drop SELECT sync menu
Search bar: add two right-side buttons (map placeholder, cloud) drawn as
anti-aliased glyph masks; rework the magnifier into a thin ring + handle.

Cloud button opens a Server & Backup page: server storage used/total with a
usage bar, server version and URL, app version, and on-device image counts
(detected / backed up / remaining), fetched lazily via /api/server/storage
and /api/server/version (with server-info legacy fallback). A "See details"
button opens a scrollable list of not-backed-up files with per-item status
(waiting / hashing / uploading / failed). An "Upload all" button (and the
detail counts) replace the removed sync screen.

Remove the SELECT sync overview (MODE_SYNC) and its now-unused helpers; the
upload-all action it hosted now lives on the cloud page so backups stay
reachable.
2026-06-13 15:18:34 +02:00
Sads ba7a30c41d Smart search bar 2026-06-13 14:46:07 +02:00
SadsandClaude Fable 5 462c4580f0 Immich theming: Overpass font, anti-aliased white icon
- all text renders in the bundled Overpass SemiBold (Immich's
  typeface) via vita2d's FreeType path, with a per-pixel-size font
  instance cache (vita2d's glyph atlas caches glyphs at their first
  drawn size, which rendered stray oversized letters when sizes mixed)
  and a system-PGF fallback if the TTF fails to load; the OFL license
  ships in the vpk next to the font
- freetype's bzip2 references get failing stubs (the SDK ships no
  libbz2 and plain TTFs never hit that path)
- icon rebuilt from the official high-res Immich logo: anti-aliased,
  flattened onto white so the LiveArea no longer shows it on black

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 01:52:14 +02:00
SadsandClaude Fable 5 e0de84a755 Auto-fetch new photos, stable month jumps, video rotation, throbbers
- new photos on the server appear automatically: the grid polls the
  newest page every ~30 s while settled; dedup_new_assets drops
  already-known ids (and also guards page fetches against server-side
  pagination drift)
- rebuild_keep_view pins the scroll and selection to the same photo
  across every relayout (page fetch, poll, sync), so loads no longer
  move the view
- R/L month jump anchors the landed month's header to the top of the
  screen, and R fetches ahead until the next month is actually loaded
- portrait videos play upright: the asset's exif orientation is kept
  (g_asset_rot) and the player rotates decoded frames (draw_video_frame)
- "loading..." texts replaced by a spinning throbber: centered when an
  item has no preview yet, a small corner one while the full-res loads
  over the thumb (never both)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 01:16:57 +02:00
SadsandClaude Fable 5 82061c7377 Justified grid, photo swipe navigation, video posters, smart prefetch
Grid:
- justified rows like the Immich web timeline: widths follow each
  photo's exif aspect ratio (withExif on search/metadata, orientation
  aware), rows stretch to span the full screen width
- row-aware d-pad navigation (variable items per row)

Detail view:
- swipe horizontally to change photos, 1:1 with the finger, neighbor
  riding alongside; release past a quarter screen commits, less
  springs back; d-pad browsing uses the same slide animation
- touch drag pans 1:1 while zoomed
- neighbors prefetch (thumbs first, then full-res / video posters)
  so swipes land sharp; opening a cold item loads its low-res thumb
  before the full-res
- videos show their poster with a translucent play button instead of
  a "press X to play" text; tap or X plays; the gallery opens this
  screen rather than auto-playing

Video startup:
- the poster stays on screen through download progress, AVPlayer
  startup and the pre-first-frame gap; no more black screen

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 00:14:28 +02:00
Sads aab839fae8 added touch scroll 2026-06-12 22:13:48 +02:00
SadsandClaude Fable 5 9e25b7f891 Textures: bilinear filtering instead of nearest
Thumbs get blown up in the detail view while loading and full-res
photos get scaled to the screen, so sample them linearly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 21:57:40 +02:00
SadsandClaude Fable 5 5c1f3ace8e Detail view: async full-res load over the blown-up thumb, O aborts
Opening a photo no longer blocks on a "Loading photo" screen: the
grid thumbnail is drawn scaled to full screen while the worker thread
downloads and decodes the full-resolution image, and O backs out to
the grid at any time (an in-flight result is discarded there).

The synchronous loaders (load_image, load_local_image, decode_jpeg)
are gone; the worker request gained a `detail` flag that decodes to
FULL_MAX instead of THUMB_MAX, and the texture-building half of
consume_worker_result is shared via req_build_texture.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 21:22:02 +02:00
SadsandClaude Fable 5 fef68a71d2 Grid: L/R jump by month; X on a video plays it immediately
- L/R triggers move to the first photo of the previous/next month
  instead of two rows (month_jump walks the date-grouped timeline)
- pressing X on a video tile starts the download/playback right away,
  skipping the detail view's "press X to play" stop

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 20:53:42 +02:00
SadsandClaude Fable 5 a1222af8ae Grid: drop the full-screen "Loading more photos" flash
Pages now fetch behind the live grid; the HUD's "+" already signals
that more photos are coming, and the fetch only blocks briefly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 20:33:18 +02:00
SadsandClaude Haiku 4.5 87721390fb Scalable assets, zoom/pan, monthly grouping, and scroll stability
- Dynamic arrays for assets (remove 1000/500 caps)
- Zoom (R/L triggers) and pan (analog stick) in detail view
- Group gallery by month/year with headers
- Fix fast-scroll crashes via texture pooling and thread safety
- Serialize curl calls (OpenSSL 1.0.2 lacks thread support)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-12 20:27:51 +02:00
SadsandClaude Opus 4.8 6c7cc4b322 Video: show real duration, stay on replay prompt at end
Fix the playback HUD showing "/ 0:00": duration is re-polled in the
render loop until sceAvPlayerGetStreamInfo reports it, instead of being
latched once before async parsing finishes.

When a video reaches its end, hold on the last frame with an
"X replay / O back" prompt instead of returning to the detail screen
(which, for server videos, forced a full re-download to watch again).
X replays from the still-local file via re-init; the decoder claim is
held across replays.

Also add the agentic loop tooling/docs: AgenticLoop.md runbook
(build, install, drive Vita3K via kwin-mcp, zero-context-cost frame
capture), controls.MD key map, deploy.sh, .mcp.json, and gitignore
build-native/ and agent-run/.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 18:13:03 +02:00
Sads 1f6f913b49 Added build with Docker 2026-06-12 16:19:04 +02:00
Sads 9713595def Extract poster frames from local camera videos 2026-06-12 14:44:17 +02:00
Sads f09f0d0757 Add camera media sync with upload support 2026-06-12 13:18:52 +02:00
Sads ea759255da Downloads and plays MP4 videos using the Vita's GPU decoder. Shows
progress on download, supports pause/resume and seeking during playback.
  Videos are deleted after viewing.
2026-06-12 12:07:54 +02:00
SadsandClaude Fable 5 31ae59d528 Convert icon0.png to 8-bit palettized PNG for LiveArea
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 00:08:30 +02:00
SadsandClaude Fable 5 bb137f2da9 Add serverip= config option to pin the domain to a LAN IP
The "unsupported protocol" failure was never about HTTPS: the Vita
resolved the public domain to the WAN IP, the router (no NAT loopback)
answered with its own admin page, and curl reported the resulting
HTTP/0.9 garbage as CURLE_UNSUPPORTED_PROTOCOL. serverip= pins the
hostname to the LAN IP via CURLOPT_RESOLVE, keeping Host/SNI intact
for the reverse proxy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 00:07:08 +02:00
SadsandClaude Fable 5 73835fa2f6 Add runtime curl diagnostics to the log
Log libcurl's runtime version/SSL backend/protocol list at startup,
mirror fatal errors into log.txt, and capture curl's verbose debug
stream for the first request.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 23:59:23 +02:00
SadsandClaude Fable 5 90709fd487 Log hex dump of parsed server URL at startup
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 23:50:19 +02:00
SadsandClaude Fable 5 65d772aae5 Sanitize config values and surface the URL on connection errors
curl error 1 (unsupported protocol) was caused by invisible junk in
the config: leading whitespace, tabs or a UTF-8 BOM around the server
URL. Trim all of it, default to http:// when no scheme is given,
validate the scheme with the parsed value shown on screen, and include
the attempted URL in the first-connection error.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 23:44:20 +02:00
SadsandClaude Fable 5 b7ac3768a8 Initial commit: Immich client PoC for PS Vita
Scrollable chronological photo grid with full-screen viewer, fetching
previews from an Immich server via its REST API. Thumbnails stream in
on a background thread over a keep-alive connection. JPEG decoding is
done with libjpeg directly (vita2d's loader rejects Immich's
APP2-first JPEGs). JSON parsed with vendored jsmn (the vitasdk jansson
package is built as PIC, which vita-elf-create can't handle).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 23:34:27 +02:00