While there are still some nasty corners (multiple shapes of error
response, unhandled error types on their end, etc.), this is a
functional, feature-parity replacement for the JSON:API API we were
using before.
According to the GraphQL docs, searching by title still goes via
Algolia.
No idea why it was originally going via the
addition endpoint but Shikimori's v1 and v2 APIs
have a dedicated endpoint to update a list entry
via PATCH or PUT (interchangeable, both allow
partial payloads).
Splitting off the update path revealed that
findLibManga would return a non-null track, which
in turn causes the update call to fail with a 404
due to `library_id` being null.
After further investigation, I realised that
findLibManga should always return null if the
title is not in the user's library, not just in
refreshes.
Add support for different Kitsu rating scales
Includes a database migration because we have been scaling Kitsu's
2-20 `ratingTwenty` integer value to a 1-10 (step 0.5) value and
stored that in the database.
I'm also "rounding" the values to the next lowest valid one in the
current rating system to mirror Kitsu's behaviour for this. Both Kitsu
and the app keep the misfit value around until the score is otherwise
edited, at which point the interface constrains the user selection to
only valid values (for the current system).
Maybe the RatingSystem data class is overkill, but a previous version
of mine had three constants for each system that had to be manually
associated at each corner. Encapsulating those in a little map of data
classes seemed the more ergonomic solution.
This was included for all other trackers in #3776 but these two had
prefix search before.
It's a small change, but it can go a long way when using `id:` with
copy-pasted IDs from elsewhere which come with starting or trailing
whitespace.
Also added author info for `id:` prefix search results since those hit
the single-series endpoint instead of `/search`, which does not
include author information (I wish it did).
Maybe unintuitive but the info is nice to have when available.
* Add id: prefix search to AniList
* Add id: prefix search to Bangumi
* Add id: prefix search to Kitsu
* Add id: prefix search to MangaUpdates
* Add id: prefix search to Shikimori
* Add id: prefix search to Hikka
Since Hikka doesn't use integer IDs and instead relies solely on a slug system,
users have to supply the slug to the `id:` search (so not `id:123` but
`id:sousou-no-frieren-97e05f` to get the Frieren manga specifically)
It's asymmetrical to the other trackers, but I thought keeping the prefix
consistent was more important than to be true to the tracker's internal
workings.
* Parse MU string IDs as base36 Longs
Turns out that's what the random strings in the URL are.
Co-authored-by: BrutuZ <7104931+BrutuZ@users.noreply.github.com>
* [skip ci] Add Changelog
---------
Co-authored-by: BrutuZ <7104931+BrutuZ@users.noreply.github.com>
* Fix wrong MangaBaka scores for step sizes > 1
We're actually sending the index of the score type in the list, not
the score itself.
Overriding indexToScore solves that issue.
Also refactored the ranges to be constants for consistency.
* Changelog
* Fix Mangabaka dates drifting in negative timezones
This was only partially handled in #3047, but MB returns full datetime
strings with a truncated time component that's always midnight UTC.
So when Mihon then parses the returned dates, it gets the day wrong in
any negative offset timezones.
With this, Mihon now discards the time component and instead takes the
date component + start-of-day in the device timezone.
* Add Changelog
* Fix relative date display
DatePeriod.days provides the number of days in the DatePeriod specifically, not the total number.
LocalDate.daysUntil provides what we were looking for.
* Add Changelog
This has the side effect of forcing the date to something concrete.
For Year-only: 1st of January that year
Ex: 2025 -> 2025-01-01
For Year+Month: 1st of said month
Ex: 2024-11 -> 2024-11-01
MAL allows setting Day+Month and Day+Year, but both of those are sent
as `null` in the API, which means Mihon will not show a date at all.
This has the side effect of Mihon sending up the date as `null` the
next time info is sent to MAL, which will clear the date fields
completely.
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
Init the reader from the view model instead of the activity so it isn't
cancelled by a configuration change mid init, which left the retained
view model half initialized and needsInit() returning false.
Assisted-by: Claude Code:claude-opus-5
- Spoof `Sec-CH-UA` client hints to match the user agent
- Fix `X-Requested-With` spoofing leaking to unrelated callers
- Update default user agent to Chrome 149