mirror of
https://github.com/venera-app/venera.git
synced 2025-12-15 14:41:15 +00:00
feat: 支持过滤阅读完成情况
This commit is contained in:
@@ -441,7 +441,7 @@ class ImageFavoriteManager with ChangeNotifier {
|
||||
for (var comic in comics) {
|
||||
count += comic.images.length;
|
||||
for (var tag in comic.tags) {
|
||||
String finalTag = tag;
|
||||
String finalTag = tag.split(":").last;
|
||||
tagCount[finalTag] = (tagCount[finalTag] ?? 0) + 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import 'package:venera/foundation/comic_source/comic_source.dart';
|
||||
import 'package:venera/foundation/comic_type.dart';
|
||||
import 'package:venera/foundation/consts.dart';
|
||||
import 'package:venera/foundation/favorites.dart';
|
||||
import 'package:venera/foundation/history.dart';
|
||||
import 'package:venera/foundation/local.dart';
|
||||
import 'package:venera/foundation/log.dart';
|
||||
import 'package:venera/foundation/res.dart';
|
||||
|
||||
@@ -43,6 +43,8 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
|
||||
|
||||
bool isLoading = false;
|
||||
|
||||
late String readFilterSelect;
|
||||
|
||||
var searchResults = <FavoriteItem>[];
|
||||
|
||||
void updateSearchResult() {
|
||||
@@ -104,6 +106,19 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
List<FavoriteItem> filterComics(List<FavoriteItem> curComics) {
|
||||
return curComics.where((comic) {
|
||||
var history =
|
||||
HistoryManager().find(comic.id, ComicType(comic.sourceKey.hashCode));
|
||||
if (readFilterSelect == "UnCompleted") {
|
||||
return history == null || history.page != history.maxPage;
|
||||
} else if (readFilterSelect == "Completed") {
|
||||
return history != null && history.page == history.maxPage;
|
||||
}
|
||||
return true;
|
||||
}).toList();
|
||||
}
|
||||
|
||||
bool matchKeyword(String keyword, FavoriteItem comic) {
|
||||
var list = keyword.split(" ");
|
||||
for (var k in list) {
|
||||
@@ -152,6 +167,8 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
readFilterSelect = appdata.implicitData["local_favorites_read_filter"] ??
|
||||
readFilterList[0];
|
||||
favPage = context.findAncestorStateOfType<_FavoritesPageState>()!;
|
||||
if (!isAllFolder) {
|
||||
var (a, b) = LocalFavoritesManager().findLinked(widget.folder);
|
||||
@@ -320,6 +337,31 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
|
||||
}),
|
||||
),
|
||||
),
|
||||
Tooltip(
|
||||
message: "Filter".tl,
|
||||
child: IconButton(
|
||||
icon: const Icon(Icons.sort_rounded),
|
||||
color: readFilterSelect != readFilterList[0]
|
||||
? context.colorScheme.primaryContainer
|
||||
: null,
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return _LocalFavoritesFilterDialog(
|
||||
initReadFilterSelect: readFilterSelect,
|
||||
updateConfig: (readFilter) {
|
||||
setState(() {
|
||||
readFilterSelect = readFilter;
|
||||
});
|
||||
updateComics();
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
Tooltip(
|
||||
message: "Search".tl,
|
||||
child: IconButton(
|
||||
@@ -454,15 +496,15 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
|
||||
actions: [
|
||||
MenuButton(entries: [
|
||||
if (!isAllFolder)
|
||||
MenuEntry(
|
||||
icon: Icons.drive_file_move,
|
||||
text: "Move to folder".tl,
|
||||
onClick: () => favoriteOption('move')),
|
||||
MenuEntry(
|
||||
icon: Icons.drive_file_move,
|
||||
text: "Move to folder".tl,
|
||||
onClick: () => favoriteOption('move')),
|
||||
if (!isAllFolder)
|
||||
MenuEntry(
|
||||
icon: Icons.copy,
|
||||
text: "Copy to folder".tl,
|
||||
onClick: () => favoriteOption('add')),
|
||||
MenuEntry(
|
||||
icon: Icons.copy,
|
||||
text: "Copy to folder".tl,
|
||||
onClick: () => favoriteOption('add')),
|
||||
MenuEntry(
|
||||
icon: Icons.select_all,
|
||||
text: "Select All".tl,
|
||||
@@ -519,9 +561,21 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
|
||||
onClick: () {
|
||||
final c = selectedComics.keys.first as FavoriteItem;
|
||||
App.rootContext.to(() => ReaderWithLoading(
|
||||
id: c.id,
|
||||
sourceKey: c.sourceKey,
|
||||
));
|
||||
id: c.id,
|
||||
sourceKey: c.sourceKey,
|
||||
));
|
||||
},
|
||||
),
|
||||
if (selectedComics.length == 1)
|
||||
MenuEntry(
|
||||
icon: Icons.arrow_forward_ios,
|
||||
text: "Jump to Detail".tl,
|
||||
onClick: () {
|
||||
final c = selectedComics.keys.first as FavoriteItem;
|
||||
App.mainNavigatorKey?.currentContext?.to(() => ComicPage(
|
||||
id: c.id,
|
||||
sourceKey: c.sourceKey,
|
||||
));
|
||||
},
|
||||
),
|
||||
]),
|
||||
@@ -568,7 +622,7 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
|
||||
)
|
||||
else
|
||||
SliverGridComics(
|
||||
comics: searchMode ? searchResults : comics,
|
||||
comics: searchMode ? searchResults : filterComics(comics),
|
||||
selections: selectedComics,
|
||||
menuBuilder: (c) {
|
||||
return [
|
||||
@@ -1075,3 +1129,78 @@ class _SelectUpdatePageNumState extends State<_SelectUpdatePageNum> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _LocalFavoritesFilterDialog extends StatefulWidget {
|
||||
const _LocalFavoritesFilterDialog({
|
||||
required this.initReadFilterSelect,
|
||||
required this.updateConfig,
|
||||
});
|
||||
|
||||
final String initReadFilterSelect;
|
||||
final Function updateConfig;
|
||||
|
||||
@override
|
||||
State<_LocalFavoritesFilterDialog> createState() =>
|
||||
_LocalFavoritesFilterDialogState();
|
||||
}
|
||||
|
||||
const readFilterList = ['All', 'UnCompleted', 'Completed'];
|
||||
|
||||
class _LocalFavoritesFilterDialogState
|
||||
extends State<_LocalFavoritesFilterDialog> {
|
||||
List<String> optionTypes = ['Filter'];
|
||||
late var readFilter = widget.initReadFilterSelect;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget tabBar = Material(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: AppTabBar(
|
||||
key: PageStorageKey(optionTypes),
|
||||
tabs: optionTypes.map((e) => Tab(text: e.tl, key: Key(e))).toList(),
|
||||
),
|
||||
).paddingTop(context.padding.top);
|
||||
return ContentDialog(
|
||||
content: DefaultTabController(
|
||||
length: 2,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
tabBar,
|
||||
TabViewBody(children: [
|
||||
Column(
|
||||
children: [
|
||||
ListTile(
|
||||
title: Text("Filter reading status".tl),
|
||||
trailing: Select(
|
||||
current: readFilter.tl,
|
||||
values: readFilterList.map((e) => e.tl).toList(),
|
||||
minWidth: 64,
|
||||
onTap: (index) {
|
||||
setState(() {
|
||||
readFilter = readFilterList[index];
|
||||
});
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
]),
|
||||
],
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
FilledButton(
|
||||
onPressed: () {
|
||||
appdata.implicitData["local_favorites_read_filter"] = readFilter;
|
||||
appdata.writeImplicitData();
|
||||
if (mounted) {
|
||||
Navigator.pop(context);
|
||||
widget.updateConfig(readFilter);
|
||||
}
|
||||
},
|
||||
child: Text("Confirm".tl),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,6 +163,9 @@ class _ReaderState extends State<Reader>
|
||||
}
|
||||
if (widget.initialPage != null) {
|
||||
page = widget.initialPage!;
|
||||
if (page < 1) {
|
||||
page = 1;
|
||||
}
|
||||
}
|
||||
// mode = ReaderMode.fromKey(appdata.settings['readerMode']);
|
||||
mode = ReaderMode.fromKey(appdata.settings.getReaderSetting(cid, type.sourceKey, 'readerMode'));
|
||||
|
||||
Reference in New Issue
Block a user