Commit Graph
40 Commits
Author SHA1 Message Date
Santo ShakilandGitHub d5adfb97dd fix(mobile): treat wired ethernet as unmetered on ios (#29351)
check the metered flags instead of the interface type, so ethernet counts like android already does.
2026-07-21 11:02:36 -05:00
Santo ShakilandGitHub 943bfafb7a fix(mobile): show real error when an asset can't be added to an album (#29754)
* fix(mobile): show real error when an asset can't be added to an album

* fix(mobile): show added toast when an add-to-album partly succeeds

* docs(mobile): explain why a partial add-to-album shows added
2026-07-21 10:56:50 -05:00
Santo ShakilandGitHub 14a2776453 fix(mobile): add album picker to the partner view bottom sheet (#30099) 2026-07-21 10:05:34 -05:00
Santo ShakilandGitHub 4938fd4c89 fix(mobile): back up files moved into a watched folder on android (#29872) 2026-07-21 19:09:50 +05:30
Santo ShakilandGitHub e81a79224c fix(mobile): stop double close animation when dismissing an asset (#29413) 2026-07-21 19:08:45 +05:30
Santo ShakilandGitHub 2cdbd0d00f fix(mobile): apply exif orientation to remote raw photos on android (#29906) 2026-07-14 19:10:41 -04:00
Santo ShakilandGitHub 9c8d718ddc fix(mobile): send a full datetime from the android memories widget (#29689) 2026-07-14 09:25:06 -05:00
c4f084f4a5 fix(mobile): play videos from search results and folder view (#29693)
* fix(mobile): play videos from search results and folder view

* pr suggestion

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-07-08 20:22:35 +00:00
2ad554fc61 fix(mobile): update timeline args on layout constraint changes (#29653)
* fix(mobile): update timeline args on layout constraint changes

* chore(mobile): temporary blank timeline diagnostics

* chore(mobile): error logs when the timeline goes blank

* chore(mobile): remove blank timeline debug logging

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-07-08 14:13:32 -05:00
58b1c5e8fb fix(mobile): fix 10-bit heic and avif colors on android (#29631)
* fix(mobile): fix 10-bit heic and avif colors on android

* fix(mobile): share the decode pool across flutter engines

* vectorize conversion

---------

Co-authored-by: mertalev <101130780+mertalev@users.noreply.github.com>
2026-07-06 21:16:09 +00:00
Santo ShakilandGitHub af2efda310 fix(mobile): apply exif orientation to android raw photos (#29337) 2026-06-29 10:59:09 -04:00
Santo ShakilandGitHub 6e1143e799 fix(mobile): hide video thumbnail when video is ready (#29012) 2026-06-26 22:20:40 -05:00
Santo ShakilandGitHub 29949bebe4 fix(mobile): only toggle backup from the switch, not the whole row (#29236)
tapping anywhere on the enable backup row flipped backup on or off, so it was easy to toggle by accident. now only the switch does it.
2026-06-26 20:00:08 +05:30
Santo ShakilandGitHub e5b50a55a4 fix(mobile): blank notifications page after enabling notifications (#29232)
the old notification toggles were removed in a cleanup, so once notifications were enabled the page had nothing left and went blank. show a "notifications enabled" status tile with a shortcut to the system notification settings instead.
2026-06-24 09:15:28 -05:00
Santo ShakilandGitHub 9a5e7a8e47 fix(mobile): endless spinner on album selection when device has no albums (#28994)
* fix(mobile): endless spinner on album selection when device has no albums

* use a page scoped future provider for the loading state

* refactor(mobile): decide album selection empty state in the parent
2026-06-18 21:38:15 +05:30
Santo ShakilandGitHub c35abb2f66 fix(mobile): re-lock locked folder when the app is backgrounded (#29089)
* fix(mobile): re-lock locked folder when the app is backgrounded

* fix(mobile): simplify locked folder overlay condition

* fix(mobile): lock locked folder on pause instead of resume
2026-06-18 21:10:18 +05:30
Santo ShakilandGitHub 793487e52c fix(mobile): refresh memories on resume and day change (#28983)
* fix(mobile): refresh memories on resume and day change

* fix(mobile): invalidate memories once after the resume sync
2026-06-18 20:46:20 +05:30
Santo ShakilandGitHub cda499f2b5 fix(mobile): keep toasts off the dynamic island when keyboard is open (#29159) 2026-06-16 18:51:29 +00:00
Santo ShakilandGitHub 12b7cd066b fix(mobile): show memories with no showAt/hideAt in the timeline lane (#29158) 2026-06-16 18:46:52 +00:00
Santo ShakilandGitHub 9ee412110f fix(mobile): stop sync albums crashing on the main isolate (#29133)
the album sync provider read cancellationProvider, which only exists in the background isolate and throws on the main one. moved the cancel signal onto the isolate call path.

fixes #29125
fixes #29119
2026-06-16 09:14:33 -05:00
Santo ShakilandGitHub abd62d9295 fix(mobile): show like and comment options on album photo deep links (#29020) 2026-06-12 14:55:26 -05:00
Santo ShakilandGitHub 59d036a2ed fix(mobile): give android notification channels proper names (#28986) 2026-06-11 15:07:37 +00:00
Santo ShakilandGitHub e2954b6411 fix(mobile): show albums whose assets are all trashed (#28985) 2026-06-11 09:41:02 -05:00
Santo ShakilandGitHub d227ba2d51 fix(mobile): stale details after editing asset date (#28977) 2026-06-10 21:32:02 -05:00
Santo ShakilandGitHub 9cb94343d1 fix(mobile): keep timezone when editing asset date time (#28978)
* fix(mobile): keep timezone when editing asset date time

* fix(mobile): negative utc offsets with minutes off by an hour
2026-06-10 21:31:31 -05:00
Santo ShakilandGitHub 07813135b5 fix(mobile): deduplicate people in asset details panel (#28972) 2026-06-10 14:37:45 +00:00
Santo ShakilandGitHub 11c1025271 fix(mobile): add album picker to archive bottom sheet (#28953) 2026-06-09 14:45:32 -05:00
Santo ShakilandGitHub c928787b3e fix(mobile): show error when creating an album fails (#28942)
it failed silently when the server was down. also disable create for blank titles.
2026-06-09 16:41:32 +00:00
Santo ShakilandGitHub fe9ca4f40a fix(mobile): show memory and folder dates in local time (#28941) 2026-06-09 10:55:43 -05:00
Santo ShakilandGitHub 8d553d6e9c chore: add santo to mobile codeowners (#28863) 2026-06-05 17:24:07 +00:00
Santo ShakilandGitHub 429e181c8f fix(mobile): run iOS bg task phases in parallel (#28293)
onIosUpload runs sync local, sync remote, hash and handle backup
sequentially. on the bg refresh task path that's a 20s budget from
iOS, and sync + hash usually eat all of it before backup gets a turn
to enqueue any candidates.

these phases don't actually depend on each other. local + remote sync
touch different tables. hash works off whatever's already in drift.
handle backup reads candidates and just enqueues to URLSession bg.
anything one phase produces in this fire shows up to the others on
the next fire, and server-side dedup catches the rare race where
backup enqueues something sync remote was about to mark as already
uploaded.

so this runs all four concurrently via Future.wait, with hash getting
the full maxSeconds-1 budget instead of a fixed 5s. outer budget
timeout still caps everything before iOS expires.

second small change: getAssetsToHash orders by createdAt DESC instead
of id ASC to match getCandidates. when hash runs inside a refresh
fire it processes recent photos first.
2026-06-03 20:13:52 -05:00
Santo ShakilandGitHub 3ab3d5cf43 fix(mobile): don't force-unwrap nil localizedTitle in ios getAlbums (#28452)
crashes on ios 26 when a PHAssetCollection returns nil for
localizedTitle. fall back to localIdentifier. ref #28428
2026-05-15 18:12:28 -05:00
Santo ShakilandGitHub df016f9228 fix(mobile): mounted check in ThumbnailTile hero flight listener (#28451)
When the user pops back from the asset viewer mid-flight, the hero
animation can fire its status listener after _ThumbnailTileState has
been disposed. setState then throws a null check on State._element.

Guard the listener with `if (!mounted) return;` — same pattern as
#28300 in the album sync action.
2026-05-15 21:41:04 +00:00
Santo ShakilandGitHub 17779c1e74 fix(mobile): cronet thumbnail buffer overflow regression from #28439 (#28450)
The hybrid added in onReadCompleted reuses Cronet's ByteBuffer between
reads to save a JNI wrap call when no grow is needed. That reuse breaks
advance() — Cronet's position() is cumulative across reads, so the same
K bytes get counted on every subsequent iteration. b.offset overshoots
b.capacity, the reuse branch keeps firing on a now-empty buffer, and
request.read() throws the original IllegalArgumentException again.

Always pass a fresh wrap from wrapRemaining() so byteBuffer.position()
reflects only this iteration's bytes. Same shape as the original PR
had before the broken optimization was layered on top.
2026-05-15 17:25:31 -04:00
Santo ShakilandGitHub 01d6a244d8 fix(mobile): cronet buffer overflow on compressed thumbnails (#28439)
CronetImageFetcher sized the response buffer from Content-Length, which is
the compressed wire size. Cronet auto-decompresses gzip/br responses and
writes decompressed bytes into the buffer, exceeding it and throwing
IllegalArgumentException: ByteBuffer is already full on the next read. Use
the growable path; Content-Length becomes an initial alloc hint only,
capped at 128 MB so an untrusted server can't overflow Int.MAX_VALUE or
OOM us upfront. Reuse Cronet's ByteBuffer between reads when no grow is
needed.
2026-05-15 14:48:23 -04:00
b031548791 fix(mobile): don't block app open on slow validateAccessToken (#28405)
* fix(mobile): don't block app open on slow validateAccessToken

AuthGuard.onNavigation was async so auto_route awaited the body through validateAccessToken's OS timeout. now it's sync and the validate runs in bg. kicks to login on 401.

* fix(mobile): handle re-login race in AuthGuard validate

if user logs out + logs back in during a slow validate, the old 401 was logging them out again. now we check the token hasn't changed before redirecting, and dedupe in-flight calls.

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-05-13 11:52:43 -05:00
Santo ShakilandGitHub f632d320f5 fix(mobile): clear linkedRemoteAlbumId in reset() so FK refs dont dangle (#28382)
* fix(mobile): clear linkedRemoteAlbumId in reset() so FK refs dont dangle

reset() runs with foreign_keys off before wiping remote_* tables, so the ON DELETE SET NULL cascade on linkedRemoteAlbumId doesnt fire. local rows keep pointing at deleted remote ids.

affects logout (clearLocalData calls reset()) and the server SyncResetV1 path (30 day idle, etc). after re-login, syncLinkedAlbum either silently warns or fires 400s (those are covered by #28299).

null the column manually inside the same transaction. cascade still works for normal SyncAlbumDeleteV1.

verified on pixel 9a with this branch built locally: logged out, deleted album from web, logged back in. without fix linkedRemoteAlbumId stayed dangling. with fix all three local rows have linkedRemoteAlbumId = NULL after the logout reset, and recovery is clean once manageLinkedAlbums runs again.

* fix(mobile): always re-enable foreign_keys in reset() + simplify the update

re-enable foreign_keys inside a try/finally so it always runs even if the transaction throws. without this, a failed reset would leave the connection with foreign_keys = OFF and silently disable cascades for everything after (per copilot review).

also drop the where filter on the linkedRemoteAlbumId update, unconditional update-all is simpler and we wipe everything in reset anyway (per ganka review).
2026-05-12 13:43:15 -05:00
Santo ShakilandGitHub 571e6a8560 chore(mobile): drop deprecated deviceAssetId / deviceId from upload fields (#28384)
server removed both fields from AssetMediaCreateDto in #27818. zod silently strips unknown fields so uploads still work, but we send dead weight on every request.

drop from foreground + background upload paths + share intent path. deviceAssetId stays as the internal background_downloader taskId, just not in the multipart form fields anymore.
2026-05-12 09:12:26 -04:00
Santo ShakilandGitHub 7c6750941e fix(mobile): mounted check before setState in album sync action (#28300)
_manualSyncAlbums fires a setState 1s after sync via Future.delayed
with no mounted check. if the widget is gone by then, setState throws
null check and the global error logger logs it severe.
2026-05-08 18:55:03 +00:00
Santo ShakilandGitHub 238895cad9 fix(mobile): restore notification plugin init (#28284)
#27666 removed LocalNotificationService with the legacy stack, which
was the only place calling FlutterLocalNotificationsPlugin().initialize().
without it, ios never prompts for the notification perm on fresh
installs so background_downloader notifications get dropped silently.

restores the init in the same spot the deleted call used to live.
2026-05-08 10:45:52 +07:00