* Use & write Year, Month, Day info in ComicInfo
Currently, users can only modify the date Mihon displays in the
chapter list by manipulating the _last modified date_ of the file.
This is obviously inconvenient, especially since the ComicInfo spec
includes Year, Month, and Day fields for this exact purpose.
If present, this reads the date at start of day in the current default
system time zone (which matches how we use Chapter.dateUpload with
relativeDateText, for example).
If Year is not specified, the entire date process is skipped.
If Month is not specified, it is set to January.
If Day is not specified, it is set to the first.
The parsed date (if any) is set as the Chapter's `date_upload` which
is used for display in the app.
Additionally, Mihon now includes this info in the written
ComicInfo.xml file for downloaded chapters. This will be convenient
for many more users, not least of which those who move
source-downloaded chapters to Local Source to read from there.
---
I used kotlinx.datetime because it's what we use for date parsing in
non-i18n places already.
* Changelog
The previous setup had a circular dependency between Injekt
registration and extension loading.
In regard to #3931, I've moved the culprit ExtensionManager out of
Injekt altogether, alongside CoverCache, PreferenceStore and
TrackPreferences, none of which a source needs.
This might also fix the underlying problem of #3947.
I don't have any nonstandard devices available, but this works fine
in an A17 Pixel emulator & on my A14 Xiaomi device.
Looks like the GetContent approach was merely carried over from older
code without being updated to the more modern OpenDocument contract.
* 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
It gets really annoying to use any of them when they have name
collisions. Especially extensions on Track or basic public functions.
Also make some same-file extension function in the MangaUpdates
package method on the class they extended.
I would have done the same for the DTOs themselves but any that are
used on method signatures have to be public and then all their members
also have to be public. We'd end up with a confusing mess of some
internal and some public DTOs, even at the top level (since generics
can be internal to the `dto` package (e.g. with parseAs<...>) but
return annotations cannot be).
* Make tracker Api classes take their tracker's ID
Also made the name consistently `trackerId` since `trackId` can be
confusing in the context of Tracks that also carry several IDs.
Also made the public constants in TrackerManager entirely redundant,
so trackers are all equally getting their ID defined in their
constructor call now.
* Explicitly mark unused Exceptions as such
* Make isExpired method of BGMOAuth data class
As opposed to an extension defined in the same file
* Kavita: thumbnail_url -> thumbnailUrl
With a SerialName annotation of course
* Suwayomi: Remove redundant with(json)
Both of these requests don't use parseAs so this not required.
* Bangumi: Don't recreate OAuth object for storing
* Remove unused attribute from tracker OAuth classes
Mostly `token_type`.
Also removed `user_id` from BGMOAuth and `scope` & `expiresIn` from
MangaBakaOAuth (which already provides `expiresAt`).
* Use kotlin.time durations for token expiry math
Something like `Clock.System.now().plus(1.hours)` is much easier to
read than `System.getEpochMillis() + 3600`.
Also lets us use the `epochSeconds` attribute where the given
timestamps are seconds-resolution.
* Bangumi: Remove redundant apply block
* Kavita: Misc simplifications
* Use parseAs in tracker interceptors
* MAL: Use existing setAuth to store refresh token
* Add continuous min width
* Add dual page flip transition, separate some dual config
* Fix progress on sides for dual
* re-organize and minor fixes
* Reverse pan when vertical and zoom start right
* add flip to single
* Simple page size heuristics for dual selection
* zoom minimum wideness
* Fix continuous page progress
* continuous dynamic cache size
* Update libs.versions.toml
A leftover of what I assume was the v1 API behaviour handling manually
multiplied the `expires` values by 1,000, supposedly to make it a
millisecond value. However, AL tokens have been saved as milliseconds
since at least the v2 API implementation in 2018, so this has made
every expiry comparison ludicrously impossible.
Example:
millisecond timestamp:
1788529931115 (2026-09-04T13:52:11.115Z)
*1,000
1788529931115000 (+58646-04-04T21:45:15Z)
So any expiry comparisons would say "yes this token is still totally
valid", causing Mihon to send expired credentials and AL to respond
with a 401.
With these changes (which include some loosely associated clean-up),
we now correctly identify expired credentials before we attempt any AL
requests & actually show a toast with the "Token expired." error
message for the first time in 8 years or so?
I was able to keep the new ALOAuth shape compatible with
already-serialized data, though whenever a user (re-)links AL from now
on, both the `token_type` and `expiresIn` fields won't exist any more.
Since they had no use in the current code anyway, I don't consider
this a problem.
I took the liberty of adding basic instructions to the error message
but these can't be i18n'd properly so I kept it short and sweet.
---
Side effect of expired credentials is Mihon erasing the token in
storage, meaning AL disappears from the tracker sheet until re-linked.
I would say this is acceptable, but we might see panicked users in
support saying "Mihon deleted my AL links" or something.