diff --git a/lib/eval/model/m_bridge.dart b/lib/eval/model/m_bridge.dart index 02d1f00e..3fd3fddf 100644 --- a/lib/eval/model/m_bridge.dart +++ b/lib/eval/model/m_bridge.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:developer'; import 'dart:io'; import 'package:bot_toast/bot_toast.dart'; import 'package:dart_eval/dart_eval_bridge.dart'; @@ -482,7 +483,6 @@ class MBridge { //Utility to use RegExp static String regExp( - //RegExp(r'\[a\]'), "[123]") String expression, String source, String replace, @@ -550,14 +550,18 @@ class MBridge { res = await request.send(); } if (res.statusCode == 403 && (source?.hasCloudflare ?? false)) { + log("Http request: ${res.statusCode}, Cloudflare"); return await cloudflareBypass( url: url, sourceId: source!.id.toString(), method: 0); } else if (res.statusCode == 200) { + log("Http request: ${res.statusCode}"); return await res.stream.bytesToString(); } else { + log("Http request: ${res.statusCode}, reasonPhrase: ${res.reasonPhrase}"); return "error"; } } catch (e) { + log("Http error: $e"); botToast(e.toString()); return "error"; } diff --git a/lib/models/source.dart b/lib/models/source.dart index 4027647f..96c3cc3b 100644 --- a/lib/models/source.dart +++ b/lib/models/source.dart @@ -71,8 +71,8 @@ class Source { this.lastUsed = false, this.apiUrl = "", this.sourceCodeUrl = "", - this.version = "", - this.versionLast = "", + this.version = "0.0.1", + this.versionLast = "0.0.1", this.sourceCode = '', this.headers = '', this.isManga = true, diff --git a/lib/modules/anime/anime_player_view.dart b/lib/modules/anime/anime_player_view.dart index e7612191..a4718349 100644 --- a/lib/modules/anime/anime_player_view.dart +++ b/lib/modules/anime/anime_player_view.dart @@ -166,6 +166,11 @@ class _AnimeStreamPageState extends riv.ConsumerState { title: _firstVid.subtitles?.first.label, language: _firstVid.subtitles?.first.label)); + late final ValueNotifier _audio = ValueNotifier(AudioTrack.uri( + _firstVid.audios?.first.file ?? "", + title: _firstVid.audios?.first.label, + language: _firstVid.audios?.first.label)); + final ValueNotifier _playbackSpeed = ValueNotifier(1.0); bool _seekToCurrentPosition = true; bool _initSubtitle = true; @@ -389,6 +394,40 @@ class _AnimeStreamPageState extends riv.ConsumerState { ], ), ), + const Padding( + padding: EdgeInsets.symmetric(vertical: 5)), + _videoAudios(context) + ], + ), + ), + ), + Container( + color: Colors.white, + width: 0.2, + height: mediaHeight(context, 1)), + Expanded( + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only( + top: 8, left: 12, bottom: 5), + child: Row( + children: [ + Text( + "l10n.subtitle", + style: Theme.of(context) + .textTheme + .bodyLarge! + .copyWith( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 20), + ), + ], + ), + ), const Padding( padding: EdgeInsets.symmetric(vertical: 5)), _videoSubtitle(context) @@ -405,8 +444,7 @@ class _AnimeStreamPageState extends riv.ConsumerState { Widget _videoSubtitle(BuildContext context) { List videoSubtitle = _player.state.tracks.subtitle - .where((element) => - element.title != null && element.language != null && widget.isLocal) + .where((element) => element.title != null && element.language != null) .toList() .map((e) => VideoPrefs(isLocal: true, subtitle: e)) .toList(); @@ -460,9 +498,84 @@ class _AnimeStreamPageState extends riv.ConsumerState { ), Expanded( child: Text( - sub.subtitle!.title ?? - sub.subtitle!.language ?? - sub.subtitle!.channels ?? + sub.subtitle?.title ?? + sub.subtitle?.language ?? + sub.subtitle?.channels ?? + "None", + style: Theme.of(context).textTheme.bodyLarge!.copyWith( + fontSize: 16, + color: selected + ? Colors.white + : Colors.white.withOpacity(0.6)), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + ); + }).toList(), + ); + } + + Widget _videoAudios(BuildContext context) { + List videoAudio = _player.state.tracks.audio + .where((element) => element.title != null && element.language != null) + .toList() + .map((e) => VideoPrefs(isLocal: true, audio: e)) + .toList(); + AudioTrack? audio; + + List audios = []; + if (widget.videos.isNotEmpty && !widget.isLocal) { + for (var video in widget.videos) { + for (var audio in video.audios ?? []) { + if (!audios.contains(audio.file)) { + videoAudio.add(VideoPrefs( + isLocal: false, + audio: AudioTrack.uri(audio.file!, + title: audio.label, language: audio.label))); + audios.add(audio.file!); + } + } + } + } + if (widget.isLocal) { + audio = _player.state.track.audio; + } else { + try { + audio = _audio.value; + } catch (_) {} + } + + videoAudio.sort((a, b) => a.audio!.title!.compareTo(b.audio!.title!)); + videoAudio.insert( + 0, VideoPrefs(isLocal: false, subtitle: SubtitleTrack.no())); + return Column( + children: videoAudio.toSet().toList().map((aud) { + final selected = audio != null && aud.audio == audio; + return GestureDetector( + onTap: () { + Navigator.pop(context); + try { + _player.setAudioTrack(aud.audio!); + if (!widget.isLocal) _audio.value = aud.audio; + } catch (_) {} + }, + child: Row( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Icon( + Icons.check, + color: selected ? Colors.white : Colors.transparent, + ), + ), + Expanded( + child: Text( + aud.audio?.title ?? + aud.audio?.language ?? + aud.audio?.channels ?? "None", style: Theme.of(context).textTheme.bodyLarge!.copyWith( fontSize: 16, @@ -1017,8 +1130,13 @@ class MaterialMobilePositionIndicatorState class VideoPrefs { VideoTrack? videoTrack; SubtitleTrack? subtitle; + AudioTrack? audio; bool isLocal; final Map? headers; VideoPrefs( - {this.videoTrack, this.isLocal = true, this.headers, this.subtitle}); + {this.videoTrack, + this.isLocal = true, + this.headers, + this.subtitle, + this.audio}); } diff --git a/lib/modules/browse/extension/extension_screen.dart b/lib/modules/browse/extension/extension_screen.dart index d3975b92..258b3963 100644 --- a/lib/modules/browse/extension/extension_screen.dart +++ b/lib/modules/browse/extension/extension_screen.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:grouped_list/grouped_list.dart'; +import 'package:grouped_list/sliver_grouped_list.dart'; import 'package:mangayomi/models/source.dart'; import 'package:mangayomi/modules/browse/extension/providers/extensions_provider.dart'; import 'package:mangayomi/modules/browse/extension/providers/fetch_anime_sources.dart'; @@ -21,8 +21,7 @@ class ExtensionScreen extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final streamExtensions = - ref.watch(getExtensionsStreamProvider(isManga: isManga, query: query)); + final streamExtensions = ref.watch(getExtensionsStreamProvider(isManga)); if (isManga) { ref.watch(fetchMangaSourcesListProvider(id: null, reFresh: false)); } else { @@ -39,131 +38,129 @@ class ExtensionScreen extends ConsumerWidget { padding: const EdgeInsets.only(top: 10), child: streamExtensions.when( data: (data) { - final entries1 = data + data = query.isEmpty + ? data + : data + .where((element) => element.name! + .toLowerCase() + .contains(query.toLowerCase())) + .toList(); + data = data .where((element) => ref.watch(showNSFWStateProvider) ? true : element.isNsfw == false) + .toList(); + final notInstalledEntries = data .where((element) => element.version == element.versionLast!) .where((element) => !element.isAdded!) .toList(); - final entries2 = data - .where((element) => ref.watch(showNSFWStateProvider) - ? true - : element.isNsfw == false) + final installedEntries = data .where((element) => element.version == element.versionLast!) .where((element) => element.isAdded!) .toList(); - final entries = data - .where((element) => ref.watch(showNSFWStateProvider) - ? true - : element.isNsfw == false) + final updateEntries = data .where((element) => compareVersions(element.version!, element.versionLast!) < 0) .toList(); - return SingleChildScrollView( - child: Column( - children: [ - if (useTestSourceCode) - for (var e in testSourceModelList) - ExtensionListTileWidget( - source: e, isTestSource: useTestSourceCode), - GroupedListView( - elements: entries, - groupBy: (element) => "", - groupSeparatorBuilder: (_) => Padding( - padding: const EdgeInsets.symmetric(horizontal: 12), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - l10n.update_pending, - style: const TextStyle( - fontWeight: FontWeight.bold, fontSize: 13), - ), - ElevatedButton( - onPressed: () async { - for (var source in entries) { - source.isManga! - ? await ref.watch( - fetchMangaSourcesListProvider( - id: source.id, reFresh: true) - .future) - : await ref.watch( - fetchAnimeSourcesListProvider( - id: source.id, reFresh: true) - .future); - } - }, - child: Text(l10n.update_all)) - ], - ), + return CustomScrollView( + slivers: [ + if (useTestSourceCode) + SliverList.builder( + itemCount: testSourceModelList.length, + itemBuilder: (context, index) => ExtensionListTileWidget( + source: testSourceModelList[index], + isTestSource: true, + )), + SliverGroupedListView( + elements: updateEntries, + groupBy: (element) => "", + groupSeparatorBuilder: (_) => Padding( + padding: const EdgeInsets.symmetric(horizontal: 12), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + l10n.update_pending, + style: const TextStyle( + fontWeight: FontWeight.bold, fontSize: 13), + ), + ElevatedButton( + onPressed: () async { + for (var source in updateEntries) { + source.isManga! + ? await ref.watch( + fetchMangaSourcesListProvider( + id: source.id, reFresh: true) + .future) + : await ref.watch( + fetchAnimeSourcesListProvider( + id: source.id, reFresh: true) + .future); + } + }, + child: Text(l10n.update_all)) + ], ), - itemBuilder: (context, Source element) { - return ExtensionListTileWidget( - source: element, - ); - }, - groupComparator: (group1, group2) => - group1.compareTo(group2), - shrinkWrap: true, - itemComparator: (item1, item2) => - item1.name!.compareTo(item2.name!), - order: GroupedListOrder.ASC, ), - GroupedListView( - elements: entries2, - groupBy: (element) => "", - groupSeparatorBuilder: (_) => Padding( - padding: const EdgeInsets.symmetric(horizontal: 12), - child: Text( - l10n.installed, - style: const TextStyle( - fontWeight: FontWeight.bold, fontSize: 13), - ), + itemBuilder: (context, Source element) { + return ExtensionListTileWidget( + source: element, + ); + }, + groupComparator: (group1, group2) => group1.compareTo(group2), + itemComparator: (item1, item2) => + item1.name!.compareTo(item2.name!), + order: GroupedListOrder.ASC, + ), + SliverGroupedListView( + elements: installedEntries, + groupBy: (element) => "", + groupSeparatorBuilder: (_) => Padding( + padding: const EdgeInsets.symmetric(horizontal: 12), + child: Text( + l10n.installed, + style: const TextStyle( + fontWeight: FontWeight.bold, fontSize: 13), ), - itemBuilder: (context, Source element) { - return ExtensionListTileWidget(source: element); - }, - groupComparator: (group1, group2) => - group1.compareTo(group2), - shrinkWrap: true, - itemComparator: (item1, item2) => - item1.name!.compareTo(item2.name!), - order: GroupedListOrder.ASC, ), - GroupedListView( - elements: entries1, - groupBy: (element) => - completeLanguageName(element.lang!.toLowerCase()), - groupSeparatorBuilder: (String groupByValue) => Padding( - padding: const EdgeInsets.only(left: 12), - child: Row( - children: [ - Text( - groupByValue, - style: const TextStyle( - fontWeight: FontWeight.bold, fontSize: 13), - ), - ], - ), + itemBuilder: (context, Source element) { + return ExtensionListTileWidget(source: element); + }, + groupComparator: (group1, group2) => group1.compareTo(group2), + itemComparator: (item1, item2) => + item1.name!.compareTo(item2.name!), + order: GroupedListOrder.ASC, + ), + SliverGroupedListView( + elements: notInstalledEntries, + groupBy: (element) => + completeLanguageName(element.lang!.toLowerCase()), + groupSeparatorBuilder: (String groupByValue) => Padding( + padding: const EdgeInsets.only(left: 12), + child: Row( + children: [ + Text( + groupByValue, + style: const TextStyle( + fontWeight: FontWeight.bold, fontSize: 13), + ), + ], ), - itemBuilder: (context, Source element) { - return ExtensionListTileWidget( - source: element, - ); - }, - groupComparator: (group1, group2) => - group1.compareTo(group2), - itemComparator: (item1, item2) => - item1.name!.compareTo(item2.name!), - shrinkWrap: true, - order: GroupedListOrder.ASC, ), - ], - ), + itemBuilder: (context, Source element) { + return ExtensionListTileWidget( + source: element, + ); + }, + groupComparator: (group1, group2) => group1.compareTo(group2), + itemComparator: (item1, item2) => + item1.name!.compareTo(item2.name!), + order: GroupedListOrder.ASC, + ), + ], ); }, - error: (error, stackTrace) => ErrorText(error), + error: (error, _) => ErrorText(error), loading: () => const ProgressCenter(), ), ), diff --git a/lib/modules/browse/extension/providers/extension_preferences_providers.dart b/lib/modules/browse/extension/providers/extension_preferences_providers.dart index 211a7825..bc4af347 100644 --- a/lib/modules/browse/extension/providers/extension_preferences_providers.dart +++ b/lib/modules/browse/extension/providers/extension_preferences_providers.dart @@ -41,8 +41,8 @@ SourcePreference getSourcePreferenceEntry(String key, int sourceId) { .sourceIdEqualTo(sourceId) .keyEqualTo(key) .findFirstSync(); - final source = isar.sources.getSync(sourceId)!; if (sourcePreference == null) { + final source = isar.sources.getSync(sourceId)!; sourcePreference = getSourcePreference(source: source).firstWhere( (element) => element.key == key, orElse: () => throw "Error when getting source preference"); diff --git a/lib/modules/browse/extension/providers/extensions_provider.dart b/lib/modules/browse/extension/providers/extensions_provider.dart index efaab544..e9713d84 100644 --- a/lib/modules/browse/extension/providers/extensions_provider.dart +++ b/lib/modules/browse/extension/providers/extensions_provider.dart @@ -5,22 +5,13 @@ import 'package:riverpod_annotation/riverpod_annotation.dart'; part 'extensions_provider.g.dart'; @riverpod -Stream> getExtensionsStream(GetExtensionsStreamRef ref, - {required String query, required bool? isManga}) async* { - yield* query.isNotEmpty - ? isar.sources - .filter() - .nameContains(query.toLowerCase(), caseSensitive: false) - .idIsNotNull() - .and() - .isActiveEqualTo(true) - .isMangaEqualTo(isManga) - .watch(fireImmediately: true) - : isar.sources - .filter() - .idIsNotNull() - .and() - .isActiveEqualTo(true) - .isMangaEqualTo(isManga) - .watch(fireImmediately: true); +Stream> getExtensionsStream( + GetExtensionsStreamRef ref, bool? isManga) async* { + yield* isar.sources + .filter() + .idIsNotNull() + .and() + .isActiveEqualTo(true) + .isMangaEqualTo(isManga) + .watch(fireImmediately: true); } diff --git a/lib/modules/browse/extension/providers/extensions_provider.g.dart b/lib/modules/browse/extension/providers/extensions_provider.g.dart index c3eebc8e..bb6145e5 100644 --- a/lib/modules/browse/extension/providers/extensions_provider.g.dart +++ b/lib/modules/browse/extension/providers/extensions_provider.g.dart @@ -7,7 +7,7 @@ part of 'extensions_provider.dart'; // ************************************************************************** String _$getExtensionsStreamHash() => - r'2f3ed044cd49c1b08587196c27d727ed9d815468'; + r'010b67dcc4ccc0736c5ca779c33751302ab28cd8'; /// Copied from Dart SDK class _SystemHash { @@ -40,13 +40,11 @@ class GetExtensionsStreamFamily extends Family>> { const GetExtensionsStreamFamily(); /// See also [getExtensionsStream]. - GetExtensionsStreamProvider call({ - required String query, - required bool? isManga, - }) { + GetExtensionsStreamProvider call( + bool? isManga, + ) { return GetExtensionsStreamProvider( - query: query, - isManga: isManga, + isManga, ); } @@ -55,8 +53,7 @@ class GetExtensionsStreamFamily extends Family>> { covariant GetExtensionsStreamProvider provider, ) { return call( - query: provider.query, - isManga: provider.isManga, + provider.isManga, ); } @@ -79,14 +76,12 @@ class GetExtensionsStreamFamily extends Family>> { class GetExtensionsStreamProvider extends AutoDisposeStreamProvider> { /// See also [getExtensionsStream]. - GetExtensionsStreamProvider({ - required String query, - required bool? isManga, - }) : this._internal( + GetExtensionsStreamProvider( + bool? isManga, + ) : this._internal( (ref) => getExtensionsStream( ref as GetExtensionsStreamRef, - query: query, - isManga: isManga, + isManga, ), from: getExtensionsStreamProvider, name: r'getExtensionsStreamProvider', @@ -97,7 +92,6 @@ class GetExtensionsStreamProvider dependencies: GetExtensionsStreamFamily._dependencies, allTransitiveDependencies: GetExtensionsStreamFamily._allTransitiveDependencies, - query: query, isManga: isManga, ); @@ -108,11 +102,9 @@ class GetExtensionsStreamProvider required super.allTransitiveDependencies, required super.debugGetCreateSourceHash, required super.from, - required this.query, required this.isManga, }) : super.internal(); - final String query; final bool? isManga; @override @@ -128,7 +120,6 @@ class GetExtensionsStreamProvider dependencies: null, allTransitiveDependencies: null, debugGetCreateSourceHash: null, - query: query, isManga: isManga, ), ); @@ -141,15 +132,12 @@ class GetExtensionsStreamProvider @override bool operator ==(Object other) { - return other is GetExtensionsStreamProvider && - other.query == query && - other.isManga == isManga; + return other is GetExtensionsStreamProvider && other.isManga == isManga; } @override int get hashCode { var hash = _SystemHash.combine(0, runtimeType.hashCode); - hash = _SystemHash.combine(hash, query.hashCode); hash = _SystemHash.combine(hash, isManga.hashCode); return _SystemHash.finish(hash); @@ -157,9 +145,6 @@ class GetExtensionsStreamProvider } mixin GetExtensionsStreamRef on AutoDisposeStreamProviderRef> { - /// The parameter `query` of this provider. - String get query; - /// The parameter `isManga` of this provider. bool? get isManga; } @@ -169,8 +154,6 @@ class _GetExtensionsStreamProviderElement with GetExtensionsStreamRef { _GetExtensionsStreamProviderElement(super.provider); - @override - String get query => (origin as GetExtensionsStreamProvider).query; @override bool? get isManga => (origin as GetExtensionsStreamProvider).isManga; } diff --git a/lib/modules/browse/extension/widgets/extension_list_tile_widget.dart b/lib/modules/browse/extension/widgets/extension_list_tile_widget.dart index 0684015c..4a11a5fd 100644 --- a/lib/modules/browse/extension/widgets/extension_list_tile_widget.dart +++ b/lib/modules/browse/extension/widgets/extension_list_tile_widget.dart @@ -2,6 +2,7 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; +import 'package:mangayomi/main.dart'; import 'package:mangayomi/models/source.dart'; import 'package:mangayomi/modules/browse/extension/providers/fetch_anime_sources.dart'; import 'package:mangayomi/modules/browse/extension/providers/fetch_manga_sources.dart'; @@ -37,6 +38,9 @@ class _ExtensionListTileWidgetState return ListTile( onTap: () async { if (sourceNotEmpty || widget.isTestSource) { + if (widget.isTestSource) { + isar.writeTxnSync(() => isar.sources.putSync(widget.source)); + } context.push('/extension_detail', extra: widget.source); } else { setState(() { diff --git a/lib/modules/browse/sources/sources_screen.dart b/lib/modules/browse/sources/sources_screen.dart index a5abd685..704d57d2 100644 --- a/lib/modules/browse/sources/sources_screen.dart +++ b/lib/modules/browse/sources/sources_screen.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:grouped_list/grouped_list.dart'; +import 'package:grouped_list/sliver_grouped_list.dart'; import 'package:isar/isar.dart'; import 'package:mangayomi/main.dart'; import 'package:mangayomi/models/source.dart'; @@ -16,6 +16,7 @@ class SourcesScreen extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { + final showNSFW = ref.watch(showNSFWStateProvider); final l10n = l10nLocalizations(context)!; return Padding( padding: const EdgeInsets.only(top: 10), @@ -33,117 +34,106 @@ class SourcesScreen extends ConsumerWidget { if (!snapshot.hasData) { return Center(child: Text(l10n.no_result)); } - final entries = snapshot.data! - .where((element) => ref.watch(showNSFWStateProvider) - ? true - : element.isNsfw == false) - .where((element) => element.lastUsed == true) + List sources = snapshot.data! + .where((element) => showNSFW ? true : element.isNsfw == false) .toList(); - final entries1 = snapshot.data! - .where((element) => ref.watch(showNSFWStateProvider) - ? true - : element.isNsfw == false) - .where((element) => element.isPinned == true) - .toList(); - final entries2 = snapshot.data! - .where((element) => ref.watch(showNSFWStateProvider) - ? true - : element.isNsfw == false) - .where((element) => element.isPinned == false) - .toList(); - return SingleChildScrollView( - child: Column( - children: [ - if (useTestSourceCode) - for (var e in testSourceModelList) - SourceListTile(source: e, isManga: isManga), - GroupedListView( - elements: entries, - groupBy: (element) => "", - groupSeparatorBuilder: (String groupByValue) => Padding( - padding: const EdgeInsets.only(left: 12), - child: Row( - children: [ - Text( - l10n.last_used, - style: const TextStyle( - fontWeight: FontWeight.bold, fontSize: 13), - ), - ], - ), + final lastUsedEntries = + sources.where((element) => element.lastUsed!).toList(); + final isPinnedEntries = + sources.where((element) => element.isPinned!).toList(); + final allEntriesWithoutIspinned = + sources.where((element) => !element.isPinned!).toList(); + return CustomScrollView( + slivers: [ + if (useTestSourceCode) + SliverList.builder( + itemCount: testSourceModelList.length, + itemBuilder: (context, index) => SourceListTile( + source: testSourceModelList[index], + isManga: isManga)), + SliverGroupedListView( + elements: lastUsedEntries, + groupBy: (element) => "", + groupSeparatorBuilder: (String groupByValue) => Padding( + padding: const EdgeInsets.only(left: 12), + child: Row( + children: [ + Text( + l10n.last_used, + style: const TextStyle( + fontWeight: FontWeight.bold, fontSize: 13), + ), + ], ), - itemBuilder: (context, Source element) { - return SourceListTile( - source: element, - isManga: isManga, - ); - }, - shrinkWrap: true, - groupComparator: (group1, group2) => - group1.compareTo(group2), - itemComparator: (item1, item2) => - item1.name!.compareTo(item2.name!), - order: GroupedListOrder.ASC, ), - GroupedListView( - elements: entries1, - groupBy: (element) => "", - groupSeparatorBuilder: (String groupByValue) => Padding( - padding: const EdgeInsets.only(left: 12), - child: Row( - children: [ - Text( - l10n.pinned, - style: const TextStyle( - fontWeight: FontWeight.bold, fontSize: 13), - ), - ], - ), + itemBuilder: (context, Source element) { + return SourceListTile( + source: element, + isManga: isManga, + ); + }, + groupComparator: (group1, group2) => + group1.compareTo(group2), + itemComparator: (item1, item2) => + item1.name!.compareTo(item2.name!), + order: GroupedListOrder.ASC, + ), + SliverGroupedListView( + elements: isPinnedEntries, + groupBy: (element) => "", + groupSeparatorBuilder: (String groupByValue) => Padding( + padding: const EdgeInsets.only(left: 12), + child: Row( + children: [ + Text( + l10n.pinned, + style: const TextStyle( + fontWeight: FontWeight.bold, fontSize: 13), + ), + ], ), - itemBuilder: (context, Source element) { - return SourceListTile( - source: element, - isManga: isManga, - ); - }, - shrinkWrap: true, - groupComparator: (group1, group2) => - group1.compareTo(group2), - itemComparator: (item1, item2) => - item1.name!.compareTo(item2.name!), - order: GroupedListOrder.ASC, ), - GroupedListView( - elements: entries2, - groupBy: (element) => - completeLanguageName(element.lang!.toLowerCase()), - groupSeparatorBuilder: (String groupByValue) => Padding( - padding: const EdgeInsets.only(left: 12), - child: Row( - children: [ - Text( - groupByValue, - style: const TextStyle( - fontWeight: FontWeight.bold, fontSize: 13), - ), - ], - ), + itemBuilder: (context, Source element) { + return SourceListTile( + source: element, + isManga: isManga, + ); + }, + groupComparator: (group1, group2) => + group1.compareTo(group2), + itemComparator: (item1, item2) => + item1.name!.compareTo(item2.name!), + order: GroupedListOrder.ASC, + ), + SliverGroupedListView( + elements: allEntriesWithoutIspinned, + groupBy: (element) => + completeLanguageName(element.lang!.toLowerCase()), + groupSeparatorBuilder: (String groupByValue) => Padding( + padding: const EdgeInsets.only(left: 12), + child: Row( + children: [ + Text( + groupByValue, + style: const TextStyle( + fontWeight: FontWeight.bold, fontSize: 13), + ), + ], ), - itemBuilder: (context, Source element) { - return SourceListTile( - source: element, - isManga: isManga, - ); - }, - shrinkWrap: true, - groupComparator: (group1, group2) => - group1.compareTo(group2), - itemComparator: (item1, item2) => - item1.name!.compareTo(item2.name!), - order: GroupedListOrder.ASC, ), - ], - ), + itemBuilder: (context, Source element) { + return SourceListTile( + source: element, + isManga: isManga, + ); + }, + groupComparator: (group1, group2) => + group1.compareTo(group2), + itemComparator: (item1, item2) => + item1.name!.compareTo(item2.name!), + order: GroupedListOrder.ASC, + ), + ], ); })); } diff --git a/lib/modules/browse/sources/widgets/source_list_tile.dart b/lib/modules/browse/sources/widgets/source_list_tile.dart index 610c6568..28a4bf62 100644 --- a/lib/modules/browse/sources/widgets/source_list_tile.dart +++ b/lib/modules/browse/sources/widgets/source_list_tile.dart @@ -3,6 +3,7 @@ import 'package:go_router/go_router.dart'; import 'package:isar/isar.dart'; import 'package:mangayomi/main.dart'; import 'package:mangayomi/models/source.dart'; +import 'package:mangayomi/sources/source_test.dart'; import 'package:mangayomi/utils/colors.dart'; import 'package:mangayomi/utils/language.dart'; import 'package:cached_network_image/cached_network_image.dart'; @@ -17,6 +18,9 @@ class SourceListTile extends StatelessWidget { Widget build(BuildContext context) { return ListTile( onTap: () { + if (useTestSourceCode) { + isar.writeTxnSync(() => isar.sources.putSync(source)); + } final sources = isar.sources .filter() .idIsNotNull() diff --git a/lib/modules/library/providers/library_state_provider.g.dart b/lib/modules/library/providers/library_state_provider.g.dart index 9fa77e0f..bbc0d7cf 100644 --- a/lib/modules/library/providers/library_state_provider.g.dart +++ b/lib/modules/library/providers/library_state_provider.g.dart @@ -7,7 +7,7 @@ part of 'library_state_provider.dart'; // ************************************************************************** String _$libraryDisplayTypeStateHash() => - r'f7355242bae652d8cf378b21626a0ca3138d5c23'; + r'8a7669eb2d0961135bc1a9469d8fbcc7dda0ca3c'; /// Copied from Dart SDK class _SystemHash { diff --git a/lib/modules/manga/detail/manga_detail_main.dart b/lib/modules/manga/detail/manga_detail_main.dart index 26d6f124..19ab8fc3 100644 --- a/lib/modules/manga/detail/manga_detail_main.dart +++ b/lib/modules/manga/detail/manga_detail_main.dart @@ -40,6 +40,7 @@ class _MangaReaderDetailState extends ConsumerState { bool _isLoading = true; @override Widget build(BuildContext context) { + print(widget.mangaId); final manga = ref.watch(getMangaDetailStreamProvider(mangaId: widget.mangaId)); return Scaffold( @@ -59,10 +60,12 @@ class _MangaReaderDetailState extends ConsumerState { .isAddedEqualTo(true) .watch(fireImmediately: true), builder: (context, snapshot) { - final sourceExist = snapshot.hasData && snapshot.data!.isNotEmpty; + final sourceExist = useTestSourceCode + ? true + : snapshot.hasData && snapshot.data!.isNotEmpty; return RefreshIndicator( onRefresh: () async { - if (sourceExist || useTestSourceCode) { + if (sourceExist) { await ref.read(updateMangaDetailProvider( mangaId: manga.id, isInit: false) .future); diff --git a/lib/modules/manga/download/providers/download_provider.g.dart b/lib/modules/manga/download/providers/download_provider.g.dart index 0e937e09..4f355963 100644 --- a/lib/modules/manga/download/providers/download_provider.g.dart +++ b/lib/modules/manga/download/providers/download_provider.g.dart @@ -6,7 +6,7 @@ part of 'download_provider.dart'; // RiverpodGenerator // ************************************************************************** -String _$downloadChapterHash() => r'6ae3da42911f2f4f2d382423b4063d017b7e0355'; +String _$downloadChapterHash() => r'41a09ffc4ef02f061eb0a5d0bfa6410d12dc6c4a'; /// Copied from Dart SDK class _SystemHash { diff --git a/lib/modules/manga/home/widget/filter_widget.dart b/lib/modules/manga/home/widget/filter_widget.dart index 3608464d..17c2a915 100644 --- a/lib/modules/manga/home/widget/filter_widget.dart +++ b/lib/modules/manga/home/widget/filter_widget.dart @@ -35,18 +35,18 @@ class FilterWidget extends StatelessWidget { final state = filterState.state; widget = CheckboxListTile( dense: true, - value: state == 0 - ? false - : state == 1 - ? true - : null, + value: switch (state) { + 0 => false, + 1 => true, + _ => null, + }, onChanged: (value) { filterList[idx] = filterState - ..state = value == null - ? 2 - : value == true - ? 1 - : 0; + ..state = switch (value) { + null => 2, + true => 1, + _ => 0, + }; onChanged(filterList); }, title: Text(filterState.name), diff --git a/lib/modules/manga/reader/providers/push_router.dart b/lib/modules/manga/reader/providers/push_router.dart index db1e5d67..5c6e104a 100644 --- a/lib/modules/manga/reader/providers/push_router.dart +++ b/lib/modules/manga/reader/providers/push_router.dart @@ -23,6 +23,7 @@ pushMangaReaderView({ .isAddedEqualTo(true) .findAllSync() .isNotEmpty; + print(sourceExist); if (sourceExist || useTestSourceCode || chapter.manga.value!.isLocalArchive!) { diff --git a/lib/modules/more/backup_and_restore/providers/restore.g.dart b/lib/modules/more/backup_and_restore/providers/restore.g.dart index 27896837..70422f1b 100644 --- a/lib/modules/more/backup_and_restore/providers/restore.g.dart +++ b/lib/modules/more/backup_and_restore/providers/restore.g.dart @@ -6,7 +6,7 @@ part of 'restore.dart'; // RiverpodGenerator // ************************************************************************** -String _$doRestoreHash() => r'3c88ad8ba80c245a4b511961111f7ab79c0d330f'; +String _$doRestoreHash() => r'91d54be97447d51073f214b1f51deffa0045b1d0'; /// Copied from Dart SDK class _SystemHash { diff --git a/lib/modules/more/more_screen.dart b/lib/modules/more/more_screen.dart index a86424d6..97e6455c 100644 --- a/lib/modules/more/more_screen.dart +++ b/lib/modules/more/more_screen.dart @@ -31,8 +31,7 @@ class MoreScreen extends StatelessWidget { const Divider(), // ListTile( // onTap: () {}, - // leading: - // const SizedBox(height: 40, child: Icon(Icons.cloud_off)), + // leading: const SizedBox(height: 40, child: Icon(Icons.cloud_off)), // subtitle: const Text('Filter all entries in your library'), // title: const Text('Donloaded only'), // trailing: Switch( diff --git a/lib/sources/utils/utils.dart b/lib/sources/utils/utils.dart index 597eb365..9d4c59c3 100644 --- a/lib/sources/utils/utils.dart +++ b/lib/sources/utils/utils.dart @@ -1,16 +1,8 @@ import 'package:isar/isar.dart'; import 'package:mangayomi/main.dart'; import 'package:mangayomi/models/source.dart'; -import 'package:mangayomi/sources/source_test.dart'; Source? getSource(String lang, String name) { - if (testSourceModelList.isNotEmpty && useTestSourceCode) { - if (lang.isEmpty || name.isEmpty) { - return testSourceModelList.first; - } - return testSourceModelList - .firstWhere((element) => element.lang == lang && element.name == name); - } try { final sourcesList = isar.sources.filter().idIsNotNull().findAllSync(); return sourcesList.firstWhere(