* ExtensionInstaller: Fix mistakenly canceling unrelated `waitingInstall` & avoid adding duplicate entry to installing `queue`
- Changes the installer queue from a synchronized list to a synchronized set to prevent duplicate entries.
- Updates queue removal logic to remove specific entries instead of using index-based removal.
- Refines `cancelQueue` logic to ensure the active installation is only cancelled if its download ID matches the requested ID.
* Ensure thread-safe access to the installation queue when canceling downloads
* perform haptic before doing action
* Perform haptic feedback call in UI/main thread instead of IO
* Haptic feedback on both cases of long press action
* feat: Add sync events to SyncYomi
Now it will send the events back to `SyncYomi` server and then forward those to the notifications services that are enabled, such as discord, telegram, and etc.
* chore: fix build error.
(cherry picked from commit 2776e411272499eba2f91acfea3cb40dc0d4c622)
* Improve client management and response handling
---------
Co-authored-by: Cuong-Tran <16017808+cuong-tran@users.noreply.github.com>
* Fix extension install/update stuck at pending (mihonapp/mihon#3000)
Co-authored-by: p
(cherry picked from commit 84265febf3ce24d71994ced2b81215f858430d4e)
* Fix lint
* Throw exception when Shizuku shell interface is unavailable during installation instead of silently doing nothing
* Properly close OkHttp response and streams
* Delete temporary extension file if failed to install
* Use ConcurrentHashMap for active jobs and steps to ensure thread safety when managing extension installation states across multiple coroutines.
* Use SupervisorJob to ensure that a failure in one installation job doesn't cancel the entire scope
* Don't use `:` in package name for safer filename
* Throw exception if asset file descriptor fails to open during extension installation
---------
Co-authored-by: Cuong-Tran <16017808+cuong-tran@users.noreply.github.com>
* Fix migration's selected sources order not preserved
(cherry picked from commit 47816d4b218e6a62ef9fcd3097b6b0b8f2f95b17)
* Use indexed map for improved sorting performance
---------
Co-authored-by: Cuong-Tran <16017808+cuong-tran@users.noreply.github.com>
* chore: Refactor selection state management and improve performance across various screens
* **MigrateMangaScreen**: Refactor state management to use a `Set<Long>` of IDs for selection instead of a list of wrapper items.
* **LibraryUpdateErrorScreen**: Simplify `onErrorSelected` signature by removing the unused `userSelected` parameter and clean up related UI components.
* **Performance**: Use `remember(state.selection)` in `MigrateMangaScreen` for efficient selection status lookups.
* **Code Quality**: Fix minor typos (e.g., `inbetweenItem` to `inBetweenItem`) and optimize imports.
* Refactor selection logic to prevent redundant state updates
* Move early exit checks for item selection status outside or to the beginning of state update blocks to avoid unnecessary recompositions.
* Improve safety and correctness of item selection by returning early from state updates when an item index is not found.
* Standardize selection checks across `HistoryScreenModel`, `LibraryUpdateErrorScreenModel`, `MigrateMangaScreenModel`, `UpdatesScreenModel`, and `MangaScreenModel`.
* update selection when migration list got updated
* Update state management to reset selection and loading status on fetch failure
* use remember getUiModel
* update headerIndexes to use remember for state management
* Refactor LibraryUpdateErrorScreen to improve state management
* Move header index calculation from the screen model to the presentation layer.
* Optimize UI model and header index memoization using `remember(state)`.
* Remove redundant `LaunchedEffect` and simplify scroll-to-index logic.
* Refactor LibraryUpdateErrorScreen to enhance state management with derivedStateOf
* fix(trackers-mangadex): Handle nullability in `createMdListTrack`
* Return null instead of throwing exception in initial track creation
* Improve error handling in `createMdListTrack`
* Change exception to return null when track not found
* handle nullability in MangaDex tracking
* feat: split "sync on add" into separate metadata and chapter fetch preferences
* refactor: remove redundant SnackbarHostState and error snackbars when auto sync entries
* clean other languages strings
* feat(migration): Allow skipping smart search for single entry migration
Introduces a "Smart search" setting when migrating a single manga, allowing users to choose between an automated best-match search or manual selection directly.
* ensure manual migration is only triggered once
* Add UI toggle
* refactor pref
* Replace deprecated rememberPlainTooltipPositionProvider
* Remove superfluous when branch
This when is marked as exhaustive.
* Replace deprecated LibrariesContainer call
AboutLibraries now wants us to produce the libraries ourselves.
* Replace deprecated ClipboardManager with Clipboard
Clipboard uses suspend functions, hence the coroutine scope addition.
* Use multi-dollar strs to simplify GraphQL queries
These have been available since Kotlin 2.1.
* Remove various redundant casts & conversions
- WebViewScreenContent: loadingState is in the LoadingState.Loading
branch, no need to cast at all
- Bangumi: username is not modified, make val
- Kavita: token is already a String
- PagerViewerAdapter: insertPageLastPage is already null-checked
- PagerViewerAdapter: use reified filterIsInstance
- ReaderViewModel: chapter IDs are already Longs
- CloudflareInterceptor: webview is smart-cast to non-null here
* Replace deprecated MenuAnchorType
Literally just a typealias for ExposedDropdownMenuAnchorType anyway.
* OptimizeNonSkippingGroups is enabled by default
* Suppress shadowing warning
This is explicitly intentional according to the KDocs.
* Migrate Context Receivers to Context Parameters
Requires changing the compiler arg, but that is part of the migration:
https://blog.jetbrains.com/kotlin/2025/04/update-on-context-parameters
Apparently, the only visible change is that names are required now.
"_" can be used for anonymous context parameters.
* Fix expression bodies with explicit return
Naming conflict resolved by aliasing.
From 2.4/2.5 onward, these will only be allowed with explicit return
types, or have to be turned into a block body. I opted for the latter
since the function is reasonably dense already.
see: https://youtrack.jetbrains.com/issue/KTLC-288
* Suppress deprecation of non-AutoMirrored icons
We use these arrows for navigation in the Upcoming screen.
I strongly doubt the AutoMirrored versions would make sense for our
use-case.
* Explicitly opt-in to new annotation default rules
affects the following annotated value-parameters:
- Preference.SliderPreference.steps (`@IntRange`)
- ReaderViewModel.State.brightnessOverlayValue (`@IntRange`)
- ReadingMode.iconRes (`@DrawableRes`)
- MigrationListScreenModel.Dialog.Progress.progress (`@FloatRange`)
see: https://youtrack.jetbrains.com/issue/KT-73255
see: https://github.com/Kotlin/KEEP/blob/change-defaulting-rule/proposals/annotation-target-in-properties.md
Warning message was the following:
This annotation is currently applied to the value parameter only, but in the future it will also be applied to field.
- To opt in to applying to both value parameter and field, add '-Xannotation-default-target=param-property' to your compiler arguments.
- To keep applying to the value parameter only, use the '@param:' annotation target.
(cherry picked from commit b543bc089a442c5e93b0fb6c83bc4037740b1eb5)
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.
(cherry picked from commit 4e4bdffdf38043418685ab42b177c8476842c83c)
* fix: add support for `EnhancedTracker` to merged sources
* ref: readability
* fix: use only sources specific to the merged title
* fix: don't match using name
* formatting
* don't block, suspend
* Move merged source out of EnhancedTracker
* Extract Injekt
* Return first accepted merged manga
* Move getMergedSources to SourceManager and update usages accordingly
* simplify code
---------
Co-authored-by: Cuong-Tran <cuongtran.tm@gmail.com>
Co-authored-by: Cuong-Tran <16017808+cuong-tran@users.noreply.github.com>
* feat(history): Allow multi-selection and batch reset for history items
* Use chapterId instead of history.id
* use remember getUiModel
* Toolbar selection mode
* cleanup History
* Replace selectedChapterIds with selection for chapter selection state
* Remove userSelected parameter from selection logic and related function signatures
* remove parentheses
* Fix range selection
* longclick on cover too
* disable clear-history button when none-selected
* 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 mihonapp/mihon#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>
---------
* Merge Panorama toggle into Filter diaglog
* Make Panorama toggle persistent and share it with History
* Implement toggleSwitch method for preference management to avoid create new function on every composition
Co-authored-by: Cuong-Tran <16017808+cuong-tran@users.noreply.github.com>
(cherry picked from commit bbe9aa8561360f030072fbc49f79748e71c6535e)