mirror of
https://github.com/venera-app/venera.git
synced 2025-09-27 07:47:24 +00:00
Add an 'All' folder to the local favorites page. Close #335
This commit is contained in:
@@ -234,7 +234,7 @@ class LocalFavoritesManager with ChangeNotifier {
|
|||||||
alter table "$folder"
|
alter table "$folder"
|
||||||
add column translated_tags TEXT;
|
add column translated_tags TEXT;
|
||||||
""");
|
""");
|
||||||
var comics = getAllComics(folder);
|
var comics = getFolderComics(folder);
|
||||||
for (var comic in comics) {
|
for (var comic in comics) {
|
||||||
var translatedTags = _translateTags(comic.tags);
|
var translatedTags = _translateTags(comic.tags);
|
||||||
_db.execute("""
|
_db.execute("""
|
||||||
@@ -349,7 +349,7 @@ class LocalFavoritesManager with ChangeNotifier {
|
|||||||
""").firstOrNull?["min_value"] ?? 0;
|
""").firstOrNull?["min_value"] ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<FavoriteItem> getAllComics(String folder) {
|
List<FavoriteItem> getFolderComics(String folder) {
|
||||||
var rows = _db.select("""
|
var rows = _db.select("""
|
||||||
select * from "$folder"
|
select * from "$folder"
|
||||||
ORDER BY display_order;
|
ORDER BY display_order;
|
||||||
@@ -357,6 +357,17 @@ class LocalFavoritesManager with ChangeNotifier {
|
|||||||
return rows.map((element) => FavoriteItem.fromRow(element)).toList();
|
return rows.map((element) => FavoriteItem.fromRow(element)).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<FavoriteItem> getAllComics() {
|
||||||
|
var res = <FavoriteItem>{};
|
||||||
|
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) {
|
void addTagTo(String folder, String id, String tag) {
|
||||||
_db.execute("""
|
_db.execute("""
|
||||||
update "$folder"
|
update "$folder"
|
||||||
@@ -736,10 +747,10 @@ class LocalFavoritesManager with ChangeNotifier {
|
|||||||
return comics;
|
return comics;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<FavoriteItemWithFolderInfo> search(String keyword) {
|
List<FavoriteItem> search(String keyword) {
|
||||||
var keywordList = keyword.split(" ");
|
var keywordList = keyword.split(" ");
|
||||||
keyword = keywordList.first;
|
keyword = keywordList.first;
|
||||||
var comics = <FavoriteItemWithFolderInfo>[];
|
var comics = <FavoriteItem>{};
|
||||||
for (var table in folderNames) {
|
for (var table in folderNames) {
|
||||||
keyword = "%$keyword%";
|
keyword = "%$keyword%";
|
||||||
var res = _db.select("""
|
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 ?;
|
WHERE name LIKE ? OR author LIKE ? OR tags LIKE ? OR translated_tags LIKE ?;
|
||||||
""", [keyword, keyword, keyword, keyword]);
|
""", [keyword, keyword, keyword, keyword]);
|
||||||
for (var comic in res) {
|
for (var comic in res) {
|
||||||
comics.add(
|
comics.add(FavoriteItem.fromRow(comic));
|
||||||
FavoriteItemWithFolderInfo(FavoriteItem.fromRow(comic), table));
|
|
||||||
}
|
}
|
||||||
if (comics.length > 200) {
|
if (comics.length > 200) {
|
||||||
break;
|
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)) {
|
if (comic.name.contains(keyword)) {
|
||||||
return true;
|
return true;
|
||||||
} else if (comic.author.contains(keyword)) {
|
} else if (comic.author.contains(keyword)) {
|
||||||
@@ -766,12 +780,14 @@ class LocalFavoritesManager with ChangeNotifier {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return comics.where((element) {
|
||||||
for (var i = 1; i < keywordList.length; i++) {
|
for (var i = 1; i < keywordList.length; i++) {
|
||||||
comics =
|
if (!test(element, keywordList[i])) {
|
||||||
comics.where((element) => test(element, keywordList[i])).toList();
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return comics;
|
return true;
|
||||||
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void editTags(String id, String folder, List<String> tags) {
|
void editTags(String id, String folder, List<String> tags) {
|
||||||
|
@@ -133,7 +133,7 @@ void addFavorite(List<Comic> comics) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<List<FavoriteItem>> updateComicsInfo(String folder) async {
|
Future<List<FavoriteItem>> updateComicsInfo(String folder) async {
|
||||||
var comics = LocalFavoritesManager().getAllComics(folder);
|
var comics = LocalFavoritesManager().getFolderComics(folder);
|
||||||
|
|
||||||
Future<void> updateSingleComic(int index) async {
|
Future<void> updateSingleComic(int index) async {
|
||||||
int retry = 3;
|
int retry = 3;
|
||||||
|
@@ -25,7 +25,6 @@ part 'favorite_actions.dart';
|
|||||||
part 'side_bar.dart';
|
part 'side_bar.dart';
|
||||||
part 'local_favorites_page.dart';
|
part 'local_favorites_page.dart';
|
||||||
part 'network_favorites_page.dart';
|
part 'network_favorites_page.dart';
|
||||||
part 'local_search_page.dart';
|
|
||||||
|
|
||||||
const _kLeftBarWidth = 256.0;
|
const _kLeftBarWidth = 256.0;
|
||||||
|
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
part of 'favorites_page.dart';
|
part of 'favorites_page.dart';
|
||||||
|
|
||||||
|
const _localAllFolderLabel = '^_^[%local_all%]^_^';
|
||||||
|
|
||||||
class _LocalFavoritesPage extends StatefulWidget {
|
class _LocalFavoritesPage extends StatefulWidget {
|
||||||
const _LocalFavoritesPage({required this.folder, super.key});
|
const _LocalFavoritesPage({required this.folder, super.key});
|
||||||
|
|
||||||
@@ -31,14 +33,25 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
|
|||||||
|
|
||||||
int? lastSelectedIndex;
|
int? lastSelectedIndex;
|
||||||
|
|
||||||
|
bool get isAllFolder => widget.folder == _localAllFolderLabel;
|
||||||
|
|
||||||
void updateComics() {
|
void updateComics() {
|
||||||
if (keyword.isEmpty) {
|
if (keyword.isEmpty) {
|
||||||
setState(() {
|
setState(() {
|
||||||
comics = LocalFavoritesManager().getAllComics(widget.folder);
|
if (isAllFolder) {
|
||||||
|
comics = LocalFavoritesManager().getAllComics();
|
||||||
|
} else {
|
||||||
|
comics = LocalFavoritesManager().getFolderComics(widget.folder);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setState(() {
|
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
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
favPage = context.findAncestorStateOfType<_FavoritesPageState>()!;
|
favPage = context.findAncestorStateOfType<_FavoritesPageState>()!;
|
||||||
comics = LocalFavoritesManager().getAllComics(widget.folder);
|
if (!isAllFolder) {
|
||||||
|
comics = LocalFavoritesManager().getFolderComics(widget.folder);
|
||||||
var (a, b) = LocalFavoritesManager().findLinked(widget.folder);
|
var (a, b) = LocalFavoritesManager().findLinked(widget.folder);
|
||||||
networkSource = a;
|
networkSource = a;
|
||||||
networkFolder = b;
|
networkFolder = b;
|
||||||
|
} else {
|
||||||
|
comics = LocalFavoritesManager().getAllComics();
|
||||||
|
networkSource = null;
|
||||||
|
networkFolder = null;
|
||||||
|
}
|
||||||
LocalFavoritesManager().addListener(updateComics);
|
LocalFavoritesManager().addListener(updateComics);
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
@@ -113,6 +132,11 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
var title = favPage.folder ?? "Unselected".tl;
|
||||||
|
if (title == _localAllFolderLabel) {
|
||||||
|
title = "All".tl;
|
||||||
|
}
|
||||||
|
|
||||||
Widget body = SmoothCustomScrollView(
|
Widget body = SmoothCustomScrollView(
|
||||||
controller: scrollController,
|
controller: scrollController,
|
||||||
slivers: [
|
slivers: [
|
||||||
@@ -135,10 +159,10 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
|
|||||||
onTap: context.width < _kTwoPanelChangeWidth
|
onTap: context.width < _kTwoPanelChangeWidth
|
||||||
? favPage.showFolderSelector
|
? favPage.showFolderSelector
|
||||||
: null,
|
: null,
|
||||||
child: Text(favPage.folder ?? "Unselected".tl),
|
child: Text(title),
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
if (networkSource != null)
|
if (networkSource != null && !isAllFolder)
|
||||||
Tooltip(
|
Tooltip(
|
||||||
message: "Sync".tl,
|
message: "Sync".tl,
|
||||||
child: Flyout(
|
child: Flyout(
|
||||||
@@ -196,6 +220,7 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
if (!isAllFolder)
|
||||||
MenuButton(
|
MenuButton(
|
||||||
entries: [
|
entries: [
|
||||||
MenuEntry(
|
MenuEntry(
|
||||||
@@ -220,7 +245,8 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
|
|||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}),
|
},
|
||||||
|
),
|
||||||
MenuEntry(
|
MenuEntry(
|
||||||
icon: Icons.reorder,
|
icon: Icons.reorder,
|
||||||
text: "Reorder".tl,
|
text: "Reorder".tl,
|
||||||
@@ -241,7 +267,8 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}),
|
},
|
||||||
|
),
|
||||||
MenuEntry(
|
MenuEntry(
|
||||||
icon: Icons.upload_file,
|
icon: Icons.upload_file,
|
||||||
text: "Export".tl,
|
text: "Export".tl,
|
||||||
@@ -253,7 +280,8 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
|
|||||||
data: utf8.encode(json),
|
data: utf8.encode(json),
|
||||||
filename: "${widget.folder}.json",
|
filename: "${widget.folder}.json",
|
||||||
);
|
);
|
||||||
}),
|
},
|
||||||
|
),
|
||||||
MenuEntry(
|
MenuEntry(
|
||||||
icon: Icons.update,
|
icon: Icons.update,
|
||||||
text: "Update Comics Info".tl,
|
text: "Update Comics Info".tl,
|
||||||
@@ -265,7 +293,8 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}),
|
},
|
||||||
|
),
|
||||||
MenuEntry(
|
MenuEntry(
|
||||||
icon: Icons.delete_outline,
|
icon: Icons.delete_outline,
|
||||||
text: "Delete Folder".tl,
|
text: "Delete Folder".tl,
|
||||||
@@ -284,7 +313,8 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
|
|||||||
favPage.folderList?.updateFolders();
|
favPage.folderList?.updateFolders();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}),
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -330,6 +360,7 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
|
|||||||
icon: Icons.flip,
|
icon: Icons.flip,
|
||||||
text: "Invert Selection".tl,
|
text: "Invert Selection".tl,
|
||||||
onClick: invertSelection),
|
onClick: invertSelection),
|
||||||
|
if (!isAllFolder)
|
||||||
MenuEntry(
|
MenuEntry(
|
||||||
icon: Icons.delete_outline,
|
icon: Icons.delete_outline,
|
||||||
text: "Delete Comic".tl,
|
text: "Delete Comic".tl,
|
||||||
@@ -404,6 +435,7 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> {
|
|||||||
selections: selectedComics,
|
selections: selectedComics,
|
||||||
menuBuilder: (c) {
|
menuBuilder: (c) {
|
||||||
return [
|
return [
|
||||||
|
if (!isAllFolder)
|
||||||
MenuEntry(
|
MenuEntry(
|
||||||
icon: Icons.delete,
|
icon: Icons.delete,
|
||||||
text: "Delete".tl,
|
text: "Delete".tl,
|
||||||
@@ -725,7 +757,7 @@ class _ReorderComicsPageState extends State<_ReorderComicsPage> {
|
|||||||
final _key = GlobalKey();
|
final _key = GlobalKey();
|
||||||
var reorderWidgetKey = UniqueKey();
|
var reorderWidgetKey = UniqueKey();
|
||||||
final _scrollController = ScrollController();
|
final _scrollController = ScrollController();
|
||||||
late var comics = LocalFavoritesManager().getAllComics(widget.name);
|
late var comics = LocalFavoritesManager().getFolderComics(widget.name);
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
|
||||||
static int _floatToInt8(double x) {
|
static int _floatToInt8(double x) {
|
||||||
|
@@ -1,41 +0,0 @@
|
|||||||
part of 'favorites_page.dart';
|
|
||||||
|
|
||||||
class LocalSearchPage extends StatefulWidget {
|
|
||||||
const LocalSearchPage({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<LocalSearchPage> createState() => _LocalSearchPageState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _LocalSearchPageState extends State<LocalSearchPage> {
|
|
||||||
String keyword = '';
|
|
||||||
|
|
||||||
var comics = <FavoriteItemWithFolderInfo>[];
|
|
||||||
|
|
||||||
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;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -102,13 +102,6 @@ class _LeftBarState extends State<_LeftBar> implements FolderList {
|
|||||||
const Spacer(),
|
const Spacer(),
|
||||||
MenuButton(
|
MenuButton(
|
||||||
entries: [
|
entries: [
|
||||||
MenuEntry(
|
|
||||||
icon: Icons.search,
|
|
||||||
text: 'Search'.tl,
|
|
||||||
onClick: () {
|
|
||||||
context.to(() => const LocalSearchPage());
|
|
||||||
},
|
|
||||||
),
|
|
||||||
MenuEntry(
|
MenuEntry(
|
||||||
icon: Icons.add,
|
icon: Icons.add,
|
||||||
text: 'Create Folder'.tl,
|
text: 'Create Folder'.tl,
|
||||||
@@ -140,6 +133,10 @@ class _LeftBarState extends State<_LeftBar> implements FolderList {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
index--;
|
index--;
|
||||||
|
if (index == 0) {
|
||||||
|
return buildLocalFolder(_localAllFolderLabel);
|
||||||
|
}
|
||||||
|
index--;
|
||||||
if (index < folders.length) {
|
if (index < folders.length) {
|
||||||
return buildLocalFolder(folders[index]);
|
return buildLocalFolder(folders[index]);
|
||||||
}
|
}
|
||||||
@@ -214,7 +211,9 @@ class _LeftBarState extends State<_LeftBar> implements FolderList {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.only(left: 16),
|
padding: const EdgeInsets.only(left: 16),
|
||||||
child: Text(name),
|
child: Text(name == _localAllFolderLabel
|
||||||
|
? "All".tl
|
||||||
|
: getFavoriteDataOrNull(name)?.title ?? name),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user