From 60aadec61d92d2bb356c6a1c0634f52f2fd67d15 Mon Sep 17 00:00:00 2001 From: femalemonkeyman Date: Mon, 14 Aug 2023 18:48:32 -0400 Subject: [PATCH] Finally feel satisfied enough to build these changes --- lib/main.dart | 32 ++++----- lib/media/media.dart | 11 +-- lib/media/media_anime.dart | 89 ++++++++++++++++++------ lib/media/providers/anime/animepahe.dart | 76 +++++++++++--------- lib/media/providers/anime/aniwatch.dart | 7 +- lib/pages/later_page.dart | 36 +++++----- lib/widgets/grid.dart | 16 ++--- pubspec.lock | 38 +++++----- 8 files changed, 174 insertions(+), 131 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 3976f4f..28ca69b 100755 --- a/lib/main.dart +++ b/lib/main.dart @@ -111,14 +111,12 @@ class Navigation extends StatelessWidget { GoRoute( name: 'anime', path: '/anime', - pageBuilder: (context, state) => MaterialPage( - child: AniPage( - key: (state.uri.queryParameters.isEmpty) - ? null - : Key(state.uri.queryParameters['tag']!), - type: 'anime', - tag: state.uri.queryParameters['tag'], - ), + builder: (context, state) => AniPage( + key: (state.uri.queryParameters.isEmpty) + ? null + : Key(state.uri.queryParameters['tag']!), + type: 'anime', + tag: state.uri.queryParameters['tag'], ), routes: [ GoRoute( @@ -147,15 +145,13 @@ class Navigation extends StatelessWidget { GoRoute( name: 'manga', path: '/manga', - builder: (context, state) { - return AniPage( - key: (state.uri.queryParameters.isEmpty) - ? null - : Key(state.uri.queryParameters['tag']!), - type: 'manga', - tag: state.uri.queryParameters['tag'], - ); - }, + builder: (context, state) => AniPage( + key: (state.uri.queryParameters.isEmpty) + ? null + : Key(state.uri.queryParameters['tag']!), + type: 'manga', + tag: state.uri.queryParameters['tag'], + ), routes: [ GoRoute( parentNavigatorKey: _rootKey, @@ -201,7 +197,7 @@ class Navigation extends StatelessWidget { GoRoute( name: 'later', path: '/later', - builder: (context, state) => const LaterPage(), + builder: (context, state) => LaterPage(), ), ], ), diff --git a/lib/media/media.dart b/lib/media/media.dart index 9b610a6..af44988 100644 --- a/lib/media/media.dart +++ b/lib/media/media.dart @@ -91,7 +91,7 @@ class AniPageState extends State { bool loading = false; final List selectedGenres = []; late String? tag = widget.tag; - Map pageInfo = {}; + final Map pageInfo = {}; final List animeData = []; @override @@ -124,7 +124,11 @@ class AniPageState extends State { }, ), ); - pageInfo = query.data!['Page']['pageInfo']; + pageInfo + ..clear() + ..addAll( + query.data!['Page']['pageInfo'], + ); animeData.addAll( List.generate( query.data!['Page']['media'].length, @@ -200,7 +204,7 @@ class AniPageState extends State { }, ).then( (value) async { - pageInfo = {}; + pageInfo.clear(); animeData.clear(); await queryData(); setState( @@ -237,7 +241,6 @@ class AniPageState extends State { }, ), child: CustomScrollView( - primary: true, slivers: [ SliverToBoxAdapter( child: Center( diff --git a/lib/media/media_anime.dart b/lib/media/media_anime.dart index 6bb3216..b9657a1 100644 --- a/lib/media/media_anime.dart +++ b/lib/media/media_anime.dart @@ -10,6 +10,20 @@ import 'package:window_manager/window_manager.dart'; const Source blank = Source(qualities: {}, subtitles: {}); +void setSubtitles(final Source media, final Player player) { + if (media.subtitles.isNotEmpty) { + player.setSubtitleTrack( + SubtitleTrack.uri( + media.subtitles.entries + .firstWhere( + (element) => element.key.toLowerCase().contains('eng'), + ) + .value, + ), + ); + } +} + class AniViewer extends StatefulWidget { final List episodes; final int episode; @@ -54,7 +68,11 @@ class AniViewerState extends State { httpHeaders: media.headers ?? {}, ), ); - setState(() {}); + setState( + () { + setSubtitles(media, player); + }, + ); } } @@ -407,26 +425,55 @@ class TopBar extends StatelessWidget { height: size.height / 2, ), builder: (context) => ListView( - children: List.generate( - // player.state.tracks.video.length - 2, - media.qualities.length, - (index) { - return ListTile( - title: Text(media.qualities.keys.elementAt(index)), - onTap: () async { - final current = await player.stream.buffer.first; - print(current); - await player.open( - Media( - media.qualities.values.elementAt(index), - httpHeaders: media.headers, - ), - ); - await player.seek(current); - }, - ); - }, - ), + children: (media.qualities.length == 1) + ? List.generate( + player.state.tracks.video.length - 2, + (index) { + return ListTile( + title: Text( + player.state.tracks.video[index + 2].h + .toString(), + ), + onTap: () { + player.setVideoTrack( + player.state.tracks.video[index + 2], + ); + context.pop(); + }, + ); + }, + ) + : List.generate( + media.qualities.length, + (index) { + return ListTile( + title: + Text(media.qualities.keys.elementAt(index)), + onTap: () { + Future.microtask( + () async { + final current = + await player.stream.position.first; + player.open( + Media( + media.qualities.values + .elementAt(index), + httpHeaders: media.headers, + ), + play: false, + ); + await player.stream.buffer.first; + setSubtitles(media, player); + player + ..seek(current) + ..play(); + }, + ); + context.pop(); + }, + ); + }, + ), ), ), ), diff --git a/lib/media/providers/anime/animepahe.dart b/lib/media/providers/anime/animepahe.dart index 9ce2f37..4c08264 100644 --- a/lib/media/providers/anime/animepahe.dart +++ b/lib/media/providers/anime/animepahe.dart @@ -22,13 +22,12 @@ Provider paheList(final AniData data) async { 'https://animepahe.ru/api?m=release&id=$syncId&sort=episode_asc'; final Map anime = (await Dio().get(link)).data; if (anime['last_page'] > 1) { - final List>> requests = []; - for (int i = 2; i <= anime['last_page']; i++) { - requests.add( - Dio().get('$link&page=$i'), //.data['data'] - ); - } - for (Response i in await Future.wait(requests)) { + for (Response i in await Future.wait( + [ + for (int i = 2; i <= anime['last_page']; i++) + Dio().get('$link&page=$i'), + ], + )) { anime['data'].addAll(i.data['data']); } } @@ -48,7 +47,7 @@ Provider paheList(final AniData data) async { } Anime paheInfo(final String id) async { - final Document data = parse( + final List data = parse( (await Dio().get( 'https://animepahe.ru/play/$id', options: Options( @@ -58,34 +57,43 @@ Anime paheInfo(final String id) async { ), )) .data, - ); - for (Element i in data.body! + ) .getElementsByTagName('button') - .where((element) => element.attributes.containsKey('data-src'))) { - if (i.attributes['data-src']?.contains('kwik') ?? false) { - Document arr = parse( - (await Dio().get( - i.attributes['data-src']!, - options: Options( - headers: { - 'referer': 'https://animepahe.ru', - }, - ), - )) - .data, - ); - qualities.addAll( - { - '${i.attributes['data-fansub']}-${i.attributes['data-resolution']}': - JsUnpack( - '\r${arr.getElementsByTagName('script').where((element) => element.text.contains('eval')).first.text}', - ).unpack().split('source=\'')[1].split('\'')[0] - }, - ); - } - } + .where( + (element) => + element.attributes.containsKey('data-src') && + (element.attributes['data-src']?.contains('kwik') ?? false), + ) + .toList(); return Source( - qualities: qualities, + qualities: Map.fromIterables( + [ + for (Element i in data) + '${i.attributes['data-fansub']}-${i.attributes['data-resolution']}' + ].reversed, + [ + for (Response i in await Future.wait( + [ + for (Element i in data) + Dio().get( + i.attributes['data-src']!, + options: Options( + headers: { + 'referer': 'https://animepahe.ru', + }, + ), + ) + ], + )) + JsUnpack( + parse(i.data) + .getElementsByTagName('script') + .where((element) => element.text.contains('eval')) + .first + .text, + ).unpack().split('source=\'')[1].split('\'')[0], + ].reversed, + ), //qualities, subtitles: {}, headers: {'referer': 'https://kwik.cx'}, ); diff --git a/lib/media/providers/anime/aniwatch.dart b/lib/media/providers/anime/aniwatch.dart index 265619a..22dcec2 100644 --- a/lib/media/providers/anime/aniwatch.dart +++ b/lib/media/providers/anime/aniwatch.dart @@ -41,6 +41,7 @@ Provider zoroList(final AniData data) async { } Anime zoroInfo(final id) async { + print(id); final Options options = Options(responseType: ResponseType.plain); final Element server = parse( jsonDecode( @@ -61,7 +62,7 @@ Anime zoroInfo(final id) async { )) .data, ); - Map sources = jsonDecode( + final Map sources = jsonDecode( (await Dio().get( 'https://megacloud.tv/embed-2/ajax/e-1/getSources?id=${link['link'].split('e-1/')[1].split('?')[0]}', options: options)) @@ -83,9 +84,7 @@ Anime zoroInfo(final id) async { } sources['sources'] = jsonDecode(decrypt(sources['sources'], key)); } - if (sources['tracks'].last['kind'] != 'captions') { - (sources['tracks'] as List).removeLast(); - } + sources['tracks'].removeWhere((element) => element['kind'] != 'captions'); return Source( qualities: { 'default': sources['sources'][0]['file'], diff --git a/lib/pages/later_page.dart b/lib/pages/later_page.dart index cb3ffca..534d501 100644 --- a/lib/pages/later_page.dart +++ b/lib/pages/later_page.dart @@ -6,31 +6,29 @@ import 'package:flutter/material.dart'; import 'package:isar/isar.dart'; import 'package:path_provider/path_provider.dart'; -class LaterPage extends StatefulWidget { - const LaterPage({super.key}); +class LaterPage extends StatelessWidget { + final List animeData = []; + final List mangaData = []; - @override - State createState() => LaterPageState(); -} - -class LaterPageState extends State { - List animeData = []; - List mangaData = []; + LaterPage({super.key}); Future get dir async { return await getApplicationDocumentsDirectory(); } final Isar isar = Isar.getInstance('later')!; - late final dataChange = isar.aniDatas.watchLazy(fireImmediately: true); - - @override - void initState() { - super.initState(); - } + late final Stream dataChange = isar.aniDatas.watchLazy(fireImmediately: true); void updateData() { - animeData = isar.aniDatas.filter().typeEqualTo("anime").findAllSync(); - mangaData = isar.aniDatas.filter().typeEqualTo("manga").findAllSync(); + animeData + ..clear() + ..addAll( + isar.aniDatas.filter().typeEqualTo("anime").findAllSync(), + ); + mangaData + ..clear() + ..addAll( + isar.aniDatas.filter().typeEqualTo("manga").findAllSync(), + ); } @override @@ -53,7 +51,7 @@ class LaterPageState extends State { Spacer(), Text( 'Anime', - textScaleFactor: 1.2, + textScaler: TextScaler.linear(1.2), ), Spacer(), Expanded( @@ -79,7 +77,7 @@ class LaterPageState extends State { Spacer(), Text( 'Manga', - textScaleFactor: 1.2, + textScaler: TextScaler.linear(1.2), ), Spacer(), Expanded( diff --git a/lib/widgets/grid.dart b/lib/widgets/grid.dart index ee9d855..1d54588 100644 --- a/lib/widgets/grid.dart +++ b/lib/widgets/grid.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'block.dart'; -class Grid extends StatefulWidget { +class Grid extends StatelessWidget { final List data; final bool keep; final int? length; @@ -12,29 +12,21 @@ class Grid extends StatefulWidget { Key? key, }) : super(key: key); - @override - State createState() => GridState(); -} - -class GridState extends State with AutomaticKeepAliveClientMixin { - @override - bool get wantKeepAlive => widget.keep; - @override Widget build(BuildContext context) { - super.build(context); return SliverGrid( gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent( childAspectRatio: 4 / 6, maxCrossAxisExtent: 280, ), delegate: SliverChildBuilderDelegate( - childCount: widget.data.length, + childCount: data.length, + addAutomaticKeepAlives: keep, (context, index) { return Padding( padding: const EdgeInsets.all(10), child: Block( - data: widget.data[index], + data: data[index], ), ); }, diff --git a/pubspec.lock b/pubspec.lock index b085a71..3c4df7e 100755 --- a/pubspec.lock +++ b/pubspec.lock @@ -375,18 +375,18 @@ packages: dependency: transitive description: name: gql - sha256: c2d4248adf2cc568976d9bb42803531232a981eff205b9931b73389e0665ac63 + sha256: "56c5707f84128dfad2db16f513bbfe011f0dae96073bbdc4e6a9925915641a03" url: "https://pub.dev" source: hosted - version: "1.0.1-alpha+1690479830964" + version: "1.0.1-alpha+1691943394579" gql_dedupe_link: dependency: transitive description: name: gql_dedupe_link - sha256: "307a33a0723edd5d9de652e38f6ccb01fbf04b90464e32efca7a3fa9027367d3" + sha256: "80419ab0618dea72a0961617cf24fba690ff4e63fffdd57a701b0c7de08b8360" url: "https://pub.dev" source: hosted - version: "2.0.4-alpha+1690479831065" + version: "2.0.4-alpha+1691943394662" gql_error_link: dependency: transitive description: @@ -399,10 +399,10 @@ packages: dependency: transitive description: name: gql_exec - sha256: "257b6eeb206343349b188a4bfe874ba5826ec7992461a97890ebf4802eaa9a86" + sha256: "7b8c816f1d4830a21ae37e107bb035073b2f5613acde8f76a7768a7eb23322d3" url: "https://pub.dev" source: hosted - version: "1.0.1-alpha+1690479830973" + version: "1.0.1-alpha+1691943394588" gql_http_link: dependency: transitive description: @@ -415,10 +415,10 @@ packages: dependency: transitive description: name: gql_link - sha256: "6e429187a7c199c9a7bb7fc26c8ed0673dae9be3a00c8be6ecf15ba9b713b3cb" + sha256: "255a0262425b6efd9df2312fd90546105baaad22a98a9873dfca56efbe9163eb" url: "https://pub.dev" source: hosted - version: "1.0.1-alpha+1690479830981" + version: "1.0.1-alpha+1691943394596" gql_transform_link: dependency: transitive description: @@ -584,7 +584,7 @@ packages: description: path: media_kit ref: main - resolved-ref: e117b5f3aec324980519bbb18c9c51b29be9a7ca + resolved-ref: "346d2506c1942053784282af513c30343fc527df" url: "https://github.com/alexmercerind/media_kit.git" source: git version: "1.1.3+1" @@ -593,25 +593,25 @@ packages: description: path: "libs/android/media_kit_libs_android_video" ref: main - resolved-ref: e117b5f3aec324980519bbb18c9c51b29be9a7ca + resolved-ref: "346d2506c1942053784282af513c30343fc527df" url: "https://github.com/alexmercerind/media_kit" source: git - version: "1.3.1" + version: "1.3.2" media_kit_libs_ios_video: dependency: "direct main" description: path: "libs/ios/media_kit_libs_ios_video" ref: main - resolved-ref: e117b5f3aec324980519bbb18c9c51b29be9a7ca + resolved-ref: "346d2506c1942053784282af513c30343fc527df" url: "https://github.com/alexmercerind/media_kit" source: git - version: "1.1.2" + version: "1.1.3" media_kit_libs_linux: dependency: "direct main" description: path: "libs/linux/media_kit_libs_linux" ref: main - resolved-ref: e117b5f3aec324980519bbb18c9c51b29be9a7ca + resolved-ref: "346d2506c1942053784282af513c30343fc527df" url: "https://github.com/alexmercerind/media_kit" source: git version: "1.1.0" @@ -620,25 +620,25 @@ packages: description: path: "libs/macos/media_kit_libs_macos_video" ref: main - resolved-ref: e117b5f3aec324980519bbb18c9c51b29be9a7ca + resolved-ref: "346d2506c1942053784282af513c30343fc527df" url: "https://github.com/alexmercerind/media_kit" source: git - version: "1.1.2" + version: "1.1.3" media_kit_libs_windows_video: dependency: "direct main" description: path: "libs/windows/media_kit_libs_windows_video" ref: main - resolved-ref: e117b5f3aec324980519bbb18c9c51b29be9a7ca + resolved-ref: "346d2506c1942053784282af513c30343fc527df" url: "https://github.com/alexmercerind/media_kit" source: git - version: "1.0.6" + version: "1.0.7" media_kit_video: dependency: "direct main" description: path: media_kit_video ref: main - resolved-ref: e117b5f3aec324980519bbb18c9c51b29be9a7ca + resolved-ref: "346d2506c1942053784282af513c30343fc527df" url: "https://github.com/alexmercerind/media_kit.git" source: git version: "1.1.3"