This should be the last "general CHANGELOG.md maintenance" we need.
Future changes (direct commits and PRs) should be strongly encouraged
to update the CHANGELOG.md file with their own contribution when they
happen.
This prefix searches entries in the library based on the ID in the
database. It is a niche feature but could be very helpful in certain
situations, such as a corrupted cover causing a crash that just shows
"🚨 Failed - MangaCover(mangaId=2245, sourceId=1, isMangaFavorite=true, url=, lastModified=0)".
With this prefix search it is possible to find the entry in question
without much hassle.
Notably, the database includes literally anything Mihon has ever seen
from extension and such, even if they weren't added to the collection.
This means that IDs actually present in the collection are not
expected to be purely sequential.
For example, in my emulator, I had two entries in the collection but
the assigned IDs were 5 and 56.
Caused by #1748.
Two different issues actually.
Firstly, the getUsername API call uses the authClient, which uses the
BangumiInterceptor to get the current OAuth data and attach the
Authorization header. However, on login, #1748 did not try to set the
new auth details until after attempting to call getUsername.
This would cause Mihon to think the user was not authenticated with
Bangumi and cancel the process.
This is fixed by having Mihon store the OAuth credentials in the
interceptor first before attempting to call getUsername.
The second issue is a simple trailing dollar sign in the API URL for
the getUsername method. This was removed.
Most if not all other trackers do this too. Technically this causes
some request duplication (since things like the BaseTracker's
setRemoteLastChapterRead fire anyway due to the tracker sheet being
open. But considering the reduced number of requests in other places,
I think this is still acceptable.
This change will allow #1736 to proceed, hopefully.
This theme is mainly geared towards e-Ink displays with limited/no
colour capabilities. Previous themes like Yin & Yang would make heavy
use of greyscale colours which could look off on some devices.
This theme is probably not conformant to Material Design 3 colour
scheme guidelines, but it does boast some amazing WebAIM contrast
ratios (#FFFFFF text on #000000 background gets a ratio of 21:1, vice
versa too).
Initially, this was intended as a purely black and white theme but
some contrast issues arose, such as the download badges (tertiary
background, onTertiary text colour) having the same colour as unread
badges (primary/onPrimary), or the step indicators (stops) not being
visible on sliders (since they use the colours of the opposite state
track (active region stops are the colour of the inactive region track
and vice versa).
To mitigate this, each variant (dark/light) of the theme has one
additional grey mixed in for their tertiary and secondaryContainer
colours each. For the dark variant, this is a #A0A0A0 background for
#000000 text (8.03:1 contrast ratio) and for the light variant, it is
a #505050 background for #FFFFFF text (8.06:1 contrast ratio).
This results in distinct unread vs download badges and visible steps
in the sliders.
---------
Co-authored-by: Sunspark-007 <73711243+Sunspark-007@users.noreply.github.com>
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
This comes with many benefits:
- Starting dates are now available and shown to users
- Lays groundwork to add private tracking for Bangumi, e.g. in #1736
- Mihon makes approximately 2-4 times fewer calls to Bangumi's API
- Simplified interceptor for the access token addition
- v0 does not allow access tokens in the query string
- There is actively maintained documentation for it
Also shrunk the DTOs for Bangumi by removing attributes we have no
use for either now or in the foreseeable future. Volume data remains
in case Mihon wants to ever support volumes. But attributes such as
user avatars, nicknames, data relating to Bangumi's tag & meta-tag
systems, etc. have been removed or just not added to the DTOs.
* Add Infinix system app to list of invalid browsers
`com.transsion.resolver` being picked by the system as a suitable
browser caused a Mihon user with an Infinix device to be unable to
open any links in browsers, including tracker login and opening a
WebView page in a real browser.
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
* Add docstring to DeviceUtil.invalidDefaultBrowsers
---------
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
* Add missing @EncodeDefault annotation to MALOAuth
Similar to the situation with Bangumi, the missing annotation means
kotlinx.serialization would _provide_ the default value upon
instantiation but not serialise it to disk. This means the isExpired()
calculation would effectively rarely/never do its job correctly,
leading to Mihon sending expired tokens to MAL and causing problems
for everyone involved.
Overall, this change _could_ (should) lead to a drastic reduction in
MAL requests failing, leading to users having to relink their MAL
accounts.
Also switched createdAt to be in seconds instead of milliseconds as
all other trackers use seconds for timestamps (except for AniList,
which uses milliseconds but doesn't use a createdAt timestamp anyway).
* Add CHANGELOG.md entry
* Fix Bangumi tracking losing track of login state
kotlinx.serialization does NOT serialize default values (like
createdAt in BGMOAuth.kt), so every time the Bangumi tracker
deserialized the tracker OAuth, createdAt was set to the time of the
read, not the time of issuance.
Separately, BangumiInterceptor did correctly fetch new OAuth
credentials upon detected expiry of the stored credentials and saved
them, but did not use them for the current request (the new
credentials were used for all subsequent requests only). This led to
401 errors from Bangumi because the expired access_token was provided.
A subsequent request using the newly acquired access_token would end
up being successful.
* Add CHANGELOG.md entry
* Add zoned date & time to debug info & logs
This should help distinguish log entries that happened recently and
may be related to crashes from older entries that occurred before now.
* Change logcat date and time output format
After some discussion, it was decided to adjust the logcat date and
time display to include the year and the timezone in the logcat
output. This results in a line start like this:
`2025-01-27 18:37:46.662 +0100`
which follows the following DateTimeFormatter pattern:
`yyyy-MM-dd HH:mm:ss.SSS Z`
* Add CHANGELOG.md entry
* Fix MAL manga cover nullability
If a manga doesn't have a cover, MAL doesn't provide the
`main_picture` element in the API response at all.
* Add CHANGELOG.md entry
* Include Coil's broken hardware bitmap device list
Declares all listed devices as unable to use hardware bitmaps.
Might fix#1541.
* Hide Hardware Bitmap Threshold setting if unusable
This hides the setting from the UI if the user's device in on Coil's
list of devices with problematic hardware bitmap implementations.
Also moved HARDWARE_BITMAP_UNSUPPORTED into the ImageUtil as a
property for more ergonomic access across the project.
* Add missing negation
* Update CHANGELOG.md
* Update CHANGELOG.md
* Needs to be and not or
Also fix typo in CHANGELOG.md
---------
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
Closes#1348.
Specifically adds com.hihonor.android.internal.app to the list of
invalid browsers. It's very similar to the existing entry for Huawei,
so it stands to reason it is the same/similar problem as with Huawei's
internal app.
In short:
- fetch & show actual summary
- fallback to "name" if "name_cn" is empty
- request larger responseGroup to get & display the summary & rating
- add type filter query param to make Bangumi filter, not us
Previously, we only displayed the "name" in the summary area and used
"name_cn" as the entry name. However, "name_cn" (Chinese name) can be
an empty string at times, resulting in an awkward looking search
result list where some, many, or even all the results have no title
displayed and only show the "name" (Japanese name) in the summary
area. This has been solved by using "name" as a fallback value should
"name_cn" be empty.
If a Chinese name is available, the original name is prepended to the
summary with the addition "作品原名:" (meaning "original series title").
By using the "responseGroup=large" query parameter, we can request
the required data we need to display the actual summary for an entry
and the entry's average rating.
The "name" is prepended to the summary contents, if any exist, so it
is still accessible for series identification if a "name_cn" exists
too and was used for the result title.
Adding the "type=1" filter query parameter means Bangumi will only
return entries of type 1 ("book") instead of all types and Mihon
needing to filter, resulting in potentially missed entry matches.
Somehow this specific issue keeps getting flagged by unrelated PRs'
CI runs (but only sometimes? Somehow? Other times the CI run would
succeed with no spotless issues.)
---------
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
This time, the Kitsu API docs are silent on whether this field (or
any other field) can be null/undefined/etc, but it can happen and
caused an error during search and update. This change just ensures the
attribute is nullable and is set to an empty String when it is null.
The API docs and the responses type `ratingTwenty` as a "number" (Int
in Kotlin, it's divided by 2 for a .5 step scale 0-10). It's nullable
because an entry without a user rating returns `null` in that field.
* Migrate tracking APIs to DTOs
Changes the handling of tracker API responses to be parsed to DTOs
instead of doing so "manually" by use of `jsonPrimitive`s and/or
`Json.decodeFromString` invocations.
This greatly simplifies the API response handling.
Renamed constants to SCREAMING_SNAKE_CASE.
Largely tried to name the DTOs in a uniform pattern, with the
tracker's (short) name at the beginning of file and data class names
(ALOAuth instead of OAuth, etc).
With these changes, no area of the code base should be using
`jsonPrimitive` and/or `Json.decodeFromString` anymore.
* Fix wrong types in KitsuAlgoliaSearchItem
This API returns start and end dates as Long and the score as Double.
Kitsu's docs claim they're strings (and they are, when requesting
manga details from Kitsu directly) but the Algolia search results
return Longs and Double, respectively.
* Apply review changes
- Renamed `BangumiX` classes to `BGMX` classes.
- Renamed `toXStatus` and `toXScore` to `toApiStatus` and `toApiScore`
* Handle migration from detekt to spotless
Removed Suppressions added for detekt.
Specifically removed:
- `SwallowedException` where an exception ends as a default value
- `MagicNumber`
- `CyclomaticComplexMethod`
- `TooGenericExceptionThrown`
Also ran spotlessApply which changed SMAddMangaResponse
* Fix Kitsu failing to add series
The `included` attribute seems to only appear when the user already
has the entry in their Kitsu list.
Since both `data` and `included` are required for `firstToTrack`, a
guard clause has been added before all its calls.
* Fix empty Bangumi error when entry doesn't exist
Previously, the non-null assertion (!!) would cause a
NullPointerException and a Toast with
"Bangumi error: " (no message) when the user had removed their list
entry from Bangumi through other means like the website.
Now it will show "Bangumi error: Could not find manga".
This is analogous to the error shown by Kitsu under these
circumstances.
* Fix Shikimori ignoring missing remote entry
The user would see no indication that Shikimori could not properly
refresh the track from the remote. This change causes the error Toast
notification to pop up with the following message
"Shikimori error: Could not find manga".
This is analogous to Kitsu and Bangumi.
* Remove usage of let where not needed
These particular occurrences weren't needed because properties are
directly accessible to further act upon. This neatly simplifies these
clauses.
* Remove missed let
* [skip ci] Add PR or commit refs to CHANGELOG.md
* [skip ci] Update CHANGELOG.md
* [skip ci] Make usernames, PRs, hashes clickable
GFM autolinking for those is not applied to all Markdown documents.
* Change commit style
* [skip ci] Add ref to #1057
---------
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
Both `SetupBackupCreateMigration` and `SetupLibraryUpdateMigration` were
trying to get the `App` class from Injekt which is never provided via
the `AppModule`. Using `Application` instead works since the
`workManager` property used by the respective `setupTask` functions is
an extension property on `Context`.
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
The previous approach would always throw an Exception because
`SimpleDateFormat.format()` expects the input to be of type `Date` or
`Number`, not `String`.
[skip ci] Add MyAnimeList issue autoclose
This rule is intended to automatically close issues that report
problems with linking MAL that would be solved with the standard
solution of updating & changing the default UA.
The RegEx might be too general, but there isn't any neat pattern in
the previously filed issues.
While most Android skins are seemingly able to handle the millisecond
format, the documentation technically specifies seconds. This seems to
be causing issues on Samsung devices using the Samsung Gallery app,
which renders the millisecond timestamps as if they were second ones,
causing the dates to be set at some point in the year 56189.
This change should fix that issue on Samsung devices and have no real
impact on the rest.
* Fix DelayedTrackingUpdateJob spam on update errors
DelayedTrackingUpdateJob would start spamming when it encountered an
error (e.g. a tracker has an issue) and never stop.
This seems to stem from a circular dependency between the Job's
`doWork` and TrackChapter's `await`.
TrackChapter sets up a completely new instance of the
DelayedTrackingUpdateJob if any Exception was thrown during the track
update.
This causes the Job to get replaced (as per the WorkManager's set
ExistingWorkPolicy).
Because of this, the guard clause at the start of doWork would never
trigger, as all instances of the Job would report being the 0th try
(because they were completely new instances).
This simple fix introduces a boolean `isRetry` parameter to
TrackChapter's await method, which is set to `false` by default.
DelayedTrackingUpdateJob however sets this parameter to `true`, which
means TrackChapter won't try to set up the Job again.
* Rename isRetry parameter to setupJobOnFailure
This also inverts the logic, so true & false were swapped.
* Fix repo name used for URL instead of baseUrl
This applies to both the item being shown in the screen as well as the
"copy to clipboard" button. Before, copying a repo url would return
"The Repo Name/index.json.min". This PR fixes that.
* Correct Misunderstanding
Passing the whole ExtensionRepo data class through now, using the name
for display purposes and the baseUrl for copying the URL.
* Refactor the ExtensionRepoService to use DTOs
Slightly refactored the `ExtensionRepoService` so it uses a DTO with
`parseAs` to avoid parsing the JSON response by hand.
The default Json instance Injekt provides here has
`ignoreUnknownKeys` enabled, so the `ExtensionRepoMetaDto` only
specifies the meta key of the response content.
The extension function `toExtensionRepo` allows for mapping the new
DTO to the `domain` `ExtensionRepo` data class.
* Implement feedback
- Removed SerialName of the ExtensionRepoMetaDto property and renamed
it `meta`, same as the incoming attribute.
- Added a more general catch clause that also logs the occurring
Exception
Detekt likes to complain about TooGenericExceptionCaught, hence the
Suppress annotation on the function.
While most Android skins are seemingly able to handle the millisecond
format, the documentation technically specifies seconds. This seems to
be causing issues on Samsung devices using the Samsung Gallery app,
which renders the millisecond timestamps as if they were second ones,
causing the dates to be set at some point in the year 56189.
This change should fix that issue on Samsung devices and have no real
impact on the rest.
* Fix DelayedTrackingUpdateJob spam on update errors
DelayedTrackingUpdateJob would start spamming when it encountered an
error (e.g. a tracker has an issue) and never stop.
This seems to stem from a circular dependency between the Job's
`doWork` and TrackChapter's `await`.
TrackChapter sets up a completely new instance of the
DelayedTrackingUpdateJob if any Exception was thrown during the track
update.
This causes the Job to get replaced (as per the WorkManager's set
ExistingWorkPolicy).
Because of this, the guard clause at the start of doWork would never
trigger, as all instances of the Job would report being the 0th try
(because they were completely new instances).
This simple fix introduces a boolean `isRetry` parameter to
TrackChapter's await method, which is set to `false` by default.
DelayedTrackingUpdateJob however sets this parameter to `true`, which
means TrackChapter won't try to set up the Job again.
* Rename isRetry parameter to setupJobOnFailure
This also inverts the logic, so true & false were swapped.
* Minor refactor of theming when expressions
Avoids triggering detekt's CyclomaticComplexMethod warning because of
too many when branches, which would happen with one more theme being
added in these two locations.
In TachiyomiTheme, the Monet theme is separated because it requires
the current Compose context to function. The other themes do not and
are delegated to a Map.
* Implement requested changes
- moved themeResources out of the ThemingDelegate interface
- replaced single condition when with if expression
* Add click-to-copy extension debug info
Adds some debug info about an extension to the user's clipboard when
tapping the logo/name/package name area at the top of the details
screen. Modeled after the debug info from the About screen.
Closes#168.
* Fix linting failure
* Slight cleanup
* Address detekt
---------
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>