Skip to content
This repository has been archived by the owner on Nov 7, 2023. It is now read-only.

Commit

Permalink
refactor(search_page): rewrite search page
Browse files Browse the repository at this point in the history
  • Loading branch information
zyrouge committed Dec 29, 2021
1 parent efc70c2 commit cfc1ace
Show file tree
Hide file tree
Showing 8 changed files with 704 additions and 701 deletions.
7 changes: 2 additions & 5 deletions lib/modules/extensions/extensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import 'dart:convert';
import 'dart:io';
import 'package:collection/collection.dart';
import 'package:extensions/extensions.dart';
import 'package:extensions/hetu/helpers/helpers.dart';
import 'package:extensions/utils/html_dom/html_dom.dart';
import 'package:http/http.dart' as http;
import 'package:path/path.dart' as path;
import '../../config/app.dart';
Expand All @@ -19,9 +17,8 @@ extension BaseExtensionUtils on BaseExtension {
abstract class ExtensionsManager {
static late final List<ResolvableExtension> store;

static Map<String, AnimeExtractor> animes = <String, AnimeExtractor>{};

static Map<String, MangaExtractor> mangas = <String, MangaExtractor>{};
static final Map<String, AnimeExtractor> animes = <String, AnimeExtractor>{};
static final Map<String, MangaExtractor> mangas = <String, MangaExtractor>{};

static Future<void> initialize() async {
await ExtensionInternals.initialize(
Expand Down
1 change: 0 additions & 1 deletion lib/ui/components/material_tiles/header.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ class MaterialHeaderTile extends StatelessWidget {
bottom: remToPx(0.4),
),
child: DefaultTextStyle(
textAlign: TextAlign.left,
style: theme.textTheme.subtitle1!.copyWith(
color: theme.primaryColor,
fontWeight: FontWeight.bold,
Expand Down
4 changes: 2 additions & 2 deletions lib/ui/components/trackers/detailed_item.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import '../../../modules/helpers/assets.dart';
import '../../../modules/helpers/ui.dart';
import '../../../modules/trackers/provider.dart';
import '../../../modules/translator/translator.dart';
import '../../pages/search_page/search_page.dart' as search_page;
import '../../pages/search_page/controller.dart';
import '../../router.dart';

typedef OnEditCallback = void Function(DetailedInfo);
Expand Down Expand Up @@ -49,7 +49,7 @@ class _DetailedItemState extends State<DetailedItem> {
Navigator.of(context).pushNamed(
ParsedRouteInfo(
RouteNames.search,
search_page.PageArguments(
SearchPageArguments(
terms: item.title,
pluginType: item.type,
autoSearch: true,
Expand Down
242 changes: 242 additions & 0 deletions lib/ui/pages/search_page/controller.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
import 'package:collection/collection.dart';
import 'package:extensions/extensions.dart';
import 'package:flutter/material.dart';
import '../../../modules/database/database.dart';
import '../../../modules/extensions/extensions.dart';
import '../../../modules/state/stateful_holder.dart';
import '../../../modules/translator/translator.dart';
import '../../models/controller.dart';
import '../../router.dart';
import '../anime_page/controller.dart';
import '../manga_page/controller.dart';

class SearchPageArguments {
SearchPageArguments({
final this.terms,
final this.autoSearch,
final this.pluginType,
final this.pluginId,
});

factory SearchPageArguments.fromJson(final Map<String, String> json) =>
SearchPageArguments(
terms: json['terms'],
autoSearch: json['autoSearch'] == 'true',
pluginType: ExtensionType.values.firstWhereOrNull(
(final ExtensionType x) => x.type == json['pluginType'],
),
pluginId: json['pluginId'],
);

String? terms;
bool? autoSearch;
ExtensionType? pluginType;
String? pluginId;

Map<String, String> toJson() {
final Map<String, String> json = <String, String>{};

if (terms != null) {
json['terms'] = terms!;
}

if (autoSearch != null) {
json['autoSearch'] = autoSearch.toString();
}

if (pluginType != null) {
json['pluginType'] = pluginType!.type;
}

if (pluginId != null) {
json['pluginId'] = pluginId!;
}

return json;
}
}

extension PluginRoutes on ExtensionType {
String get route {
switch (this) {
case ExtensionType.anime:
return RouteNames.animePage;

case ExtensionType.manga:
return RouteNames.mangaPage;
}
}

Map<String, String> constructQuery({
required final String plugin,
required final String src,
}) {
switch (this) {
case ExtensionType.anime:
return AnimePageArguments(src: src, plugin: plugin).toJson();

case ExtensionType.manga:
return MangaPageArguments(src: src, plugin: plugin).toJson();
}
}
}

class CurrentPlugin {
const CurrentPlugin({
required final this.type,
required final this.plugin,
});

final ExtensionType type;
final BaseExtractor plugin;

CurrentPlugin copyWith({
final ExtensionType? type,
final BaseExtractor? plugin,
}) =>
CurrentPlugin(
type: type ?? this.type,
plugin: plugin ?? this.plugin,
);
}

class SearchResult {
const SearchResult({
required final this.info,
required final this.plugin,
});

final SearchInfo info;
final CurrentPlugin plugin;
}

class SearchPageController extends Controller<SearchPageController> {
SearchPageArguments? args;
StatefulValueHolderWithError<List<SearchResult>?> results =
StatefulValueHolderWithError<List<SearchResult>?>(null);

final TextEditingController searchTextController = TextEditingController();
late CurrentPlugin currentPlugin;

@override
Future<void> setup() async {
final CachedPreferencesSchema preferences = CachedPreferencesBox.get();
final ExtensionType type =
preferences.lastSelectedSearch?.lastSelectedType ?? ExtensionType.anime;

BaseExtractor plugin;
switch (type) {
case ExtensionType.anime:
plugin = ExtensionsManager.animes[
preferences.lastSelectedSearch?.lastSelectedAnimePlugin ??
''] ??
ExtensionsManager.animes.values.first;
break;

case ExtensionType.manga:
plugin = ExtensionsManager.mangas[
preferences.lastSelectedSearch?.lastSelectedMangaPlugin ??
''] ??
ExtensionsManager.mangas.values.first;
break;
}

setCurrentPlugin(CurrentPlugin(type: type, plugin: plugin));

await super.setup();
}

@override
Future<void> dispose() async {
searchTextController.dispose();

await super.dispose();
}

Future<void> onInitState(final BuildContext context) async {
args = SearchPageArguments.fromJson(
ParsedRouteInfo.fromSettings(ModalRoute.of(context)!.settings).params,
);

if (args?.pluginType != null) {
BaseExtractor? plugin;
switch (args!.pluginType!) {
case ExtensionType.anime:
plugin = ExtensionsManager.animes[args!.pluginId!];
break;

case ExtensionType.manga:
plugin = ExtensionsManager.mangas[args!.pluginId!];
break;
}

if (plugin != null) {
setCurrentPlugin(
CurrentPlugin(type: args!.pluginType!, plugin: plugin),
);
}
}

if (args?.terms != null) {
searchTextController.value = TextEditingValue(text: args!.terms!);

if (searchTextController.value.text.isNotEmpty &&
(args?.autoSearch ?? false)) {
args!.autoSearch = false;
await search();
}
}
}

Future<void> setCurrentPlugin(final CurrentPlugin plugin) async {
currentPlugin = plugin;

final CachedPreferencesSchema preferences = CachedPreferencesBox.get();

preferences.lastSelectedSearch =
(preferences.lastSelectedSearch ?? const LastSelectedSearchPlugin())
.copyWith(
lastSelectedType: plugin.type,
lastSelectedAnimePlugin:
plugin.type == ExtensionType.anime ? plugin.plugin.id : null,
lastSelectedMangaPlugin:
plugin.type == ExtensionType.manga ? plugin.plugin.id : null,
);

await CachedPreferencesBox.save(preferences);
reassemble();

if (searchTextController.value.text.isNotEmpty &&
(args?.autoSearch ?? false)) {
args!.autoSearch = false;
await search();
}
}

Future<void> search() async {
results.resolving(null);
reassemble();

try {
final List<SearchInfo> searches = await currentPlugin.plugin.search(
searchTextController.text,
Translator.t.locale,
);

results.resolve(
searches
.map(
(final SearchInfo x) => SearchResult(
info: x,
plugin: currentPlugin,
),
)
.toList(),
);
} catch (err, stack) {
results.failUnknown(null, err, stack);
}

reassemble();
}
}

0 comments on commit cfc1ace

Please sign in to comment.