Add "src:" prefix to search by source ID (mihonapp/mihon#2927)

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)
This commit is contained in:
MajorTanya 2026-02-03 10:54:22 +01:00 committed by Cuong-Tran
parent 696908f94b
commit 0d712e4365
No known key found for this signature in database
GPG key ID: 94EFFE320FE7A47C
3 changed files with 30 additions and 24 deletions

View file

@ -15,6 +15,7 @@ The format is a modified version of [Keep a Changelog](https://keepachangelog.co
- Automatically remove downloads on Suwayomi after reading, configurable via extension settings ([@cpiber](https://github.com/cpiber)) ([#2673](https://github.com/mihonapp/mihon/pull/2673))
- Display author & artist name in MAL search results ([@MajorTanya](https://github.com/MajorTanya)) ([#2833](https://github.com/mihonapp/mihon/pull/2833))
- Add filter options to Updates tab ([@MajorTanya](https://github.com/MajorTanya)) ([#2851](https://github.com/mihonapp/mihon/pull/2851))
- Add `src:` prefix to search the library by source ID ([@MajorTanya](https://github.com/MajorTanya)) ([#2927](https://github.com/mihonapp/mihon/pull/2927))
### Improved
- Minimize memory usage by reducing in-memory cover cache size ([@Lolle2000la](https://github.com/Lolle2000la)) ([#2266](https://github.com/mihonapp/mihon/pull/2266))

View file

@ -20,28 +20,31 @@ data class LibraryItem(
) {
val id: Long = libraryManga.id
// /**
// * Checks if a query matches the manga
// *
// * @param constraint the query to check.
// * @return true if the manga matches the query, false otherwise.
// */
// fun matches(constraint: String): Boolean {
// val sourceName by lazy { sourceManager.getOrStub(libraryManga.manga.source).getNameForMangaInfo() }
// if (constraint.startsWith("id:", true)) {
// return id == constraint.substringAfter("id:").toLongOrNull()
// }
// return libraryManga.manga.title.contains(constraint, true) ||
// (libraryManga.manga.author?.contains(constraint, true) ?: false) ||
// (libraryManga.manga.artist?.contains(constraint, true) ?: false) ||
// (libraryManga.manga.description?.contains(constraint, true) ?: false) ||
// constraint.split(",").map { it.trim() }.all { subconstraint ->
// checkNegatableConstraint(subconstraint) {
// sourceName.contains(it, true) ||
// (libraryManga.manga.genre?.any { genre -> genre.equals(it, true) } ?: false)
// }
// }
// }
// /**
// * Checks if a query matches the manga
// *
// * @param constraint the query to check.
// * @return true if the manga matches the query, false otherwise.
// */
// fun matches(constraint: String): Boolean {
// val source = sourceManager.getOrStub(libraryManga.manga.source)
// val sourceName by lazy { source.getNameForMangaInfo() }
// if (constraint.startsWith("id:", true)) {
// return id == constraint.substringAfter("id:").toLongOrNull()
// } else if (constraint.startsWith("src:", true)) {
// return source.id == constraint.substringAfter("src:").toLongOrNull()
// }
// return libraryManga.manga.title.contains(constraint, true) ||
// (libraryManga.manga.author?.contains(constraint, true) ?: false) ||
// (libraryManga.manga.artist?.contains(constraint, true) ?: false) ||
// (libraryManga.manga.description?.contains(constraint, true) ?: false) ||
// constraint.split(",").map { it.trim() }.all { subconstraint ->
// checkNegatableConstraint(subconstraint) {
// sourceName.contains(it, true) ||
// (libraryManga.manga.genre?.any { genre -> genre.equals(it, true) } ?: false)
// }
// }
// }
// /**
// * Checks a predicate on a negatable constraint. If the constraint starts with a minus character,

View file

@ -1176,10 +1176,12 @@ class LibraryScreenModel(
unfiltered.asFlow().cancellable().filter { item ->
val mangaId = item.libraryManga.manga.id
if (query.startsWith("id:", true)) {
val id = query.substringAfter("id:").toLongOrNull()
return@filter mangaId == id
return@filter mangaId == query.substringAfter("id:").toLongOrNull()
}
val sourceId = item.libraryManga.manga.source
if (query.startsWith("src:", true)) {
return@filter sourceId == query.substringAfter("src:").toLongOrNull()
}
if (isMetadataSource(sourceId) && mangaWithMetaIds.binarySearch(mangaId) >= 0) {
val tags = getSearchTags.await(mangaId)
val titles = getSearchTitles.await(mangaId)