diff --git a/lib/anime/anime_videos.dart b/lib/anime/anime_videos.dart index 1e6f7de..5e19826 100644 --- a/lib/anime/anime_videos.dart +++ b/lib/anime/anime_videos.dart @@ -3,6 +3,7 @@ import 'package:anicross/providers/anime_providers.dart'; import 'package:audio_video_progress_bar/audio_video_progress_bar.dart'; import 'package:better_player/better_player.dart'; import 'package:dio/dio.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:media_kit/media_kit.dart'; @@ -40,7 +41,9 @@ class AniViewerState extends State { widget.episode['id'], ) ?? widget.episode; - setState(() {}); + setState(() { + subtitles = getMedia['subtitles'] ?? []; + }); }, ); } @@ -76,7 +79,7 @@ class AniViewerState extends State { @override Widget build(context) { - if (getMedia.isNotEmpty) { + if (getMedia.isNotEmpty && !kIsWeb) { if (isPhone) { BetterPlayerDataSource source = BetterPlayerDataSource( BetterPlayerDataSourceType.network, @@ -199,7 +202,7 @@ class VideoControlsState extends State { Widget build(context) { return GestureDetector( onTap: () => setState(() { - (widget.player.state.isPlaying) + (widget.player.state.playing) ? widget.player.pause() : widget.player.play(); }), diff --git a/lib/info_page.dart b/lib/info_page.dart index 7eb03f6..be00bfe 100644 --- a/lib/info_page.dart +++ b/lib/info_page.dart @@ -5,11 +5,13 @@ import 'package:anicross/providers/info_models.dart'; import 'package:anicross/providers/manga_providers.dart'; import 'package:expandable_text/expandable_text.dart'; import 'package:flutter/material.dart'; +import 'package:isar/isar.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; import 'widgets/image.dart'; class InfoPage extends StatefulWidget { final AniData data; + const InfoPage({required this.data, super.key}); @override @@ -18,6 +20,10 @@ class InfoPage extends StatefulWidget { class InfoPageState extends State { List content = []; + final Isar isar = Isar.getInstance() ?? + Isar.openSync( + [AniDataSchema], + ); @override void initState() { @@ -34,6 +40,11 @@ class InfoPageState extends State { super.initState(); } + @override + void dispose() { + super.dispose(); + } + @override Widget build(context) { final expands = Column( @@ -41,9 +52,18 @@ class InfoPageState extends State { mainAxisSize: MainAxisSize.min, children: [ const Divider(), + ExpandableText( + widget.data.description, + expandText: "More", + collapseText: "Less", + maxLines: 8, + ), + const Divider( + height: 15, + ), Wrap( - spacing: 10, - runSpacing: 10, + spacing: 7, + runSpacing: 5, children: List.generate( widget.data.tags.length.clamp(0, 20), (index) { @@ -55,15 +75,6 @@ class InfoPageState extends State { }, ), ), - const Divider( - height: 15, - ), - ExpandableText( - widget.data.description, - expandText: "More", - collapseText: "Less", - maxLines: 8, - ), ], ); return Scaffold( @@ -111,8 +122,31 @@ class InfoPageState extends State { height: 20, ), ActionChip( - onPressed: () {}, - avatar: const Icon(MdiIcons.bookmark), + onPressed: () => setState( + () { + QueryBuilder media = + isar.aniDatas.filter().mediaIdMatches( + widget.data.mediaId, + ); + + if (media.isEmptySync()) { + isar.writeTxnSync( + () => isar.aniDatas.putSync(widget.data), + ); + } else { + isar.writeTxnSync( + () => media.deleteAllSync(), + ); + } + }, + ), + avatar: (isar.aniDatas + .filter() + .mediaIdMatches(widget.data.mediaId) + .isEmptySync()) + ? const Icon(MdiIcons.bookmarkOutline) + : const Icon(MdiIcons.bookmark), label: const Text("Later"), ), if (MediaQuery.of(context).size.width / diff --git a/lib/later_page.dart b/lib/later_page.dart new file mode 100644 index 0000000..89b75cb --- /dev/null +++ b/lib/later_page.dart @@ -0,0 +1,57 @@ +import 'package:anicross/providers/info_models.dart'; +import 'package:anicross/widgets/grid.dart'; +import 'package:flutter/material.dart'; +import 'package:isar/isar.dart'; + +class LaterPage extends StatefulWidget { + const LaterPage({super.key}); + + @override + State createState() => LaterPageState(); +} + +class LaterPageState extends State { + List animeData = []; + List mangaData = []; + final Isar isar = Isar.getInstance() ?? + Isar.openSync( + [AniDataSchema], + ); + late final dataChange = isar.aniDatas.watchLazy(fireImmediately: true); + + @override + void initState() { + super.initState(); + } + + void updateData() { + animeData = isar.aniDatas.filter().typeEqualTo("anime").findAllSync(); + mangaData = isar.aniDatas.filter().typeEqualTo("manga").findAllSync(); + } + + @override + Widget build(context) { + return StreamBuilder( + stream: dataChange, + builder: (context, snap) { + updateData(); + return CustomScrollView( + slivers: [ + Grid( + data: animeData, + paginate: () {}, + keep: false, + length: animeData.length, + ), + Grid( + data: mangaData, + paginate: () {}, + keep: false, + length: mangaData.length, + ), + ], + ); + }, + ); + } +} diff --git a/lib/main.dart b/lib/main.dart index 9765e12..7cbe963 100755 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,5 @@ import 'package:anicross/color_schemes.g.dart'; +import 'package:anicross/later_page.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; @@ -58,8 +59,7 @@ class AniNav extends StatelessWidget { MangaPage(), //NovelPage(), Placeholder(), - Placeholder(), - //SizedBox.shrink(), + LaterPage(), ], ), ), diff --git a/lib/manga/manga_reader.dart b/lib/manga/manga_reader.dart index bcca17a..8326e83 100644 --- a/lib/manga/manga_reader.dart +++ b/lib/manga/manga_reader.dart @@ -88,7 +88,13 @@ class MangaControls extends StatefulWidget { } class MangaControlsState extends State { - bool show = true; + bool show = false; + + @override + void dispose() { + widget.controller.dispose(); + super.dispose(); + } @override Widget build(context) { @@ -100,6 +106,10 @@ class MangaControlsState extends State { opacity: !show ? 0.0 : 1.0, child: Stack( children: [ + Positioned( + child: Text( + widget.controller.page.toString(), + )), Container( decoration: const BoxDecoration( gradient: LinearGradient( @@ -117,30 +127,40 @@ class MangaControlsState extends State { ), ), ), - Positioned.fill( - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Flexible( - child: GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () { - widget.controller.jumpToPage( - (widget.controller.page! + 1).toInt(), - ); - }, - ), - ), - Flexible( - child: GestureDetector( - onTap: () { - widget.controller.jumpToPage( - (widget.controller.page! - 1).toInt(), - ); - }, - ), - ), - ], + Positioned( + top: 0, + left: 0, + width: MediaQuery.of(context).size.width / 2, + child: GestureDetector( + onTap: () { + widget.controller.jumpToPage( + (widget.controller.page! + 1).toInt(), + ); + }, + ), + ), + Positioned( + top: 0, + right: 0, + width: MediaQuery.of(context).size.width / 2, + child: GestureDetector( + onTap: () { + widget.controller.jumpToPage( + (widget.controller.page! - 1).toInt(), + ); + }, + ), + ), + Positioned( + height: MediaQuery.of(context).size.height / 5, + left: 0, + right: 0, + bottom: 0, + child: GestureDetector( + //behavior: HitTestBehavior.opaque, + onTap: () => setState( + () => (show) ? show = false : show = true, + ), ), ), const BackButton(), diff --git a/lib/providers/anime_providers.dart b/lib/providers/anime_providers.dart index c93f7b7..67065b1 100644 --- a/lib/providers/anime_providers.dart +++ b/lib/providers/anime_providers.dart @@ -36,16 +36,13 @@ Future mediaInfo(id) async { //Begin Hanime Future haniList(String name) async { - //name.split(pattern).getRange(0, 3); Response json = await Dio().post( "https://search.htv-services.com/", data: jsonEncode( { "search_text": (name.split(" ").length > 3) - ? name.split(" ").getRange(0, 3).join(" ").replaceAll(":", "") - : name, - // "${name.split(" ")[0]} ${name.split(" ")[1]} ${name.split(" ")[2]}" - // .replaceAll(":", ""), + ? name.split(" ").getRange(0, 3).join(" ") + : name.replaceAll("☆", " "), "tags": [], "tags-mode": "AND", "brands": [], @@ -58,14 +55,16 @@ Future haniList(String name) async { ); if (json.data['nbHits'] > 0) { final List results = jsonDecode(json.data['hits']); - List videos = []; - - for (var i in results) { + for (Map i in results) { Response v = await Dio().get( "https://hanime.tv/api/v8/video?id=${i['id']}", ); - videos.add(v.data); + print(i['name'].toString().similarityTo(name)); + if (i['name'].toString().similarityTo(name) > 0.2) { + print("yes"); + videos.add(v.data); + } } return List.generate( diff --git a/lib/widgets/block.dart b/lib/widgets/block.dart index 1be189d..5b03bcf 100644 --- a/lib/widgets/block.dart +++ b/lib/widgets/block.dart @@ -32,7 +32,7 @@ class Block extends StatelessWidget { position: DecorationPosition.foreground, decoration: BoxDecoration( border: Border.all(strokeAlign: -0.050), - borderRadius: BorderRadius.circular(30), + borderRadius: BorderRadius.circular(15), gradient: const LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, diff --git a/lib/widgets/grid.dart b/lib/widgets/grid.dart index 448b615..1e9cc3e 100644 --- a/lib/widgets/grid.dart +++ b/lib/widgets/grid.dart @@ -5,9 +5,13 @@ import 'block.dart'; class Grid extends StatefulWidget { final List data; final Function paginate; + final bool keep; + final int? length; const Grid({ required this.data, required this.paginate, + this.keep = true, + this.length, Key? key, }) : super(key: key); @@ -17,30 +21,28 @@ class Grid extends StatefulWidget { class GridState extends State with AutomaticKeepAliveClientMixin { @override - bool get wantKeepAlive => true; + bool get wantKeepAlive => widget.keep; @override Widget build(BuildContext context) { super.build(context); return SliverGrid( - //primary: false, gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent( - //mainAxisSpacing: 20, - //crossAxisSpacing: 20, childAspectRatio: 4 / 6, maxCrossAxisExtent: 280, ), delegate: SliverChildBuilderDelegate( + childCount: widget.length, (context, index) { - if (index <= widget.data.length - 5) { + if (index >= widget.data.length - 5 && widget.length == null) { + widget.paginate(); + } else { return Padding( padding: const EdgeInsets.all(10), child: Block( data: widget.data[index], ), ); - } else { - widget.paginate(); } return null; }, diff --git a/lib/widgets/image.dart b/lib/widgets/image.dart index b522e2a..8a149f1 100644 --- a/lib/widgets/image.dart +++ b/lib/widgets/image.dart @@ -9,7 +9,7 @@ class AniImage extends StatelessWidget { @override Widget build(context) { return ClipRRect( - borderRadius: BorderRadius.circular(30.0), + borderRadius: BorderRadius.circular(15.0), child: CachedNetworkImage( fit: BoxFit.cover, imageUrl: image, diff --git a/pubspec.lock b/pubspec.lock index 477dd8d..43196e1 100755 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: d74f051467a841ce893a50ebeb420b7a5695f985d2781e22b3927fbc849aea45 + sha256: a36ec4843dc30ea6bf652bf25e3448db6c5e8bcf4aa55f063a5d1dad216d8214 url: "https://pub.dev" source: hosted - version: "57.0.0" + version: "58.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: b665679cdccab0c754e65021f01087c6fab07a0b13659dd58827f765739b40f8 + sha256: cc4242565347e98424ce9945c819c192ec0838cb9d1f6aa4a97cc96becbc5b27 url: "https://pub.dev" source: hosted - version: "5.9.0" + version: "5.10.0" archive: dependency: "direct main" description: @@ -58,6 +58,14 @@ packages: url: "https://github.com/femalemonkeyman/betterplayer" source: git version: "0.0.83" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" + source: hosted + version: "2.1.1" build: dependency: transitive description: @@ -544,10 +552,10 @@ packages: dependency: transitive description: name: matcher - sha256: c94db23593b89766cda57aab9ac311e3616cf87c6fa4e9749df032f66f30dcb8 + sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" url: "https://pub.dev" source: hosted - version: "0.12.14" + version: "0.12.15" material_color_utilities: dependency: transitive description: @@ -569,16 +577,25 @@ packages: description: path: media_kit ref: main - resolved-ref: "2fdd64dd4f2855d6c12c57306c5ebf4a7c8db27a" + resolved-ref: "03d8a702d5c0600e94548fd68a6b71c1485a0e49" url: "https://github.com/alexmercerind/media_kit.git" source: git version: "0.0.1" + media_kit_libs_ios_video: + dependency: "direct main" + description: + path: media_kit_libs_ios_video + ref: main + resolved-ref: "03d8a702d5c0600e94548fd68a6b71c1485a0e49" + url: "https://github.com/alexmercerind/media_kit" + source: git + version: "1.0.0" media_kit_libs_linux: dependency: "direct main" description: path: media_kit_libs_linux ref: main - resolved-ref: "2fdd64dd4f2855d6c12c57306c5ebf4a7c8db27a" + resolved-ref: "03d8a702d5c0600e94548fd68a6b71c1485a0e49" url: "https://github.com/alexmercerind/media_kit" source: git version: "1.0.0" @@ -587,7 +604,7 @@ packages: description: path: media_kit_libs_macos_video ref: main - resolved-ref: "2fdd64dd4f2855d6c12c57306c5ebf4a7c8db27a" + resolved-ref: "03d8a702d5c0600e94548fd68a6b71c1485a0e49" url: "https://github.com/alexmercerind/media_kit" source: git version: "1.0.0" @@ -596,7 +613,7 @@ packages: description: path: media_kit_libs_windows_video ref: main - resolved-ref: "2fdd64dd4f2855d6c12c57306c5ebf4a7c8db27a" + resolved-ref: "03d8a702d5c0600e94548fd68a6b71c1485a0e49" url: "https://github.com/alexmercerind/media_kit" source: git version: "1.0.0" @@ -605,10 +622,10 @@ packages: description: path: media_kit_video ref: main - resolved-ref: "2fdd64dd4f2855d6c12c57306c5ebf4a7c8db27a" + resolved-ref: "03d8a702d5c0600e94548fd68a6b71c1485a0e49" url: "https://github.com/alexmercerind/media_kit.git" source: git - version: "0.0.1" + version: "0.0.2" meta: dependency: transitive description: @@ -741,10 +758,10 @@ packages: dependency: transitive description: name: permission_handler_apple - sha256: "9c370ef6a18b1c4b2f7f35944d644a56aa23576f23abee654cf73968de93f163" + sha256: ee96ac32f5a8e6f80756e25b25b9f8e535816c8e6665a96b6d70681f8c4f7e85 url: "https://pub.dev" source: hosted - version: "9.0.7" + version: "9.0.8" permission_handler_platform_interface: dependency: transitive description: @@ -797,10 +814,10 @@ packages: dependency: transitive description: name: pointycastle - sha256: ae73e842cdd27a3467a71d70cefd9b198538aab4fc7dde1d0e8c78c96225abf0 + sha256: c3120a968135aead39699267f4c74bc9a08e4e909e86bc1b0af5bfd78691123c url: "https://pub.dev" source: hosted - version: "3.7.1" + version: "3.7.2" pool: dependency: transitive description: @@ -966,6 +983,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + sha256: "6b12a91cd2febdb6f7e7d92c00d1d0c01d88bffc7fe36b1ed236f0cc37cb5ca4" + url: "https://pub.dev" + source: hosted + version: "0.5.0" time: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index c8b4abe..40cf7ca 100755 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -49,6 +49,11 @@ dependencies: url: https://github.com/alexmercerind/media_kit ref: main path: media_kit_libs_macos_video + media_kit_libs_ios_video: + git: + url: https://github.com/alexmercerind/media_kit + ref: main + path: media_kit_libs_ios_video path_provider: permission_handler: universal_io: