From 8bba523ba6d2db1afe8ef7c974f05cb8abd1ee66 Mon Sep 17 00:00:00 2001 From: kodjodevf <107993382+kodjodevf@users.noreply.github.com> Date: Wed, 12 Apr 2023 14:24:27 +0100 Subject: [PATCH] global search feature --- lib/router/router.dart | 40 +++ lib/services/get_manga_chapter_url.g.dart | 2 +- lib/services/get_manga_detail.dart | 4 +- lib/services/get_manga_detail.g.dart | 18 +- lib/services/get_popular_manga.dart | 2 + lib/services/get_popular_manga.g.dart | 2 +- lib/services/search_manga.dart | 52 ++++ lib/views/browse/browse_screen.dart | 7 + .../browse/extension/extension_lang.dart | 1 - .../widgets/extension_list_tile_widget.dart | 4 - lib/views/browse/global_search_screen.dart | 247 ++++++++++++++++++ lib/views/browse/migrate_screen.dart | 2 +- lib/views/history/history_screen.dart | 58 +++- lib/views/library/library_screen.dart | 3 + .../providers/library_state_provider.g.dart | 2 +- lib/views/library/search_text_form_field.dart | 9 +- .../widgets/library_gridview_widget.dart | 1 - .../widgets/library_listview_widget.dart | 1 - .../manga/detail/manga_reader_detail.dart | 2 +- lib/views/manga/home/manga_home_screen.dart | 2 +- lib/views/manga/home/manga_search_screen.dart | 60 +++-- .../reader_controller_provider.g.dart | 2 +- lib/views/updates/updates_screen.dart | 3 + lib/views/widgets/bottom_text_widget.dart | 10 +- pubspec.lock | 8 - pubspec.yaml | 2 +- 26 files changed, 471 insertions(+), 73 deletions(-) create mode 100644 lib/views/browse/global_search_screen.dart diff --git a/lib/router/router.dart b/lib/router/router.dart index 29914072..a224c244 100644 --- a/lib/router/router.dart +++ b/lib/router/router.dart @@ -6,11 +6,13 @@ import 'package:mangayomi/models/manga_type.dart'; import 'package:mangayomi/models/model_manga.dart'; import 'package:mangayomi/views/browse/browse_screen.dart'; import 'package:mangayomi/views/browse/extension/extension_lang.dart'; +import 'package:mangayomi/views/browse/global_search_screen.dart'; import 'package:mangayomi/views/general/general_screen.dart'; import 'package:mangayomi/views/history/history_screen.dart'; import 'package:mangayomi/views/library/library_screen.dart'; import 'package:mangayomi/views/manga/detail/manga_reader_detail.dart'; import 'package:mangayomi/views/manga/home/manga_home_screen.dart'; +import 'package:mangayomi/views/manga/home/manga_search_screen.dart'; import 'package:mangayomi/views/manga/reader/manga_reader_view.dart'; import 'package:mangayomi/views/more/more_screen.dart'; import 'package:mangayomi/views/more/settings/appearance/appearance_screen.dart'; @@ -177,6 +179,44 @@ class AsyncRouterNotifier extends ChangeNotifier { ); }, ), + GoRoute( + path: "/globalSearch", + name: "globalSearch", + builder: (context, state) { + return const GlobalSearchScreen(); + }, + pageBuilder: (context, state) { + return CustomTransition( + key: state.pageKey, + child: const GlobalSearchScreen(), + ); + }, + ), + GoRoute( + path: "/searchResult", + name: "searchResult", + builder: (context, state) { + final data = state.extra as Map; + return SearchResultScreen( + query: data['query']!, + lang: data['lang']!, + source: data['source']!, + viewOnly: data['viewOnly'], + ); + }, + pageBuilder: (context, state) { + final data = state.extra as Map; + return CustomTransition( + key: state.pageKey, + child: SearchResultScreen( + query: data['query']!, + lang: data['lang']!, + source: data['source']!, + viewOnly: data['viewOnly'], + ), + ); + }, + ), ]; } diff --git a/lib/services/get_manga_chapter_url.g.dart b/lib/services/get_manga_chapter_url.g.dart index 3ebc1d71..349121da 100644 --- a/lib/services/get_manga_chapter_url.g.dart +++ b/lib/services/get_manga_chapter_url.g.dart @@ -7,7 +7,7 @@ part of 'get_manga_chapter_url.dart'; // ************************************************************************** String _$getMangaChapterUrlHash() => - r'a9425fc3bdffdf9d8f50acdd7e58671d8ff41a6a'; + r'b17d3053901db005a4eee673163d2dc78ceb75f4'; /// Copied from Dart SDK class _SystemHash { diff --git a/lib/services/get_manga_detail.dart b/lib/services/get_manga_detail.dart index 9bd16190..f0d7db37 100644 --- a/lib/services/get_manga_detail.dart +++ b/lib/services/get_manga_detail.dart @@ -79,7 +79,7 @@ beautifyChapterName(String? vol, String? chap, String? title, String? lang) { Future getMangaDetail(GetMangaDetailRef ref, {required String imageUrl, required String url, - required String name, + required String title, required String lang, required String source}) async { List genre = []; @@ -604,7 +604,7 @@ Future getMangaDetail(GetMangaDetailRef ref, genre: genre, author: author, description: description, - name: name, + name: title, url: url, source: source, imageUrl: imageUrl, diff --git a/lib/services/get_manga_detail.g.dart b/lib/services/get_manga_detail.g.dart index da7496b2..6badf791 100644 --- a/lib/services/get_manga_detail.g.dart +++ b/lib/services/get_manga_detail.g.dart @@ -6,7 +6,7 @@ part of 'get_manga_detail.dart'; // RiverpodGenerator // ************************************************************************** -String _$getMangaDetailHash() => r'9079556aadc0a4b027620d3c5b75280268c022f8'; +String _$getMangaDetailHash() => r'b312cc1f35a45520a827c87b7be862cf5f67ffb3'; /// Copied from Dart SDK class _SystemHash { @@ -44,14 +44,14 @@ class GetMangaDetailFamily extends Family> { GetMangaDetailProvider call({ required String imageUrl, required String url, - required String name, + required String title, required String lang, required String source, }) { return GetMangaDetailProvider( imageUrl: imageUrl, url: url, - name: name, + title: title, lang: lang, source: source, ); @@ -64,7 +64,7 @@ class GetMangaDetailFamily extends Family> { return call( imageUrl: provider.imageUrl, url: provider.url, - name: provider.name, + title: provider.title, lang: provider.lang, source: provider.source, ); @@ -92,7 +92,7 @@ class GetMangaDetailProvider GetMangaDetailProvider({ required this.imageUrl, required this.url, - required this.name, + required this.title, required this.lang, required this.source, }) : super.internal( @@ -100,7 +100,7 @@ class GetMangaDetailProvider ref, imageUrl: imageUrl, url: url, - name: name, + title: title, lang: lang, source: source, ), @@ -117,7 +117,7 @@ class GetMangaDetailProvider final String imageUrl; final String url; - final String name; + final String title; final String lang; final String source; @@ -126,7 +126,7 @@ class GetMangaDetailProvider return other is GetMangaDetailProvider && other.imageUrl == imageUrl && other.url == url && - other.name == name && + other.title == title && other.lang == lang && other.source == source; } @@ -136,7 +136,7 @@ class GetMangaDetailProvider var hash = _SystemHash.combine(0, runtimeType.hashCode); hash = _SystemHash.combine(hash, imageUrl.hashCode); hash = _SystemHash.combine(hash, url.hashCode); - hash = _SystemHash.combine(hash, name.hashCode); + hash = _SystemHash.combine(hash, title.hashCode); hash = _SystemHash.combine(hash, lang.hashCode); hash = _SystemHash.combine(hash, source.hashCode); diff --git a/lib/services/get_popular_manga.dart b/lib/services/get_popular_manga.dart index aa876b07..3f94dfbc 100644 --- a/lib/services/get_popular_manga.dart +++ b/lib/services/get_popular_manga.dart @@ -1,3 +1,5 @@ +// ignore_for_file: unused_local_variable + import 'dart:async'; import 'dart:convert'; import 'package:http/http.dart' as http; diff --git a/lib/services/get_popular_manga.g.dart b/lib/services/get_popular_manga.g.dart index a49c5485..d02300a3 100644 --- a/lib/services/get_popular_manga.g.dart +++ b/lib/services/get_popular_manga.g.dart @@ -6,7 +6,7 @@ part of 'get_popular_manga.dart'; // RiverpodGenerator // ************************************************************************** -String _$getPopularMangaHash() => r'57e376026390038dbcf96f93b7a2e25a188d3156'; +String _$getPopularMangaHash() => r'cc0567f4659ae10b5e55ccdbb5f5a9560cc09a16'; /// Copied from Dart SDK class _SystemHash { diff --git a/lib/services/search_manga.dart b/lib/services/search_manga.dart index bb83ea1c..04ff6481 100644 --- a/lib/services/search_manga.dart +++ b/lib/services/search_manga.dart @@ -92,7 +92,59 @@ Future searchManga(SearchMangaRef ref, .toList(); } } + /***********/ + /*mangakawaii*/ + /***********/ + else if (source == "mangakawaii") { + final dom = await httpResToDom( + url: + 'https://www.mangakawaii.io/search?query=${query.trim()}&search_type=manga', + headers: {'Accept-Language': 'fr'}); + if (dom + .querySelectorAll( + '#page-content > div > div > ul > li > div.section__list-group-right > div.section__list-group-header > div > h4 > a') + .isNotEmpty) { + final ur = dom + .querySelectorAll( + '#page-content > div > div > ul > li > div.section__list-group-right > div.section__list-group-header > div > h4 > a') + .where((e) => e.attributes.containsKey('href')) + .map((e) => e.attributes['href']) + .toList(); + for (var a in ur) { + url.add(a!); + } + + final nam = dom + .querySelectorAll( + '#page-content > div > div > ul > li > div.section__list-group-right > div.section__list-group-header > div > h4 > a') + .map((e) => e.text) + .toList(); + for (var a in nam) { + name.add(a); + image.add(''); + } + } + } + /***********/ + /*mmrcms*/ + /***********/ + else if (getWpMangTypeSource(source) == TypeSource.mmrcms) { + final response = await http.get( + Uri.parse('${getWpMangaUrl(source)}/search?query=${query.trim()}')); + final rep = jsonDecode(response.body); + for (var ok in rep['suggestions']) { + if (source == 'Read Comics Online') { + url.add('${getWpMangaUrl(source)}/comic/${ok['data']}'); + } else if (source == 'Scan VF') { + url.add('${getWpMangaUrl(source)}/${ok['data']}'); + } else { + url.add('${getWpMangaUrl(source)}/manga/${ok['data']}'); + } + name.add(ok["value"]); + image.add(''); + } + } /***********/ /*mangahere*/ /***********/ diff --git a/lib/views/browse/browse_screen.dart b/lib/views/browse/browse_screen.dart index 4f4f499d..53dbe226 100644 --- a/lib/views/browse/browse_screen.dart +++ b/lib/views/browse/browse_screen.dart @@ -59,6 +59,9 @@ class _BrowseScreenState extends State .toList(); }); }, + onSuffixPressed: () { + _textEditingController.clear(); + }, onPressed: () { setState(() { _isSearch = false; @@ -76,6 +79,10 @@ class _BrowseScreenState extends State setState(() { _isSearch = true; }); + } else if (_tabBarController.index == 0) { + context.push( + '/globalSearch', + ); } }, icon: Icon( diff --git a/lib/views/browse/extension/extension_lang.dart b/lib/views/browse/extension/extension_lang.dart index e0cd4908..bdf9bbe4 100644 --- a/lib/views/browse/extension/extension_lang.dart +++ b/lib/views/browse/extension/extension_lang.dart @@ -73,6 +73,5 @@ class ExtensionsLang extends ConsumerWidget { ); }), ); - ; } } diff --git a/lib/views/browse/extension/widgets/extension_list_tile_widget.dart b/lib/views/browse/extension/widgets/extension_list_tile_widget.dart index 9ca00747..a35fdab3 100644 --- a/lib/views/browse/extension/widgets/extension_list_tile_widget.dart +++ b/lib/views/browse/extension/widgets/extension_list_tile_widget.dart @@ -1,5 +1,3 @@ -import 'dart:developer'; - import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:mangayomi/utils/lang.dart'; @@ -20,7 +18,6 @@ class ExtensionListTileWidget extends StatelessWidget { @override Widget build(BuildContext context) { - // log(logoUrl); return ListTile( onTap: () { onChanged(!value); @@ -59,6 +56,5 @@ class ExtensionListTileWidget extends StatelessWidget { onChanged: (value) { onChanged(value); })); - ; } } diff --git a/lib/views/browse/global_search_screen.dart b/lib/views/browse/global_search_screen.dart new file mode 100644 index 00000000..9f6ee827 --- /dev/null +++ b/lib/views/browse/global_search_screen.dart @@ -0,0 +1,247 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:go_router/go_router.dart'; +import 'package:mangayomi/models/model_manga.dart'; +import 'package:mangayomi/providers/hive_provider.dart'; +import 'package:mangayomi/services/get_manga_detail.dart'; +import 'package:mangayomi/services/search_manga.dart'; +import 'package:mangayomi/source/source_model.dart'; +import 'package:mangayomi/utils/cached_network.dart'; +import 'package:mangayomi/utils/headers.dart'; +import 'package:mangayomi/utils/lang.dart'; +import 'package:mangayomi/views/library/search_text_form_field.dart'; +import 'package:mangayomi/views/manga/home/manga_home_screen.dart'; +import 'package:mangayomi/views/widgets/bottom_text_widget.dart'; +import 'package:mangayomi/views/widgets/manga_image_card_widget.dart'; + +class GlobalSearchScreen extends ConsumerStatefulWidget { + const GlobalSearchScreen({ + super.key, + }); + + @override + ConsumerState createState() => _GlobalSearchScreenState(); +} + +class _GlobalSearchScreenState extends ConsumerState { + String query = ""; + final _textEditingController = TextEditingController(); + @override + Widget build(BuildContext context) { + final sourceList = ref + .watch(hiveBoxMangaSourceProvider) + .values + .where((element) => element.isAdded == true) + .toList(); + return Scaffold( + appBar: AppBar( + leading: Container(), + actions: [ + SeachFormTextField( + onChanged: (value) {}, + onPressed: () { + Navigator.pop(context); + }, + onFieldSubmitted: (value) { + setState(() { + query = value; + }); + }, + onSuffixPressed: () { + _textEditingController.clear(); + setState(() { + query = ""; + }); + }, + controller: _textEditingController, + ) + ], + ), + body: query.isNotEmpty + ? ListView( + children: [ + for (var i = 0; i < sourceList.length; i++) + SizedBox( + height: 230, + child: SourceSearchScreen( + query: query, + source: sourceList[i], + ), + ), + ], + ) + : Container(), + ); + } +} + +class SourceSearchScreen extends ConsumerWidget { + final String query; + + final SourceModel source; + const SourceSearchScreen({ + super.key, + required this.query, + required this.source, + }); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final search = + ref.watch(searchMangaProvider(source: source.sourceName, query: query)); + return Scaffold( + body: SizedBox( + height: 240, + child: Column( + children: [ + ListTile( + dense: true, + onTap: () { + Map data = { + 'query': query, + 'source': source.sourceName, + 'lang': source.lang, + 'viewOnly': true, + }; + context.push('/searchResult', extra: data); + }, + title: Text(source.sourceName), + subtitle: Text( + completeLang(source.lang), + style: const TextStyle(fontSize: 10), + ), + trailing: const Icon(Icons.arrow_forward_sharp), + ), + Flexible( + child: search.when( + loading: () => const Center( + child: CircularProgressIndicator(), + ), + error: (error, stackTrace) => + Center(child: Text(error.toString())), + data: (data) { + if (data.name.isNotEmpty) { + return ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: data.name.length, + itemBuilder: (context, index) { + return MangaGlobalImageCard( + url: data.url[index]!, + name: data.name[index]!, + image: data.image[index]!, + source: source.sourceName, + lang: source.lang, + ); + }, + ); + } + return const Center( + child: Text("No result"), + ); + }), + ), + ], + ), + )); + } +} + +class MangaGlobalImageCard extends ConsumerStatefulWidget { + final String image; + final String url; + final String name; + final String source; + final String lang; + const MangaGlobalImageCard({ + super.key, + required this.url, + required this.name, + required this.image, + required this.source, + required this.lang, + }); + + @override + ConsumerState createState() => + _MangaGlobalImageCardState(); +} + +class _MangaGlobalImageCardState extends ConsumerState + with AutomaticKeepAliveClientMixin { + @override + Widget build(BuildContext context) { + super.build(context); + final getMangaDetail = ref.watch(getMangaDetailProvider( + source: widget.source, + imageUrl: widget.image, + title: widget.name, + url: widget.url, + lang: widget.lang)); + + return getMangaDetail.when( + data: (data) { + return GestureDetector( + onTap: () async { + final modelManga = ModelManga( + imageUrl: data.imageUrl, + name: data.name, + genre: data.genre, + author: data.author, + chapterDate: data.chapterDate, + chapterTitle: data.chapterTitle, + chapterUrl: data.chapterUrl, + status: data.status, + description: data.description, + favorite: false, + link: data.url, + source: data.source, + lang: widget.lang); + if (mounted) { + context.push('/manga-reader/detail', extra: modelManga); + } + }, + child: SizedBox( + width: 90, + child: Column(children: [ + cachedNetworkImage( + headers: headers(data.source!), + imageUrl: data.imageUrl!, + width: 80, + height: 120, + fit: BoxFit.fill), + BottomTextWidget( + fontSize: 12.0, + text: widget.name, + isLoading: true, + isComfortableGrid: true, + ) + ]), + ), + ); + }, + loading: () => SizedBox( + width: 60, + child: Column(children: [ + ClipRRect( + borderRadius: BorderRadius.circular(5), + child: Container( + color: Theme.of(context).cardColor, + width: 80, + height: 120, + ), + ), + BottomTextWidget( + fontSize: 12.0, + text: widget.name, + isLoading: true, + isComfortableGrid: true, + ) + ]), + ), + error: (error, stackTrace) => Center(child: Text(error.toString())), + ); + } + + @override + bool get wantKeepAlive => true; +} diff --git a/lib/views/browse/migrate_screen.dart b/lib/views/browse/migrate_screen.dart index 4bbea76e..1be6e195 100644 --- a/lib/views/browse/migrate_screen.dart +++ b/lib/views/browse/migrate_screen.dart @@ -10,7 +10,7 @@ class MigrateScreen extends StatefulWidget { class _MigrateScreenState extends State { @override Widget build(BuildContext context) { - return Center( + return const Center( child: Text('Migrate'), ); } diff --git a/lib/views/history/history_screen.dart b/lib/views/history/history_screen.dart index 8734e629..94406d97 100644 --- a/lib/views/history/history_screen.dart +++ b/lib/views/history/history_screen.dart @@ -42,7 +42,6 @@ class _HistoryScreenState extends ConsumerState { _isSearch ? SeachFormTextField( onChanged: (value) { - log(value.toString()); setState(() { entriesFilter = entriesData .where((element) => element.modelManga.name! @@ -51,6 +50,9 @@ class _HistoryScreenState extends ConsumerState { .toList(); }); }, + onSuffixPressed: () { + _textEditingController.clear(); + }, onPressed: () { setState(() { _isSearch = false; @@ -69,7 +71,40 @@ class _HistoryScreenState extends ConsumerState { icon: Icon(Icons.search, color: Theme.of(context).hintColor)), IconButton( splashRadius: 20, - onPressed: () {}, + onPressed: () { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: const Text( + "Remove everything", + ), + content: const Text( + 'Are you sure? All history will be lost.'), + actions: [ + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: const Text("Cancel")), + const SizedBox( + width: 15, + ), + TextButton( + onPressed: () { + ref.watch(hiveBoxMangaHistory).clear(); + Navigator.pop(context); + }, + child: const Text("Ok")), + ], + ) + ], + ); + }); + }, icon: Icon(Icons.delete_sweep_outlined, color: Theme.of(context).hintColor)), ], @@ -80,6 +115,7 @@ class _HistoryScreenState extends ConsumerState { valueListenable: ref.watch(hiveBoxMangaHistory).listenable(), builder: (context, value, child) { final entries = value.values.toList(); + entriesData = value.values.toList(); final entriesHistory = _textEditingController.text.isNotEmpty ? entriesFilter : entries; @@ -212,13 +248,14 @@ class _HistoryScreenState extends ConsumerState { builder: (context) { return AlertDialog( title: const Text( - "Delete", + "Remove", ), + content: const Text( + 'This will remove the read date of this chapter. Are you sure?'), actions: [ Row( mainAxisAlignment: - MainAxisAlignment - .spaceAround, + MainAxisAlignment.end, children: [ TextButton( onPressed: () { @@ -226,7 +263,10 @@ class _HistoryScreenState extends ConsumerState { context); }, child: const Text( - "No")), + "Cancel")), + const SizedBox( + width: 15, + ), TextButton( onPressed: () { ref @@ -239,7 +279,7 @@ class _HistoryScreenState extends ConsumerState { context); }, child: const Text( - "Yes")), + "Remove")), ], ) ], @@ -266,7 +306,9 @@ class _HistoryScreenState extends ConsumerState { order: GroupedListOrder.DESC, ); } - return const Center(child: Text("")); + return const Center( + child: Text('Nothing read recently'), + ); }, ), ), diff --git a/lib/views/library/library_screen.dart b/lib/views/library/library_screen.dart index f4cc0d5f..dae643af 100644 --- a/lib/views/library/library_screen.dart +++ b/lib/views/library/library_screen.dart @@ -60,6 +60,9 @@ class _LibraryScreenState extends ConsumerState _textEditingController.clear(); }, controller: _textEditingController, + onSuffixPressed: () { + _textEditingController.clear(); + }, ) : IconButton( splashRadius: 20, diff --git a/lib/views/library/providers/library_state_provider.g.dart b/lib/views/library/providers/library_state_provider.g.dart index da8ccc05..b76afb2d 100644 --- a/lib/views/library/providers/library_state_provider.g.dart +++ b/lib/views/library/providers/library_state_provider.g.dart @@ -24,7 +24,7 @@ final libraryReverseListStateProvider = typedef _$LibraryReverseListState = AutoDisposeNotifier; String _$libraryDisplayTypeStateHash() => - r'e3c78daf9932930aa9df05a2718d087089744522'; + r'2743481e54668fe95294194b62014f9713de2cb8'; /// See also [LibraryDisplayTypeState]. @ProviderFor(LibraryDisplayTypeState) diff --git a/lib/views/library/search_text_form_field.dart b/lib/views/library/search_text_form_field.dart index 089aa2d7..11589090 100644 --- a/lib/views/library/search_text_form_field.dart +++ b/lib/views/library/search_text_form_field.dart @@ -3,12 +3,16 @@ import 'package:flutter/material.dart'; class SeachFormTextField extends StatelessWidget { final Function(String)? onChanged; final VoidCallback onPressed; + final VoidCallback onSuffixPressed; final TextEditingController controller; + final Function(String)? onFieldSubmitted; const SeachFormTextField( {super.key, required this.onChanged, required this.onPressed, - required this.controller}); + required this.controller, + this.onFieldSubmitted, + required this.onSuffixPressed}); @override Widget build(BuildContext context) { @@ -18,6 +22,7 @@ class SeachFormTextField extends StatelessWidget { controller: controller, keyboardType: TextInputType.text, onChanged: onChanged, + onFieldSubmitted: onFieldSubmitted, decoration: InputDecoration( isDense: true, hintText: 'Search...', @@ -28,6 +33,8 @@ class SeachFormTextField extends StatelessWidget { icon: const Icon( Icons.arrow_back, )), + suffixIcon: IconButton( + onPressed: onSuffixPressed, icon: const Icon(Icons.clear)), enabledBorder: const OutlineInputBorder( borderSide: BorderSide.none, ), diff --git a/lib/views/library/widgets/library_gridview_widget.dart b/lib/views/library/widgets/library_gridview_widget.dart index 09ef13e0..c89510de 100644 --- a/lib/views/library/widgets/library_gridview_widget.dart +++ b/lib/views/library/widgets/library_gridview_widget.dart @@ -85,6 +85,5 @@ class LibraryGridViewWidget extends StatelessWidget { ); }, ); - ; } } diff --git a/lib/views/library/widgets/library_listview_widget.dart b/lib/views/library/widgets/library_listview_widget.dart index 7a018095..ea026c05 100644 --- a/lib/views/library/widgets/library_listview_widget.dart +++ b/lib/views/library/widgets/library_listview_widget.dart @@ -82,6 +82,5 @@ class LibraryListViewWidget extends StatelessWidget { ); }, ); - ; } } diff --git a/lib/views/manga/detail/manga_reader_detail.dart b/lib/views/manga/detail/manga_reader_detail.dart index 3ad414e2..bfa4f8a6 100644 --- a/lib/views/manga/detail/manga_reader_detail.dart +++ b/lib/views/manga/detail/manga_reader_detail.dart @@ -43,7 +43,7 @@ class _MangaReaderDetailState extends ConsumerState { .watch(getMangaDetailProvider( imageUrl: '', lang: widget.modelManga.lang!, - name: widget.modelManga.name!, + title: widget.modelManga.name!, source: widget.modelManga.source!, url: widget.modelManga.link!) .future) diff --git a/lib/views/manga/home/manga_home_screen.dart b/lib/views/manga/home/manga_home_screen.dart index 99bc516a..3f113da0 100644 --- a/lib/views/manga/home/manga_home_screen.dart +++ b/lib/views/manga/home/manga_home_screen.dart @@ -160,7 +160,7 @@ class _MangaHomeImageCardState extends ConsumerState final getMangaDetail = ref.watch(getMangaDetailProvider( source: widget.source, imageUrl: widget.image, - name: widget.name, + title: widget.name, url: widget.url, lang: widget.lang)); diff --git a/lib/views/manga/home/manga_search_screen.dart b/lib/views/manga/home/manga_search_screen.dart index ba0e725c..34724bca 100644 --- a/lib/views/manga/home/manga_search_screen.dart +++ b/lib/views/manga/home/manga_search_screen.dart @@ -52,7 +52,7 @@ class CustomSearchDelegate extends SearchDelegate { return const Center(child: Text("Empty")); } - return SearchResult( + return SearchResultScreen( query: query, source: source, lang: lang, @@ -86,43 +86,51 @@ class CustomSearchDelegate extends SearchDelegate { } } -class SearchResult extends ConsumerWidget { +class SearchResultScreen extends ConsumerWidget { final String query; final String source; final String lang; - const SearchResult({ + final bool viewOnly; + const SearchResultScreen({ super.key, required this.query, required this.source, required this.lang, + this.viewOnly = false, }); @override Widget build(BuildContext context, WidgetRef ref) { final search = ref.watch(searchMangaProvider(source: source, query: query)); - return search.when( - loading: () => const Center( - child: CircularProgressIndicator(), - ), - error: (error, stackTrace) => Center(child: Text(error.toString())), - data: (data) { - if (data.name.isNotEmpty) { - return GridViewWidget( - itemCount: data.name.length, - itemBuilder: (context, index) { - return MangaHomeImageCard( - url: data.url[index]!, - name: data.name[index]!, - image: data.image[index]!, - source: source, - lang: lang, + return Scaffold( + appBar: viewOnly + ? AppBar( + title: Text(query), + ) + : null, + body: search.when( + loading: () => const Center( + child: CircularProgressIndicator(), + ), + error: (error, stackTrace) => Center(child: Text(error.toString())), + data: (data) { + if (data.name.isNotEmpty) { + return GridViewWidget( + itemCount: data.name.length, + itemBuilder: (context, index) { + return MangaHomeImageCard( + url: data.url[index]!, + name: data.name[index]!, + image: data.image[index]!, + source: source, + lang: lang, + ); + }, ); - }, - ); - } - return const Center( - child: Text("Empty"), - ); - }); + } + return const Center( + child: Text("Empty"), + ); + })); } } diff --git a/lib/views/manga/reader/providers/reader_controller_provider.g.dart b/lib/views/manga/reader/providers/reader_controller_provider.g.dart index 3dad4ca7..6436224c 100644 --- a/lib/views/manga/reader/providers/reader_controller_provider.g.dart +++ b/lib/views/manga/reader/providers/reader_controller_provider.g.dart @@ -182,7 +182,7 @@ class CurrentIndexProvider } } -String _$readerControllerHash() => r'a2acca315e2e89858de09af86f749a3a9ee2a9b9'; +String _$readerControllerHash() => r'8d9f171beadfd98a701e370a4f9a8e145d6b31de'; abstract class _$ReaderController extends BuildlessAutoDisposeNotifier { late final MangaReaderModel mangaReaderModel; diff --git a/lib/views/updates/updates_screen.dart b/lib/views/updates/updates_screen.dart index acaf21cd..6e6cbddb 100644 --- a/lib/views/updates/updates_screen.dart +++ b/lib/views/updates/updates_screen.dart @@ -20,6 +20,9 @@ class UpdatesScreen extends StatelessWidget { icon: Icon(Icons.refresh, color: Theme.of(context).hintColor)), ], ), + body: const Center( + child: Text("No recent updates"), + ), ); } } diff --git a/lib/views/widgets/bottom_text_widget.dart b/lib/views/widgets/bottom_text_widget.dart index 29f06f91..a54240ac 100644 --- a/lib/views/widgets/bottom_text_widget.dart +++ b/lib/views/widgets/bottom_text_widget.dart @@ -4,11 +4,13 @@ class BottomTextWidget extends StatelessWidget { final bool isLoading; final String text; final bool isComfortableGrid; + final double? fontSize; const BottomTextWidget( {super.key, required this.text, this.isLoading = false, - this.isComfortableGrid = false}); + this.isComfortableGrid = false, + this.fontSize = 13.0}); @override Widget build(BuildContext context) { @@ -20,10 +22,10 @@ class BottomTextWidget extends StatelessWidget { Expanded( child: Text( text, - style: const TextStyle( - fontSize: 13.0, + style: TextStyle( + fontSize: fontSize, color: Colors.white, - shadows: [ + shadows: const [ Shadow(offset: Offset(0.5, 0.9), blurRadius: 3.0) ], ), diff --git a/pubspec.lock b/pubspec.lock index bcf7a26b..09e4f200 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -241,14 +241,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.0" - draggable_menu: - dependency: "direct main" - description: - name: draggable_menu - sha256: "534e9fd85c9e37849456a8359561a6814f2b8048e04be7d97d3cdc76224ff33d" - url: "https://pub.dev" - source: hosted - version: "0.2.0" draggable_scrollbar: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 6b62eb7b..c68bb706 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -52,7 +52,7 @@ dependencies: intl: ^0.18.0 # rive: ^0.10.3 google_fonts: ^4.0.3 - draggable_menu: ^0.2.0 + # draggable_menu: ^0.2.0 # The following adds the Cupertino Icons font to your application.