mirror of
https://github.com/venera-app/venera.git
synced 2025-12-16 07:01:16 +00:00
Merge pull request #582 from luckyray-fan/feat-add-filter-local-favorites
feat: 支持过滤阅读完成情况
This commit is contained in:
@@ -47,6 +47,7 @@
|
|||||||
"Move to folder": "移动到文件夹",
|
"Move to folder": "移动到文件夹",
|
||||||
"Copy to folder": "复制到文件夹",
|
"Copy to folder": "复制到文件夹",
|
||||||
"Delete Comic": "删除漫画",
|
"Delete Comic": "删除漫画",
|
||||||
|
"Jump to Detail": "跳转详情",
|
||||||
"Delete @c comics?": "删除 @c 本漫画?",
|
"Delete @c comics?": "删除 @c 本漫画?",
|
||||||
"Add comic source": "添加漫画源",
|
"Add comic source": "添加漫画源",
|
||||||
"Delete comic source '@n' ?": "删除漫画源 '@n' ?",
|
"Delete comic source '@n' ?": "删除漫画源 '@n' ?",
|
||||||
@@ -69,6 +70,9 @@
|
|||||||
"Next": "前进",
|
"Next": "前进",
|
||||||
"Login with webview": "通过网页登录",
|
"Login with webview": "通过网页登录",
|
||||||
"Read": "阅读",
|
"Read": "阅读",
|
||||||
|
"Completed": "已完成",
|
||||||
|
"UnCompleted": "未完成",
|
||||||
|
"Filter reading status": "过滤阅读状态",
|
||||||
"Download": "下载",
|
"Download": "下载",
|
||||||
"Favorite": "收藏",
|
"Favorite": "收藏",
|
||||||
"Comments": "评论",
|
"Comments": "评论",
|
||||||
@@ -464,6 +468,7 @@
|
|||||||
"Move": "移動",
|
"Move": "移動",
|
||||||
"Move to folder": "移動到資料夾",
|
"Move to folder": "移動到資料夾",
|
||||||
"Copy to folder": "複製到資料夾",
|
"Copy to folder": "複製到資料夾",
|
||||||
|
"Jump to Detail": "跳轉詳情",
|
||||||
"Delete Comic": "刪除漫畫",
|
"Delete Comic": "刪除漫畫",
|
||||||
"Delete @c comics?": "刪除 @c 本漫畫?",
|
"Delete @c comics?": "刪除 @c 本漫畫?",
|
||||||
"Add comic source": "添加漫畫源",
|
"Add comic source": "添加漫畫源",
|
||||||
@@ -487,6 +492,9 @@
|
|||||||
"Next": "前進",
|
"Next": "前進",
|
||||||
"Login with webview": "透過網頁登入",
|
"Login with webview": "透過網頁登入",
|
||||||
"Read": "閱讀",
|
"Read": "閱讀",
|
||||||
|
"Completed": "已完成",
|
||||||
|
"UnCompleted": "未完成",
|
||||||
|
"Filter reading status": "過濾閱讀狀態",
|
||||||
"Download": "下載",
|
"Download": "下載",
|
||||||
"Favorite": "收藏",
|
"Favorite": "收藏",
|
||||||
"Comments": "評論",
|
"Comments": "評論",
|
||||||
|
|||||||
@@ -441,7 +441,7 @@ class ImageFavoriteManager with ChangeNotifier {
|
|||||||
for (var comic in comics) {
|
for (var comic in comics) {
|
||||||
count += comic.images.length;
|
count += comic.images.length;
|
||||||
for (var tag in comic.tags) {
|
for (var tag in comic.tags) {
|
||||||
String finalTag = tag;
|
String finalTag = tag.split(":").last;
|
||||||
tagCount[finalTag] = (tagCount[finalTag] ?? 0) + 1;
|
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/comic_type.dart';
|
||||||
import 'package:venera/foundation/consts.dart';
|
import 'package:venera/foundation/consts.dart';
|
||||||
import 'package:venera/foundation/favorites.dart';
|
import 'package:venera/foundation/favorites.dart';
|
||||||
|
import 'package:venera/foundation/history.dart';
|
||||||
import 'package:venera/foundation/local.dart';
|
import 'package:venera/foundation/local.dart';
|
||||||
import 'package:venera/foundation/log.dart';
|
import 'package:venera/foundation/log.dart';
|
||||||
import 'package:venera/foundation/res.dart';
|
import 'package:venera/foundation/res.dart';
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
|
|||||||
|
|
||||||
bool isLoading = false;
|
bool isLoading = false;
|
||||||
|
|
||||||
|
late String readFilterSelect;
|
||||||
|
|
||||||
var searchResults = <FavoriteItem>[];
|
var searchResults = <FavoriteItem>[];
|
||||||
|
|
||||||
void updateSearchResult() {
|
void updateSearchResult() {
|
||||||
@@ -104,6 +106,19 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
|
|||||||
setState(() {});
|
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) {
|
bool matchKeyword(String keyword, FavoriteItem comic) {
|
||||||
var list = keyword.split(" ");
|
var list = keyword.split(" ");
|
||||||
for (var k in list) {
|
for (var k in list) {
|
||||||
@@ -152,6 +167,8 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
readFilterSelect = appdata.implicitData["local_favorites_read_filter"] ??
|
||||||
|
readFilterList[0];
|
||||||
favPage = context.findAncestorStateOfType<_FavoritesPageState>()!;
|
favPage = context.findAncestorStateOfType<_FavoritesPageState>()!;
|
||||||
if (!isAllFolder) {
|
if (!isAllFolder) {
|
||||||
var (a, b) = LocalFavoritesManager().findLinked(widget.folder);
|
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(
|
Tooltip(
|
||||||
message: "Search".tl,
|
message: "Search".tl,
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
@@ -523,7 +565,23 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
|
|||||||
sourceKey: c.sourceKey,
|
sourceKey: c.sourceKey,
|
||||||
),
|
),
|
||||||
enableIOSGesture: false,
|
enableIOSGesture: false,
|
||||||
iosFullScreenGesture: false);
|
iosFullScreenGesture: false,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
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,
|
||||||
|
),
|
||||||
|
enableIOSGesture: false,
|
||||||
|
iosFullScreenGesture: false,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
@@ -570,7 +628,7 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
|
|||||||
)
|
)
|
||||||
else
|
else
|
||||||
SliverGridComics(
|
SliverGridComics(
|
||||||
comics: searchMode ? searchResults : comics,
|
comics: searchMode ? searchResults : filterComics(comics),
|
||||||
selections: selectedComics,
|
selections: selectedComics,
|
||||||
menuBuilder: (c) {
|
menuBuilder: (c) {
|
||||||
return [
|
return [
|
||||||
@@ -1081,3 +1139,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) {
|
if (widget.initialPage != null) {
|
||||||
page = widget.initialPage!;
|
page = widget.initialPage!;
|
||||||
|
if (page < 1) {
|
||||||
|
page = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// mode = ReaderMode.fromKey(appdata.settings['readerMode']);
|
// mode = ReaderMode.fromKey(appdata.settings['readerMode']);
|
||||||
mode = ReaderMode.fromKey(appdata.settings.getReaderSetting(cid, type.sourceKey, 'readerMode'));
|
mode = ReaderMode.fromKey(appdata.settings.getReaderSetting(cid, type.sourceKey, 'readerMode'));
|
||||||
|
|||||||
Reference in New Issue
Block a user