* perf(backup): batch database operations during restore
Reduce overhead by chunking manga and repo restoration into
transactions of 100 entries. Categories now restored in a single
transaction. Optimized DatabaseHandler to reuse existing transaction
contexts instead of creating redundant nested ones.
Changed TransactionElement to internal to allow AndroidDatabaseHandler
to check transaction state from the same package.
* fix(backup): make restore progress and errors thread-safe
Use AtomicInteger for progress and synchronizedList for errors to
prevent race conditions during concurrent restoration coroutines.
* perf(backup): update progress notification only once per chunk
Reduce UI/IPC overhead by moving notification updates out of the inner
loop, triggering them only after each 100-item transaction chunk.
Reduced on my emulator from 46 seconds to 27
* fix: remove invalid awaitAsOne() call on insert() return type
categoriesQueries.insert() returns Long (the inserted row ID), not an
ExecutableQuery<T>, so awaitAsOne() is not applicable.
* fix(feedback): Use `CopyOnWriteArrayList` and kotlin `AtomicInt`, add a changelog entry
Note that using kotlin `AtomicInt` instead of java `AtomicInteger` requires opting into an experimental API.
---------
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
* fix(telemetry): prevent Google Play Services spam notifications
Check for Google Play Services availability before initializing Firebase
to prevent system notifications when GPS is disabled or uninstalled.
- Add GPS availability check using GoogleApiAvailability
- Wrap Firebase initialization in try-catch for additional safety
- Skip Firebase initialization gracefully when GPS unavailable
- Add proper logging for debugging purposes
- Add core.common dependency to telemetry module for logcat support
Fixes#3135
* docs: add changelog entry for Google Play Services notification fix
---------
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
MAL has a concept of "titles waiting for approval". These titles
cannot be added to user lists, but they do show up on the website and
crucially, in search results.
However, trying to add such an "unapproved" title will return a 400
error response with the error "invalid_content".
Previously, the awaitSuccess() call would mean the generic "HTTP 400"
toast would be shown. Now, a dedicated informative error message is
shown instead.
Allows users to search for the exact source ID in their library.
Similar to the Browse > Migrate screen, but filtered in the Library,
where users can take all the usual actions.
Could be used in the future to change the search behaviour of tapping
the source name in the title info view to search by the ID with this
prefix.
* Add Filters to Updates screen
Behaves basically like the filters in the library:
- Unread: Show/Don't show unread chapters
- Downloaded: Show/Don't show downloaded chapters
- Started: Show/Don't show chapters that have some progress but aren't
fully Read
- Bookmarked: Show/Don't show chapters that have been bookmarked
Started behaves differently from its Library counterpart because the
actual manga data is not available at this point in time and I thought
calling getManga for each entry without caching would be a pretty bad
idea.
I have modelled this closely on the filter control flow in the
Library, but I'm sure this can be simplified/adjusted in some way.
* Move most filtering logic to SQL
Unread, Started, and Bookmarked filters are now part of the SQL query.
Download state cannot be filtered in the database so it remains in
Kotlin.
Because the Downloaded filter has to be run in Kotlin, the combine
flow uses the preferences flow twice, once to get the SQL query params
and once for the Kotlin filters (only Downloaded at this time).
* Add "Hide excluded scanlators" to update filters
Based on the work done in #1623 but integrated with the other filters
in this PR. Added the user as a co-author for credit.
Co-authored-by: Dani <17619547+shabnix@users.noreply.github.com>
---------
Co-authored-by: Dani <17619547+shabnix@users.noreply.github.com>