* Update Simple Icons to 16.34.0
The brand paths are unchanged; only the version in the headers moves.
* Use the current Material Symbols names
Several symbols were renamed after the Valkyrie migration. people_alt,
new_releases, screen_lock_*, screen_rotation and stay_current_* are only
aliases in the font now, for group, verified and the mobile_* symbols.
done, push_pin and expand_less/expand_more become check, keep and
keyboard_arrow_up/down, which draw the same or an almost identical glyph.
* Use filled icons where the Material Symbols migration dropped the fill
The migration mapped Filled and Default references to the outline symbols,
but the classic glyph was often solid, and Outlined Warning, Error and
Pause were solid as well. Each call site was compared against the rendered
classic glyph, and the solid ones now use RoundedFilled. view_list needs an
auto-mirrored filled pack. The outline SVGs this leaves unused are removed.
* Show a compact grid icon for the compact display modes
Compact and cover-only grids showed the same view_module icon as the
comfortable grid.
* Generate notification and layout drawables from Material Symbols
Notifications and XML layouts can't use ImageVectors, so they relied on
hand-kept copies of classic Material drawables. A build-logic task now
converts an opt-in list of the module's SVGs with AGP's Svg2Vector into
generated resources. sdk-common is taken from AGP's own dependency metadata,
so its version always matches AGP.
Compose call sites that only needed a drawable (tab close, crop) use the
ImageVectors instead. The icons module's R class must be imported as
MaterialSymbolsR, enforced by spotless, so it isn't mistaken for the app's R.
* Redraw custom icons in the Material Symbols style
The reading mode, crop off, mark previous as read and chapter download
icons were drawn in the classic style. They are rebuilt from Material
Symbols shapes (mobile_gear, mobile_arrow_right/down, crop,
arrow_circle_down, downloading) in a new custom-material-symbols module;
each SVG header lists where its parts come from. The default reading mode
and incognito use mobile_gear and eyeglasses_2 as they are.
ReadingMode holds an ImageVector now, and the module's R class follows the
same alias rule as MaterialSymbolsR.
* Use Material Symbols for the launcher shortcuts
Updates uses release_alert because the symbol named new_releases is now a
check badge.
* Rename the animated icon drawables
anim_*_enter no longer fits now that the icons play in both directions.
This is a pure rename so the following commits show only content changes.
* Use Material Symbols for the bottom navigation icons
The library, updates, history and browse animations are rebuilt from the
outline and filled symbols but keep their original motion: the white inside
is pushed into the ribbon, the "!" and the needle, and the history ring
still spins. Updates uses release_alert, like the shortcut. More already
matches more_horiz and is unchanged.
* Use rounded bars for the manga description caret
The animation is unchanged; the bars get rounded ends to match the
Material Symbols stroke.
* Settle the browse tab icon when selecting and deselecting
The compass turns a full turn and settles with overshoot both ways, instead
of deselecting by playing the select animation backwards. A
rememberAnimatedVectorPainter overload takes separate enter and exit
animations and doesn't animate on the first composition.
* Add Apollo for GraphQL interactions
* Migrate AniList to use Apollo
* Migrate Shikimori to use Apollo
Not all Shikimori requests can be served by their GraphQL API (notably
they do not offer any mutations), so those remain as-is.
* Migrate Suwayomi to use Apollo
Includes leveraging some slightly newer Suwayomi features,
specifically the Double/Float filter fixes first pre-released in
2.1.1985 on 2025-10-26 and first fully released in 2.1.2100 on
2026-05-08.
Considering the tachiyomix 1.6 extension lib changes were added in
Suwayomi 2.3.2223 on 2026-06-30, I think it is fair to depend on such
sorta-recent behaviour.
* Fix temp migration names and leftovers
* Create ApolloResponse.dataOrElse extension
Because Apollo doesn't throw exceptions and instead just provides them
as response attributes, the current ApolloResponse.awaitSuccess() is
useless and will be removed shortly.
This new extension function should wrap the basic handling of an
ApolloResponse object neatly.
Co-authored-by: Mitchell Syer <6090655+Syer10@users.noreply.github.com>
* Use dataOrElse in AnilistApi.kt
* Use dataOrElse in ShikimoriApi.kt
* Use dataOrElse in SuwayomiApi.kt
* Delete obsolete ApolloCall.awaitSuccess
* Migrate Kitsu to use Apollo
Kitsu has some unfortunate edges in its GraphQL API (such as returning
nonstandard bodies which don't play well with Apollo) but this should
be an equivalent implementation.
* Extract a MangaFragment for AniList
This simplifies the queries and the converters (which can now delegate
to the MangaFragment.toTrackSearch() method internally and adjust the
track as needed).
Also move the toALUser converter to AnilistUtils.kt to keep all
converters together.
Added a scalar-mapper for AL's CountryCode type.
* Minor consistency cleanup of the queries
* Store list entry ID not title ID for Shikimori
* Extract common MangaFragment for Shikimori
Also map the ISO8601Date to a Kotlin String in the service config.
* Map Kitsu's ISO8601DateTime to kotlin.time.Instant
Utilises Apollo's own adapter-core library which provides the mapper.
Requires opting in to ExperimentalTime until the library resolves the
outdated annotation.
Co-authored-by: Mitchell Syer <6090655+Syer10@users.noreply.github.com>
* Replace Kitsu TODO comment
So much for STOPSHIP preventing me shipping this...
* Bump Apollo version to 5.1.0
* Bump apollo-adapters-core to 0.8.0
Freshly released just earlier.
This resolves having to opt in to ExperimentalTime.
* Make new utils internal to align with #3908
* Fix leftover issues from merged #3828
This PR restructured the AniList and Kitsu user objects.
* Bump apollo to 5.2.0
* Remove unused attributes from queries
* Allow custom exception handler in dataOrElse
Enables callers to manually handle specific non-200 responses.
Callers MUST close the `ApolloHttpException.body` attached to the
passed exception to avoid resource and socket leaks.
Defaults to current behaviour of (re)throwing the status code with our
HttpException.
Utilized in KitsuApi.kt to specially handle Kitsu sending a 500 error
response when deleting library IDs not actually in a user's library
and falling back to the "throw as HttpException" if it's any other
error response.
* Rethrow networking/IO exceptions
This helps to avoid masking networking problems as "This isn't in your
list" problems.
Currently, the app shows "Failed to connect to ..." when the remote
server is unreachable (e.g. downtime, DNS block, etc) because that's
the message provided by the ConnectException thrown by Android's
network stack.
This change restores that behaviour, approximately.
Not the most elegant solution but it _should_ avoid false-positive
toasts.
---------
Co-authored-by: Mitchell Syer <6090655+Syer10@users.noreply.github.com>
Migration 16 replaces favorite, date_added and favorite_modified_at with one nullable favorite_at. A favorite whose date_added is 0 falls back to favorite_modified_at. Manga.favorite and dateAdded become getters derived from it, and restore merges it by taking the earliest non-zero time.
app no longer touches the database directly. Backup restore's queries move into a new RestoreRepository in :data, which restores a batch of entries all or nothing, stopping between entries if cancelled, as before. The remaining direct calls (excluded scanlators, clear database, backup creation, store and category restore) go through their repositories, and the database bindings move from AppBindings into :data.
* Continuous background color
* Use ImageDecoder instead of Kim
* Only get tag when in dual mode
* Update libs.versions.toml
* Make progress circle smaller and animate progress
* Fix long strip showing the menu at ends
* Replace java.time APIs with kotlin(x).(date)time
kotlinx-datetime explicitly says in its README that it does not cover
i18n, so we have to stick with using their toJavaX converters wherever
we localise dates and times.
Yes, some of these replacements are... questionable. But I wanted to
try and maximise the replacement for now.
* Bump kotlinx-datetime to 0.8.0
* More kotlin.time/kotlinx-datetime replacements
* Remove redundant init block & make attributes val
* Replace new use of java.time.Instant