Commit Graph
10 Commits
Author SHA1 Message Date
SadsandClaude Opus 4.8 5a0eb06d3e Places map: city base map, cluster gallery, zoom + render polish
Base map / tiles:
- Switch the base map to the mapchart city-label world map; re-derive its
  Web-Mercator georeferencing (MAP_LON0/1, MAP_IMG_MY0/1) by least-squares
  against the pixel-identical graticule export.
- Add a 1.5x LANCZOS supersample LOD and bump tile quality 90->94 so city
  labels stay crisp when zoomed in (tools/png_to_tiles.py).
- Fill the map view background with the ocean colour instead of black.

Navigation / clustering:
- Snap the cluster grid to power-of-two zoom octaves so the bubbles stop
  jittering during a continuous zoom.
- Replace the loose zoom clamps with named MAP_SCALE_MIN/MAX (whole map fills
  the screen .. country/region level).
- Add a toggleable computed lat/lon graticule overlay (TRIANGLE).

Cluster gallery:
- Selecting a bubble now opens all its photos on the same justified grid as
  the timeline/search (a g_gallery_active filter). Members not already paged
  in are appended as hidden g_asset entries (kept out of the main timeline);
  a background metadata worker resolves each one's date/aspect so the grid
  reflows into month sections + true aspect ratios.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011uKJQMYDE9Nrq9ECsU3MxH
2026-06-18 22:26:59 +02:00
SadsandClaude Opus 4.8 66b9d77ac4 Add geotag "Places" map with raster LOD tile pyramid
New src/map.c (unity-build part) adds a map screen reached from the search
bar's map button:
- Fetches geotag markers (GET /api/map/markers), projects with Web Mercator.
- Clusters markers into count "bubbles" in map space (anchored to the world,
  so panning translates them instead of reshuffling); pan (d-pad/touch),
  zoom (L/R/pinch). X or tap zooms into a cluster, or opens a lone/co-located
  photo — fetching that asset on demand if it isn't paged into the grid —
  and returns to the map on back.
- Base map: a Web-Mercator LOD tile pyramid generated offline from a MapChart
  PNG (tools/png_to_tiles.py -> assets/maptiles.pak); the level matching the
  on-screen scale is drawn from 256px JPEG tiles decoded into pooled textures
  (the crash-safe path), with a coarse overview underneath so there are no
  gaps while tiles stream in. Georeferencing (full longitude, lat band) was
  fit from isolated-island centroids so markers land on land.

main.c uses a larger vita2d vertex pool; app.c wires the mode in.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 04:24:03 +02:00
SadsandClaude Opus 4.8 351804819b Video bitrate probe, loading throbbers, boot spinner, transparent logo
- Video: probe the MP4 header (range request for moov) before downloading
  the whole clip; if the average bitrate overruns the declared H.264 level
  the Vita's decoder enforces, show the "too high" message up front instead
  of downloading then failing at playback. Verdict validated against the
  real demo videos (e.g. e75d495e: Level 3.1 @ 18.8 Mbps -> rejected).
- Error screens: word-wrap title + detail so long messages no longer run
  off the edges; the bitrate message now spells out the server-side fix
  (Immich transcoding policy / bitrate cap).
- Boot: one continuous spinner. A single boot worker thread does sign-in +
  first page + local scan while the main thread animates one logo with a
  never-resetting frame counter, instead of three separate static screens.
- Throbbers: the cloud/server-info page and smart search now fetch on a
  worker thread and animate a throbber instead of freezing the UI.
- Logo: swap the in-app logo for a clean 200x200 transparent PNG (the old
  one was matted from the white-background icon and had fringe); keep the
  launcher icon's white background. Linear-filter the logo + cloud badges
  so they scale/rotate smoothly.
- Drop AgenticLoop.md (and its CLAUDE.md reference).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 00:48:42 +02:00
SadsandClaude Opus 4.8 fc2127450f Cloud-status badges from Immich SVGs; remove the bottom HUD bar
Replace the grid status dot with the Immich cloud icons (rasterized from the
provided SVGs to white transparent PNGs: cloud = on server, cloud-off = on
device, cloud-done = on both). Drawn white in the cell's bottom-right corner,
no background, with a 1px dark shadow for legibility (red tint on failure).
Icons rendered high-res, thinned, and LANCZOS-downscaled so they stay
anti-aliased at badge size.

Also drop the bottom HUD hint bar on every page (draw_hud is now a no-op).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 19:33:04 +02:00
SadsandClaude Opus 4.8 b329cc6b50 Login screen, account switching, and UI polish
Login: an interactive sign-in screen (server/email/password via the on-screen
keyboard, touch + d-pad, password masked) shown when there's no usable
credential or a config login fails, plus a "Try the demo server" button. The
bundled Immich logo is now the official transparent PNG (clean edges), drawn
minified on a slow spin for the startup loader.

Logout (cloud menu, top-left) returns to the sign-in screen instead of quitting;
on re-auth, reset_for_account_change() pauses the sync thread, drains the
thumbnail worker, recycles thumbnails, drops the old library/local/search state
and reloads from the new account. The thumbnail worker now builds its auth
header (and resolve list) per request, so a new token takes effect immediately
instead of looping on "invalid user token"; g_serverip is cleared on logout.

Grid: Square now drops focus to the grid AND hides the top bar in one press.

Verified against demo.immich.app (v2.7.5) over TLS 1.2: login, grid/search,
cloud page, logout -> Try demo account switch, all with working thumbnails.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 18:48:49 +02:00
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
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 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