Skip to content

Commit

Permalink
Add ability to manage search sources. Close #174
Browse files Browse the repository at this point in the history
  • Loading branch information
wgh136 committed Feb 9, 2025
1 parent 17ef17c commit df4263f
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 25 deletions.
6 changes: 4 additions & 2 deletions assets/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,8 @@
"Cloudflare verification required": "需要Cloudflare验证",
"Success": "成功",
"Compressing": "压缩中",
"Exporting": "导出中"
"Exporting": "导出中",
"Search Sources": "搜索源"
},
"zh_TW": {
"Home": "首頁",
Expand Down Expand Up @@ -649,6 +650,7 @@
"Cloudflare verification required": "需要Cloudflare驗證",
"Success": "成功",
"Compressing": "壓縮中",
"Exporting": "匯出中"
"Exporting": "匯出中",
"Search Sources": "搜索源"
}
}
1 change: 1 addition & 0 deletions lib/foundation/appdata.dart
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ class _Settings with ChangeNotifier {
'explore_pages': [],
'categories': [],
'favorites': [],
'searchSources': null,
'showFavoriteStatusOnTile': true,
'showHistoryStatusOnTile': false,
'blockedWords': [],
Expand Down
11 changes: 8 additions & 3 deletions lib/init.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,16 @@ Future<void> init() async {
await ComicSource.init().wait();
await LocalManager().init().wait();
CacheManager().setLimitSize(appdata.settings['cacheSize']);
if (appdata.settings['searchSources'] == null) {
appdata.settings['searchSources'] = ComicSource.all()
.where((e) => e.searchPageData != null)
.map((e) => e.key)
.toList();
}
if (App.isAndroid) {
handleLinks();
}
FlutterError.onError = (details) {
Log.error(
"Unhandled Exception", "${details.exception}\n${details.stack}");
Log.error("Unhandled Exception", "${details.exception}\n${details.stack}");
};
}
}
14 changes: 13 additions & 1 deletion lib/pages/aggregated_search_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import "package:flutter/material.dart";
import 'package:shimmer_animation/shimmer_animation.dart';
import "package:venera/components/components.dart";
import "package:venera/foundation/app.dart";
import "package:venera/foundation/appdata.dart";
import "package:venera/foundation/comic_source/comic_source.dart";
import "package:venera/pages/search_result_page.dart";
import "package:venera/utils/translations.dart";
Expand All @@ -24,7 +25,18 @@ class _AggregatedSearchPageState extends State<AggregatedSearchPage> {

@override
void initState() {
sources = ComicSource.all().where((e) => e.searchPageData != null).toList();
var all = ComicSource.all()
.where((e) => e.searchPageData != null)
.map((e) => e.key)
.toList();
var settings = appdata.settings['searchSources'] as List;
var sources = <String>[];
for (var source in settings) {
if (all.contains(source)) {
sources.add(source);
}
}
this.sources = sources.map((e) => ComicSource.find(e)!).toList();
_keyword = widget.keyword;
controller = SearchBarController(
currentText: widget.keyword,
Expand Down
95 changes: 76 additions & 19 deletions lib/pages/search_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ import 'package:venera/foundation/comic_source/comic_source.dart';
import 'package:venera/foundation/state_controller.dart';
import 'package:venera/pages/aggregated_search_page.dart';
import 'package:venera/pages/search_result_page.dart';
import 'package:venera/pages/settings/settings_page.dart';
import 'package:venera/utils/app_links.dart';
import 'package:venera/utils/ext.dart';
import 'package:venera/utils/tags_translation.dart';
import 'package:venera/utils/translations.dart';

import 'comic_page.dart';
import 'comic_source_page.dart';

class SearchPage extends StatefulWidget {
const SearchPage({super.key});
Expand All @@ -27,8 +29,13 @@ class SearchPage extends StatefulWidget {
class _SearchPageState extends State<SearchPage> {
late final SearchBarController controller;

late List<String> searchSources;

String searchTarget = "";

SearchPageData get currentSearchPageData =>
ComicSource.find(searchTarget)!.searchPageData!;

bool aggregatedSearch = false;

var focusNode = FocusNode();
Expand Down Expand Up @@ -139,31 +146,85 @@ class _SearchPageState extends State<SearchPage> {

@override
void initState() {
findSearchSources();
var defaultSearchTarget = appdata.settings['defaultSearchTarget'];
if (defaultSearchTarget == "_aggregated_") {
aggregatedSearch = true;
searchTarget = ComicSource.all().where((e) => e.searchPageData != null)
.toList().first.key;
} else if (defaultSearchTarget != null &&
ComicSource.find(defaultSearchTarget) != null) {
searchSources.contains(defaultSearchTarget)) {
searchTarget = defaultSearchTarget;
} else {
searchTarget = ComicSource.all().first.key;
}
controller = SearchBarController(
onSearch: search,
);
appdata.settings.addListener(updateSearchSourcesIfNeeded);
super.initState();
}

@override
void dispose() {
focusNode.dispose();
appdata.settings.removeListener(updateSearchSourcesIfNeeded);
super.dispose();
}

void findSearchSources() {
var all = ComicSource.all()
.where((e) => e.searchPageData != null)
.map((e) => e.key)
.toList();
var settings = appdata.settings['searchSources'] as List;
var sources = <String>[];
for (var source in settings) {
if (all.contains(source)) {
sources.add(source);
}
}
searchSources = sources;
if (!searchSources.contains(searchTarget)) {
searchTarget = searchSources.firstOrNull ?? "";
}
}

void updateSearchSourcesIfNeeded() {
var old = searchSources;
findSearchSources();
if (old.isEqualsTo(searchSources)) {
return;
}
setState(() {});
}

void manageSearchSources() {
showPopUpWidget(App.rootContext, setSearchSourcesWidget());
}

Widget buildEmpty() {
var msg = "No Search Sources".tl;
msg += '\n';
VoidCallback onTap;
if (ComicSource.isEmpty) {
msg += "Please add some sources".tl;
onTap = () {
context.to(() => ComicSourcePage());
};
} else {
msg += "Please check your settings".tl;
onTap = manageSearchSources;
}
return NetworkError(
message: msg,
retry: onTap,
withAppbar: true,
buttonText: "Manage".tl,
);
}

@override
Widget build(BuildContext context) {
if (searchSources.isEmpty) {
return buildEmpty();
}
return Scaffold(
body: SmoothCustomScrollView(
slivers: buildSlivers().toList(),
Expand Down Expand Up @@ -192,8 +253,7 @@ class _SearchPageState extends State<SearchPage> {
}

Widget buildSearchTarget() {
var sources =
ComicSource.all().where((e) => e.searchPageData != null).toList();
var sources = searchSources.map((e) => ComicSource.find(e)!).toList();
return SliverToBoxAdapter(
child: Container(
width: double.infinity,
Expand All @@ -205,6 +265,10 @@ class _SearchPageState extends State<SearchPage> {
contentPadding: EdgeInsets.zero,
leading: const Icon(Icons.search),
title: Text("Search in".tl),
trailing: IconButton(
icon: const Icon(Icons.settings),
onPressed: manageSearchSources,
),
),
Wrap(
spacing: 8,
Expand All @@ -231,11 +295,6 @@ class _SearchPageState extends State<SearchPage> {
onChanged: (value) {
setState(() {
aggregatedSearch = value ?? false;
if (!aggregatedSearch &&
appdata.settings['defaultSearchTarget'] ==
"_aggregated_") {
searchTarget = sources.first.key;
}
});
},
),
Expand All @@ -247,9 +306,7 @@ class _SearchPageState extends State<SearchPage> {
}

void useDefaultOptions() {
final searchOptions =
ComicSource.find(searchTarget)!.searchPageData!.searchOptions ??
<SearchOptions>[];
final searchOptions = currentSearchPageData.searchOptions ?? [];
options = searchOptions.map((e) => e.defaultValue).toList();
}

Expand All @@ -260,9 +317,7 @@ class _SearchPageState extends State<SearchPage> {

var children = <Widget>[];

final searchOptions =
ComicSource.find(searchTarget)!.searchPageData!.searchOptions ??
<SearchOptions>[];
final searchOptions = currentSearchPageData.searchOptions ?? [];
if (searchOptions.length != options.length) {
useDefaultOptions();
}
Expand Down Expand Up @@ -396,7 +451,9 @@ class _SearchPageState extends State<SearchPage> {
Text(
subTitle,
style: TextStyle(
fontSize: 14, color: Theme.of(context).colorScheme.outline),
fontSize: 14,
color: Theme.of(context).colorScheme.outline,
),
)
],
),
Expand Down
18 changes: 18 additions & 0 deletions lib/pages/settings/explore_settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ class _ExploreSettingsState extends State<ExploreSettings> {
title: "Network Favorite Pages".tl,
builder: setFavoritesPagesWidget,
).toSliver(),
_PopupWindowSetting(
title: "Search Sources".tl,
builder: setSearchSourcesWidget,
).toSliver(),
_SwitchSetting(
title: "Show favorite status on comic tile".tl,
settingKey: "showFavoriteStatusOnTile",
Expand Down Expand Up @@ -210,4 +214,18 @@ Widget setFavoritesPagesWidget() {
settingsIndex: "favorites",
pages: pages,
);
}

Widget setSearchSourcesWidget() {
var pages = <String, String>{};
for (var c in ComicSource.all()) {
if (c.searchPageData != null) {
pages[c.key] = c.name;
}
}
return _MultiPagesFilter(
title: "Search Sources".tl,
settingsIndex: "searchSources",
pages: pages,
);
}

0 comments on commit df4263f

Please sign in to comment.