diff --git a/lib/foundation/favorites.dart b/lib/foundation/favorites.dart index 0b9f353..ad2baf6 100644 --- a/lib/foundation/favorites.dart +++ b/lib/foundation/favorites.dart @@ -234,7 +234,7 @@ class LocalFavoritesManager with ChangeNotifier { alter table "$folder" add column translated_tags TEXT; """); - var comics = getAllComics(folder); + var comics = getFolderComics(folder); for (var comic in comics) { var translatedTags = _translateTags(comic.tags); _db.execute(""" @@ -349,7 +349,7 @@ class LocalFavoritesManager with ChangeNotifier { """).firstOrNull?["min_value"] ?? 0; } - List getAllComics(String folder) { + List getFolderComics(String folder) { var rows = _db.select(""" select * from "$folder" ORDER BY display_order; @@ -357,6 +357,17 @@ class LocalFavoritesManager with ChangeNotifier { return rows.map((element) => FavoriteItem.fromRow(element)).toList(); } + List getAllComics() { + var res = {}; + for (final folder in folderNames) { + var comics = _db.select(""" + select * from "$folder"; + """); + res.addAll(comics.map((element) => FavoriteItem.fromRow(element))); + } + return res.toList(); + } + void addTagTo(String folder, String id, String tag) { _db.execute(""" update "$folder" @@ -736,10 +747,10 @@ class LocalFavoritesManager with ChangeNotifier { return comics; } - List search(String keyword) { + List search(String keyword) { var keywordList = keyword.split(" "); keyword = keywordList.first; - var comics = []; + var comics = {}; for (var table in folderNames) { keyword = "%$keyword%"; var res = _db.select(""" @@ -747,15 +758,18 @@ class LocalFavoritesManager with ChangeNotifier { WHERE name LIKE ? OR author LIKE ? OR tags LIKE ? OR translated_tags LIKE ?; """, [keyword, keyword, keyword, keyword]); for (var comic in res) { - comics.add( - FavoriteItemWithFolderInfo(FavoriteItem.fromRow(comic), table)); + comics.add(FavoriteItem.fromRow(comic)); } if (comics.length > 200) { break; } } - bool test(FavoriteItemWithFolderInfo comic, String keyword) { + bool test(FavoriteItem comic, String keyword) { + keyword = keyword.trim(); + if (keyword.isEmpty) { + return true; + } if (comic.name.contains(keyword)) { return true; } else if (comic.author.contains(keyword)) { @@ -766,12 +780,14 @@ class LocalFavoritesManager with ChangeNotifier { return false; } - for (var i = 1; i < keywordList.length; i++) { - comics = - comics.where((element) => test(element, keywordList[i])).toList(); - } - - return comics; + return comics.where((element) { + for (var i = 1; i < keywordList.length; i++) { + if (!test(element, keywordList[i])) { + return false; + } + } + return true; + }).toList(); } void editTags(String id, String folder, List tags) { diff --git a/lib/pages/favorites/favorite_actions.dart b/lib/pages/favorites/favorite_actions.dart index 4d466ea..621f474 100644 --- a/lib/pages/favorites/favorite_actions.dart +++ b/lib/pages/favorites/favorite_actions.dart @@ -133,7 +133,7 @@ void addFavorite(List comics) { } Future> updateComicsInfo(String folder) async { - var comics = LocalFavoritesManager().getAllComics(folder); + var comics = LocalFavoritesManager().getFolderComics(folder); Future updateSingleComic(int index) async { int retry = 3; diff --git a/lib/pages/favorites/favorites_page.dart b/lib/pages/favorites/favorites_page.dart index 015c4e0..aa14a64 100644 --- a/lib/pages/favorites/favorites_page.dart +++ b/lib/pages/favorites/favorites_page.dart @@ -25,7 +25,6 @@ part 'favorite_actions.dart'; part 'side_bar.dart'; part 'local_favorites_page.dart'; part 'network_favorites_page.dart'; -part 'local_search_page.dart'; const _kLeftBarWidth = 256.0; diff --git a/lib/pages/favorites/local_favorites_page.dart b/lib/pages/favorites/local_favorites_page.dart index eea258a..a807b08 100644 --- a/lib/pages/favorites/local_favorites_page.dart +++ b/lib/pages/favorites/local_favorites_page.dart @@ -1,5 +1,7 @@ part of 'favorites_page.dart'; +const _localAllFolderLabel = '^_^[%local_all%]^_^'; + class _LocalFavoritesPage extends StatefulWidget { const _LocalFavoritesPage({required this.folder, super.key}); @@ -31,14 +33,25 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> { int? lastSelectedIndex; + bool get isAllFolder => widget.folder == _localAllFolderLabel; + void updateComics() { if (keyword.isEmpty) { setState(() { - comics = LocalFavoritesManager().getAllComics(widget.folder); + if (isAllFolder) { + comics = LocalFavoritesManager().getAllComics(); + } else { + comics = LocalFavoritesManager().getFolderComics(widget.folder); + } }); } else { setState(() { - comics = LocalFavoritesManager().searchInFolder(widget.folder, keyword); + if (isAllFolder) { + comics = LocalFavoritesManager().search(keyword); + } else { + comics = + LocalFavoritesManager().searchInFolder(widget.folder, keyword); + } }); } } @@ -46,10 +59,16 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> { @override void initState() { favPage = context.findAncestorStateOfType<_FavoritesPageState>()!; - comics = LocalFavoritesManager().getAllComics(widget.folder); - var (a, b) = LocalFavoritesManager().findLinked(widget.folder); - networkSource = a; - networkFolder = b; + if (!isAllFolder) { + comics = LocalFavoritesManager().getFolderComics(widget.folder); + var (a, b) = LocalFavoritesManager().findLinked(widget.folder); + networkSource = a; + networkFolder = b; + } else { + comics = LocalFavoritesManager().getAllComics(); + networkSource = null; + networkFolder = null; + } LocalFavoritesManager().addListener(updateComics); super.initState(); } @@ -113,6 +132,11 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> { @override Widget build(BuildContext context) { + var title = favPage.folder ?? "Unselected".tl; + if (title == _localAllFolderLabel) { + title = "All".tl; + } + Widget body = SmoothCustomScrollView( controller: scrollController, slivers: [ @@ -135,10 +159,10 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> { onTap: context.width < _kTwoPanelChangeWidth ? favPage.showFolderSelector : null, - child: Text(favPage.folder ?? "Unselected".tl), + child: Text(title), ), actions: [ - if (networkSource != null) + if (networkSource != null && !isAllFolder) Tooltip( message: "Sync".tl, child: Flyout( @@ -196,9 +220,10 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> { }, ), ), - MenuButton( - entries: [ - MenuEntry( + if (!isAllFolder) + MenuButton( + entries: [ + MenuEntry( icon: Icons.edit_outlined, text: "Rename".tl, onClick: () { @@ -220,8 +245,9 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> { return null; }, ); - }), - MenuEntry( + }, + ), + MenuEntry( icon: Icons.reorder, text: "Reorder".tl, onClick: () { @@ -241,8 +267,9 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> { } }, ); - }), - MenuEntry( + }, + ), + MenuEntry( icon: Icons.upload_file, text: "Export".tl, onClick: () { @@ -253,8 +280,9 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> { data: utf8.encode(json), filename: "${widget.folder}.json", ); - }), - MenuEntry( + }, + ), + MenuEntry( icon: Icons.update, text: "Update Comics Info".tl, onClick: () { @@ -265,8 +293,9 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> { }); } }); - }), - MenuEntry( + }, + ), + MenuEntry( icon: Icons.delete_outline, text: "Delete Folder".tl, color: context.colorScheme.error, @@ -284,9 +313,10 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> { favPage.folderList?.updateFolders(); }, ); - }), - ], - ), + }, + ), + ], + ), ], ) else if (multiSelectMode) @@ -330,22 +360,23 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> { icon: Icons.flip, text: "Invert Selection".tl, onClick: invertSelection), - MenuEntry( - icon: Icons.delete_outline, - text: "Delete Comic".tl, - color: context.colorScheme.error, - onClick: () { - showConfirmDialog( - context: context, - title: "Delete".tl, - content: "Delete @c comics?" - .tlParams({"c": selectedComics.length}), - btnColor: context.colorScheme.error, - onConfirm: () { - _deleteComicWithId(); - }, - ); - }), + if (!isAllFolder) + MenuEntry( + icon: Icons.delete_outline, + text: "Delete Comic".tl, + color: context.colorScheme.error, + onClick: () { + showConfirmDialog( + context: context, + title: "Delete".tl, + content: "Delete @c comics?" + .tlParams({"c": selectedComics.length}), + btnColor: context.colorScheme.error, + onConfirm: () { + _deleteComicWithId(); + }, + ); + }), MenuEntry( icon: Icons.download, text: "Download".tl, @@ -404,17 +435,18 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> { selections: selectedComics, menuBuilder: (c) { return [ - MenuEntry( - icon: Icons.delete, - text: "Delete".tl, - onClick: () { - LocalFavoritesManager().deleteComicWithId( - widget.folder, - c.id, - (c as FavoriteItem).type, - ); - }, - ), + if (!isAllFolder) + MenuEntry( + icon: Icons.delete, + text: "Delete".tl, + onClick: () { + LocalFavoritesManager().deleteComicWithId( + widget.folder, + c.id, + (c as FavoriteItem).type, + ); + }, + ), MenuEntry( icon: Icons.check, text: "Select".tl, @@ -725,7 +757,7 @@ class _ReorderComicsPageState extends State<_ReorderComicsPage> { final _key = GlobalKey(); var reorderWidgetKey = UniqueKey(); final _scrollController = ScrollController(); - late var comics = LocalFavoritesManager().getAllComics(widget.name); + late var comics = LocalFavoritesManager().getFolderComics(widget.name); bool changed = false; static int _floatToInt8(double x) { diff --git a/lib/pages/favorites/local_search_page.dart b/lib/pages/favorites/local_search_page.dart deleted file mode 100644 index f798bc5..0000000 --- a/lib/pages/favorites/local_search_page.dart +++ /dev/null @@ -1,41 +0,0 @@ -part of 'favorites_page.dart'; - -class LocalSearchPage extends StatefulWidget { - const LocalSearchPage({super.key}); - - @override - State createState() => _LocalSearchPageState(); -} - -class _LocalSearchPageState extends State { - String keyword = ''; - - var comics = []; - - late final SearchBarController controller; - - @override - void initState() { - super.initState(); - controller = SearchBarController(onSearch: (text) { - keyword = text; - comics = LocalFavoritesManager().search(keyword); - setState(() {}); - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: SmoothCustomScrollView(slivers: [ - SliverSearchBar(controller: controller), - SliverGridComics( - comics: comics, - badgeBuilder: (c) { - return (c as FavoriteItemWithFolderInfo).folder; - }, - ), - ]), - ); - } -} diff --git a/lib/pages/favorites/side_bar.dart b/lib/pages/favorites/side_bar.dart index f2535bb..71f2c9b 100644 --- a/lib/pages/favorites/side_bar.dart +++ b/lib/pages/favorites/side_bar.dart @@ -102,13 +102,6 @@ class _LeftBarState extends State<_LeftBar> implements FolderList { const Spacer(), MenuButton( entries: [ - MenuEntry( - icon: Icons.search, - text: 'Search'.tl, - onClick: () { - context.to(() => const LocalSearchPage()); - }, - ), MenuEntry( icon: Icons.add, text: 'Create Folder'.tl, @@ -140,6 +133,10 @@ class _LeftBarState extends State<_LeftBar> implements FolderList { ); } index--; + if (index == 0) { + return buildLocalFolder(_localAllFolderLabel); + } + index--; if (index < folders.length) { return buildLocalFolder(folders[index]); } @@ -214,7 +211,9 @@ class _LeftBarState extends State<_LeftBar> implements FolderList { ), ), padding: const EdgeInsets.only(left: 16), - child: Text(name), + child: Text(name == _localAllFolderLabel + ? "All".tl + : getFavoriteDataOrNull(name)?.title ?? name), ), ); }