mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-03-11 17:25:32 +00:00
Fix #349
Added a checkbox "ignoreFiltersOnSearch" to the library search, so when checked, the whole library will be searched, not just the filtered library (Downloaded, Unwatched/Unread, Started, Bookmarked) + added some comments
This commit is contained in:
parent
1f118184ba
commit
71a6358452
28 changed files with 213 additions and 125 deletions
|
|
@ -8,6 +8,7 @@
|
|||
"open_random_entry": "فتح مدخل عشوائي",
|
||||
"import": "استيراد",
|
||||
"filter": "مرشح",
|
||||
"ignore_filters": "تجاهل مرشح",
|
||||
"downloaded": "تم التحميل",
|
||||
"unread": "غير مقروء",
|
||||
"started": "بدأ",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
"open_random_entry": "Zufälligen Eintrag öffnen",
|
||||
"import": "Importieren",
|
||||
"filter": "Filter",
|
||||
"ignore_filters": "Filter ignorieren",
|
||||
"downloaded": "Heruntergeladen",
|
||||
"unread": "Ungelesen",
|
||||
"unwatched": "Nicht angeschaut",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
"open_random_entry": "Open random entry",
|
||||
"import": "Import",
|
||||
"filter": "Filter",
|
||||
"ignore_filters": "Ignore Filters",
|
||||
"downloaded": "Downloaded",
|
||||
"unread": "Unread",
|
||||
"unwatched": "Unwatched",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
"open_random_entry": "Abrir entrada aleatoria",
|
||||
"import": "Importar",
|
||||
"filter": "Filtrar",
|
||||
"ignore_filters": "Ignorar filtros",
|
||||
"downloaded": "Descargado",
|
||||
"unread": "Sin leer",
|
||||
"started": "Comenzado",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
"open_random_entry": "Abrir entrada aleatoria",
|
||||
"import": "Importar",
|
||||
"filter": "Filtrar",
|
||||
"ignore_filters": "Ignorar filtros",
|
||||
"downloaded": "Descargado",
|
||||
"unread": "Sin leer",
|
||||
"started": "Comenzado",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
"open_random_entry": "Ouvrir une entrée au hasard",
|
||||
"import": "Importer",
|
||||
"filter": "Filtre",
|
||||
"ignore_filters": "Ignorer les filtres",
|
||||
"downloaded": "Téléchargé",
|
||||
"unread": "Non lus",
|
||||
"started": "Commencé",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
"open_random_entry": "Buka Entri Acak",
|
||||
"import": "Impor",
|
||||
"filter": "Filter",
|
||||
"ignore_filters": "Abaikan filter",
|
||||
"downloaded": "Telah Diunduh",
|
||||
"unread": "Belum Dibaca",
|
||||
"started": "Dimulai",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
"open_random_entry": "Apri voce casuale",
|
||||
"import": "Importa",
|
||||
"filter": "Filtro",
|
||||
"ignore_filters": "Ignora filtri",
|
||||
"downloaded": "Scaricato",
|
||||
"unread": "Non letto",
|
||||
"started": "Iniziato",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
"open_random_entry": "Abrir entrada aleatória",
|
||||
"import": "Importar",
|
||||
"filter": "Filtro",
|
||||
"ignore_filters": "Ignorar filtros",
|
||||
"downloaded": "Baixados",
|
||||
"unread": "Não lidos",
|
||||
"started": "Iniciados",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
"open_random_entry": "Abrir entrada aleatória",
|
||||
"import": "Importar",
|
||||
"filter": "Filtro",
|
||||
"ignore_filters": "Ignorar filtros",
|
||||
"downloaded": "Baixado",
|
||||
"unread": "Não lido",
|
||||
"started": "Iniciado",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
"open_random_entry": "Открыть случайную запись",
|
||||
"import": "Импорт",
|
||||
"filter": "Фильтр",
|
||||
"ignore_filters": "Игнорировать фильтры",
|
||||
"downloaded": "Загружено",
|
||||
"unread": "Непрочитанное",
|
||||
"started": "Начато",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
"open_random_entry": "สุ่มอ่าน",
|
||||
"import": "นำเข้า",
|
||||
"filter": "ตัวกรอง",
|
||||
"ignore_filters": "ไม่สนใจตัวกรอง",
|
||||
"downloaded": "ดาวน์โหลดแล้ว",
|
||||
"unread": "ยังไม่อ่าน",
|
||||
"started": "เริ่มแล้ว",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
"open_random_entry": "Rastgele Giriş Aç",
|
||||
"import": "İçe Aktar",
|
||||
"filter": "Filtre",
|
||||
"ignore_filters": "Filtreleri yok say",
|
||||
"downloaded": "İndirildi",
|
||||
"unread": "Okunmamış",
|
||||
"started": "Başladı",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
"open_random_entry": "随机打开条目",
|
||||
"import": "导入",
|
||||
"filter": "筛选",
|
||||
"ignore_filters": "忽略筛选",
|
||||
"downloaded": "已下载",
|
||||
"unread": "未读",
|
||||
"started": "已开始",
|
||||
|
|
|
|||
|
|
@ -165,6 +165,12 @@ abstract class AppLocalizations {
|
|||
/// **'Filter'**
|
||||
String get filter;
|
||||
|
||||
/// No description provided for @ignore_filters.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Ignore Filters'**
|
||||
String get ignore_filters;
|
||||
|
||||
/// No description provided for @downloaded.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ class AppLocalizationsAr extends AppLocalizations {
|
|||
@override
|
||||
String get filter => 'مرشح';
|
||||
|
||||
@override
|
||||
String get ignore_filters => 'تجاهل مرشح';
|
||||
|
||||
@override
|
||||
String get downloaded => 'تم التحميل';
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
@override
|
||||
String get filter => 'Filter';
|
||||
|
||||
@override
|
||||
String get ignore_filters => 'Filter ignorieren';
|
||||
|
||||
@override
|
||||
String get downloaded => 'Heruntergeladen';
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
@override
|
||||
String get filter => 'Filter';
|
||||
|
||||
@override
|
||||
String get ignore_filters => 'Ignore Filters';
|
||||
|
||||
@override
|
||||
String get downloaded => 'Downloaded';
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ class AppLocalizationsEs extends AppLocalizations {
|
|||
@override
|
||||
String get filter => 'Filtrar';
|
||||
|
||||
@override
|
||||
String get ignore_filters => 'Ignorar filtros';
|
||||
|
||||
@override
|
||||
String get downloaded => 'Descargado';
|
||||
|
||||
|
|
@ -1466,6 +1469,9 @@ class AppLocalizationsEs419 extends AppLocalizationsEs {
|
|||
@override
|
||||
String get filter => 'Filtrar';
|
||||
|
||||
@override
|
||||
String get ignore_filters => 'Ignorar filtros';
|
||||
|
||||
@override
|
||||
String get downloaded => 'Descargado';
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||
@override
|
||||
String get filter => 'Filtre';
|
||||
|
||||
@override
|
||||
String get ignore_filters => 'Ignorer les filtres';
|
||||
|
||||
@override
|
||||
String get downloaded => 'Téléchargé';
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ class AppLocalizationsId extends AppLocalizations {
|
|||
@override
|
||||
String get filter => 'Filter';
|
||||
|
||||
@override
|
||||
String get ignore_filters => 'Abaikan filter';
|
||||
|
||||
@override
|
||||
String get downloaded => 'Telah Diunduh';
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
@override
|
||||
String get filter => 'Filtro';
|
||||
|
||||
@override
|
||||
String get ignore_filters => 'Ignora filtri';
|
||||
|
||||
@override
|
||||
String get downloaded => 'Scaricato';
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ class AppLocalizationsPt extends AppLocalizations {
|
|||
@override
|
||||
String get filter => 'Filtro';
|
||||
|
||||
@override
|
||||
String get ignore_filters => 'Ignorar filtros';
|
||||
|
||||
@override
|
||||
String get downloaded => 'Baixados';
|
||||
|
||||
|
|
@ -1466,6 +1469,9 @@ class AppLocalizationsPtBr extends AppLocalizationsPt {
|
|||
@override
|
||||
String get filter => 'Filtro';
|
||||
|
||||
@override
|
||||
String get ignore_filters => 'Ignorar filtros';
|
||||
|
||||
@override
|
||||
String get downloaded => 'Baixado';
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ class AppLocalizationsRu extends AppLocalizations {
|
|||
@override
|
||||
String get filter => 'Фильтр';
|
||||
|
||||
@override
|
||||
String get ignore_filters => 'Игнорировать фильтры';
|
||||
|
||||
@override
|
||||
String get downloaded => 'Загружено';
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ class AppLocalizationsTh extends AppLocalizations {
|
|||
@override
|
||||
String get filter => 'ตัวกรอง';
|
||||
|
||||
@override
|
||||
String get ignore_filters => 'ไม่สนใจตัวกรอง';
|
||||
|
||||
@override
|
||||
String get downloaded => 'ดาวน์โหลดแล้ว';
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
@override
|
||||
String get filter => 'Filtre';
|
||||
|
||||
@override
|
||||
String get ignore_filters => 'Filtreleri yok say';
|
||||
|
||||
@override
|
||||
String get downloaded => 'İndirildi';
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||
@override
|
||||
String get filter => '筛选';
|
||||
|
||||
@override
|
||||
String get ignore_filters => '忽略筛选';
|
||||
|
||||
@override
|
||||
String get downloaded => '已下载';
|
||||
|
||||
|
|
|
|||
|
|
@ -1013,6 +1013,21 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
|||
);
|
||||
}
|
||||
|
||||
bool matchesSearchQuery(Manga manga, String query) {
|
||||
final keywords = query
|
||||
.toLowerCase()
|
||||
.split(',')
|
||||
.map((k) => k.trim())
|
||||
.where((k) => k.isNotEmpty);
|
||||
|
||||
return keywords.any(
|
||||
(keyword) =>
|
||||
(manga.name?.toLowerCase().contains(keyword) ?? false) ||
|
||||
(manga.source?.toLowerCase().contains(keyword) ?? false) ||
|
||||
(manga.genre?.any((g) => g.toLowerCase().contains(keyword)) ?? false),
|
||||
);
|
||||
}
|
||||
|
||||
List<Manga> _filterAndSortManga({
|
||||
required List<Manga> data,
|
||||
required int downloadFilterType,
|
||||
|
|
@ -1022,133 +1037,126 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
|||
required int sortType,
|
||||
}) {
|
||||
List<Manga>? mangas;
|
||||
mangas =
|
||||
data
|
||||
.where((element) {
|
||||
List list = [];
|
||||
if (downloadFilterType == 1) {
|
||||
for (var chap in element.chapters) {
|
||||
final modelChapDownload =
|
||||
isar.downloads.filter().idEqualTo(chap.id).findAllSync();
|
||||
|
||||
if (modelChapDownload.isNotEmpty &&
|
||||
modelChapDownload.first.isDownload == true) {
|
||||
list.add(true);
|
||||
}
|
||||
}
|
||||
return list.isNotEmpty;
|
||||
} else if (downloadFilterType == 2) {
|
||||
for (var chap in element.chapters) {
|
||||
final modelChapDownload =
|
||||
isar.downloads.filter().idEqualTo(chap.id).findAllSync();
|
||||
if (!(modelChapDownload.isNotEmpty &&
|
||||
modelChapDownload.first.isDownload == true)) {
|
||||
list.add(true);
|
||||
}
|
||||
}
|
||||
return list.length == element.chapters.length;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.where((element) {
|
||||
List list = [];
|
||||
if (unreadFilterType == 1 || startedFilterType == 1) {
|
||||
for (var chap in element.chapters) {
|
||||
if (!chap.isRead!) {
|
||||
list.add(true);
|
||||
}
|
||||
}
|
||||
return list.isNotEmpty;
|
||||
} else if (unreadFilterType == 2 || startedFilterType == 2) {
|
||||
final searchQuery = _textEditingController.text;
|
||||
// Skip all filters, just do search
|
||||
if (searchQuery.isNotEmpty && ignoreFiltersOnSearch) {
|
||||
mangas =
|
||||
data
|
||||
.where((element) => matchesSearchQuery(element, searchQuery))
|
||||
.toList();
|
||||
} else {
|
||||
// Apply filters + search
|
||||
mangas =
|
||||
data
|
||||
.where((element) {
|
||||
// Filter by download
|
||||
List list = [];
|
||||
for (var chap in element.chapters) {
|
||||
if (chap.isRead!) {
|
||||
list.add(true);
|
||||
}
|
||||
}
|
||||
return list.length == element.chapters.length;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.where((element) {
|
||||
List list = [];
|
||||
if (bookmarkedFilterType == 1) {
|
||||
for (var chap in element.chapters) {
|
||||
if (chap.isBookmarked!) {
|
||||
list.add(true);
|
||||
}
|
||||
}
|
||||
return list.isNotEmpty;
|
||||
} else if (bookmarkedFilterType == 2) {
|
||||
List list = [];
|
||||
for (var chap in element.chapters) {
|
||||
if (!chap.isBookmarked!) {
|
||||
list.add(true);
|
||||
}
|
||||
}
|
||||
return list.length == element.chapters.length;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.where(
|
||||
(element) =>
|
||||
_textEditingController.text.isNotEmpty
|
||||
? _textEditingController.text
|
||||
.split(",")
|
||||
.any(
|
||||
(keyword) =>
|
||||
element.name!.toLowerCase().contains(
|
||||
_textEditingController.text.toLowerCase(),
|
||||
) ||
|
||||
(element.source != null &&
|
||||
element.source!.toLowerCase().contains(
|
||||
_textEditingController.text.toLowerCase(),
|
||||
)) ||
|
||||
element.genre!.contains(keyword),
|
||||
)
|
||||
: true,
|
||||
)
|
||||
.toList();
|
||||
if (downloadFilterType == 1) {
|
||||
for (var chap in element.chapters) {
|
||||
final modelChapDownload =
|
||||
isar.downloads
|
||||
.filter()
|
||||
.idEqualTo(chap.id)
|
||||
.findAllSync();
|
||||
|
||||
if (sortType == 0) {
|
||||
mangas.sort((a, b) {
|
||||
return a.name!.compareTo(b.name!);
|
||||
});
|
||||
} else if (sortType == 1) {
|
||||
mangas.sort((a, b) {
|
||||
return a.lastRead!.compareTo(b.lastRead!);
|
||||
});
|
||||
} else if (sortType == 2) {
|
||||
mangas.sort((a, b) {
|
||||
return a.lastUpdate?.compareTo(b.lastUpdate ?? 0) ?? 0;
|
||||
});
|
||||
} else if (sortType == 3) {
|
||||
mangas.sort((a, b) {
|
||||
return a.chapters
|
||||
.where((element) => !element.isRead!)
|
||||
.toList()
|
||||
.length
|
||||
.compareTo(
|
||||
b.chapters.where((element) => !element.isRead!).toList().length,
|
||||
);
|
||||
});
|
||||
} else if (sortType == 4) {
|
||||
mangas.sort((a, b) {
|
||||
return a.chapters.length.compareTo(b.chapters.length);
|
||||
});
|
||||
} else if (sortType == 5) {
|
||||
mangas.sort((a, b) {
|
||||
final aChaps = a.chapters;
|
||||
final bChaps = b.chapters;
|
||||
return (aChaps.lastOrNull?.dateUpload ?? "").compareTo(
|
||||
bChaps.lastOrNull?.dateUpload ?? "",
|
||||
);
|
||||
});
|
||||
} else if (sortType == 6) {
|
||||
mangas.sort((a, b) {
|
||||
return a.dateAdded?.compareTo(b.dateAdded ?? 0) ?? 0;
|
||||
});
|
||||
if (modelChapDownload.isNotEmpty &&
|
||||
modelChapDownload.first.isDownload == true) {
|
||||
list.add(true);
|
||||
}
|
||||
}
|
||||
return list.isNotEmpty;
|
||||
} else if (downloadFilterType == 2) {
|
||||
for (var chap in element.chapters) {
|
||||
final modelChapDownload =
|
||||
isar.downloads
|
||||
.filter()
|
||||
.idEqualTo(chap.id)
|
||||
.findAllSync();
|
||||
if (!(modelChapDownload.isNotEmpty &&
|
||||
modelChapDownload.first.isDownload == true)) {
|
||||
list.add(true);
|
||||
}
|
||||
}
|
||||
return list.length == element.chapters.length;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.where((element) {
|
||||
// Filter by unread or started
|
||||
List list = [];
|
||||
if (unreadFilterType == 1 || startedFilterType == 1) {
|
||||
for (var chap in element.chapters) {
|
||||
if (!chap.isRead!) {
|
||||
list.add(true);
|
||||
}
|
||||
}
|
||||
return list.isNotEmpty;
|
||||
} else if (unreadFilterType == 2 || startedFilterType == 2) {
|
||||
List list = [];
|
||||
for (var chap in element.chapters) {
|
||||
if (chap.isRead!) {
|
||||
list.add(true);
|
||||
}
|
||||
}
|
||||
return list.length == element.chapters.length;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.where((element) {
|
||||
// Filter by bookmarked
|
||||
List list = [];
|
||||
if (bookmarkedFilterType == 1) {
|
||||
for (var chap in element.chapters) {
|
||||
if (chap.isBookmarked!) {
|
||||
list.add(true);
|
||||
}
|
||||
}
|
||||
return list.isNotEmpty;
|
||||
} else if (bookmarkedFilterType == 2) {
|
||||
List list = [];
|
||||
for (var chap in element.chapters) {
|
||||
if (!chap.isBookmarked!) {
|
||||
list.add(true);
|
||||
}
|
||||
}
|
||||
return list.length == element.chapters.length;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.where(
|
||||
(element) =>
|
||||
searchQuery.isNotEmpty
|
||||
? matchesSearchQuery(element, searchQuery)
|
||||
: true,
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
// Sorting the data based on selected sort type
|
||||
mangas.sort((a, b) {
|
||||
switch (sortType) {
|
||||
case 0:
|
||||
return a.name!.compareTo(b.name!);
|
||||
case 1:
|
||||
return a.lastRead!.compareTo(b.lastRead!);
|
||||
case 2:
|
||||
return a.lastUpdate?.compareTo(b.lastUpdate ?? 0) ?? 0;
|
||||
case 3:
|
||||
return a.chapters
|
||||
.where((e) => !e.isRead!)
|
||||
.length
|
||||
.compareTo(b.chapters.where((e) => !e.isRead!).length);
|
||||
case 4:
|
||||
return a.chapters.length.compareTo(b.chapters.length);
|
||||
case 5:
|
||||
return (a.chapters.lastOrNull?.dateUpload ?? "").compareTo(
|
||||
b.chapters.lastOrNull?.dateUpload ?? "",
|
||||
);
|
||||
case 6:
|
||||
return a.dateAdded?.compareTo(b.dateAdded ?? 0) ?? 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
return mangas;
|
||||
}
|
||||
|
||||
|
|
@ -1188,7 +1196,9 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
|||
);
|
||||
|
||||
final entries =
|
||||
data.where((e) => !(e.hide ?? false)).toList();
|
||||
data
|
||||
.where((e) => !(e.hide ?? false))
|
||||
.toList();
|
||||
if (entries.isEmpty) {
|
||||
return Text(l10n.library_no_category_exist);
|
||||
}
|
||||
|
|
@ -2043,6 +2053,7 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
|||
return l10n.date_added;
|
||||
}
|
||||
|
||||
bool ignoreFiltersOnSearch = false;
|
||||
PreferredSize _appBar(
|
||||
bool isNotFiltering,
|
||||
bool showNumbersOfItems,
|
||||
|
|
@ -2202,6 +2213,21 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
|||
},
|
||||
icon: const Icon(Icons.search),
|
||||
),
|
||||
if (_isSearch)
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(l10n.ignore_filters),
|
||||
Checkbox(
|
||||
value: ignoreFiltersOnSearch,
|
||||
onChanged: (val) {
|
||||
setState(() {
|
||||
ignoreFiltersOnSearch = val ?? false;
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
IconButton(
|
||||
splashRadius: 20,
|
||||
onPressed: () {
|
||||
|
|
|
|||
Loading…
Reference in a new issue