Add a quiet "Powered by Sofa" footer to the logged-out splash screen,
linking to sofa.watch. The footer sits in normal flow below the hero so
it can't overlap the buttons on short screens, and clears the bottom
safe-area inset.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Exclude library titles and order by lastFetchedAt in SQL, and stamp
lastFetchedAt when a non-library refresh fails so it moves to the back.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Pin all @orpc/* catalog entries to 2.0.0-beta.42; @sofa/api now depends on @orpc/openapi
- Contract routes move from .route() to .meta(openapi(...)); schemas gain meta ids so the
OpenAPI document hoists them as named components; publicInfo overrides document-level security
- OpenAPI generator/handler use v2 APIs (converters, base, spec plugin option, OpenAPI 3.1.1 output)
- Add restoreRootFileType routing interceptor so root-level File inputs (avatar upload, backup
restore) keep their MIME type under Bun.serve
- Web/native links use origin + path url; native error classification derives HTTP status from
COMMON_ERROR_STATUS_MAP / MalformedResponseError since ORPCError.status is gone
- router-auth test reads v2 orderedMiddlewares; regenerated docs/public/openapi.json
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
updateStatus now returns { alreadyAdded }. Native toasts say so instead of
claiming success, and the Explore hero hides Add to Watchlist for library titles.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Window starts now equal the first chart bucket, and year buckets are built from the 1st of each month so the 29th-31st no longer repeat or skip months.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds tracking.history (cursor-paginated, movies and episodes merged), a
last_watched library sort, and a /history web page.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Declare the app's 12 languages to iOS and Android via expo-localization,
resolve the language from the device's preferred languages at start-up and
on Android runtime changes, and make Settings > Language open the system
settings page. Drops the MMKV-stored locale.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Extract the job loop into runImportJob (with tests), hold its UI state in
useImportJob, and move the importing/done steps and stat/option components
into import-dialog-parts. Both dialogs now close when an import continues in
the background or the connection drops.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Search queries that look like an IMDb ID (e.g. tt0133093) are now resolved
through TMDB's find endpoint, respecting the movie/tv type filter.
Supersedes #60.
Co-authored-by: Gonçalo Fonseca <gcare.fonseca99@outlook.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Android tab bar only declared four tabs with hard-coded English
labels, so the Library route was never registered and "See all" on Home
did nothing. Match the iOS tab set and order and use LingUI labels.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>