import 'dart:io'; import 'package:better_player_plus/better_player_plus.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:go_router/go_router.dart'; import 'package:news_app/ui/video/video_detail_page.dart'; import 'package:news_app/ui/video/video_recommend_list_page.dart'; import '../../constant/config.dart'; import '../../gen/assets.gen.dart'; import '../../model/video_new_model.dart'; import '../../util/device_util.dart'; import '../../util/share_util.dart'; import '../../widget/auth_gesture_detector.dart'; import '../../widget/load_image.dart'; import '../../widget/my_txt.dart'; class VideoPlayItemWidget extends ConsumerStatefulWidget { final VideoNewModel item; final bool isActive; const VideoPlayItemWidget({ super.key, required this.item, required this.isActive, }); @override ConsumerState createState() => _VideoItemWidgetState(); } class _VideoItemWidgetState extends ConsumerState { late BetterPlayerController _controller; bool _isPlaying = false; bool _isWeChatInstalled = false; Future _checkWeChatInstallation() async { if (Platform.isAndroid) { final installed = await isWeChatInstalledOnlyAndroid(); setState(() => _isWeChatInstalled = installed); } else if (Platform.isIOS) { final installed = await fluwx.isWeChatInstalled; setState(() => _isWeChatInstalled = installed); } } Future shareAction(VideoNewModel data) async { showModalBottomSheet( context: context, builder: (context) => SafeArea( child: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SizedBox(height: 10.h), Container( width: double.infinity, height: 80.h, decoration: BoxDecoration( borderRadius: BorderRadius.only( topLeft: Radius.circular(10.r), topRight: Radius.circular(10.r), ), color: Colors.white, ), child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ if (_isWeChatInstalled) GestureDetector( onTap: () { Navigator.pop(context); shareWeiXinUrl( title: data.shareDesc ?? "", url: data.shareUrl ?? "", ); }, child: Container( width: 100.w, height: 80.h, child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ LoadAssetImage( 'share_wxhy', width: 40.w, height: 40.h, ), SizedBox(height: 10.h), myTxt( text: "微信好友", color: Colors.black, fontSize: 12.sp, fontWeight: FontWeight.bold, ), ], ), ), ), if (_isWeChatInstalled) GestureDetector( onTap: () { Navigator.pop(context); shareWeiXinPYUrl( title: data.shareDesc ?? "", url: data.shareUrl ?? "", ); }, child: Container( width: 100.w, height: 80.h, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ LoadAssetImage( 'share_pyq', width: 40.w, height: 40.h, ), SizedBox(height: 10.h), myTxt( text: "朋友圈", color: Colors.black, fontSize: 12.sp, fontWeight: FontWeight.bold, ), ], ), ), ), GestureDetector( onTap: () { Navigator.pop(context); shareUrl( title: data.shareDesc ?? "", url: data.shareUrl ?? "", ); }, child: Container( width: 100.w, height: 80.h, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ LoadAssetImage( 'share_xtfx', width: 40.w, height: 40.h, ), SizedBox(height: 10.h), myTxt( text: "系统分享", color: Colors.black, fontSize: 12.sp, fontWeight: FontWeight.bold, ), ], ), ), ), ], ), ), ], ), ), ); } @override void initState() { super.initState(); _checkWeChatInstallation(); _controller = BetterPlayerController( BetterPlayerConfiguration( autoPlay: false, looping: true, aspectRatio: 16 / 9, fit: BoxFit.fitWidth, controlsConfiguration: const BetterPlayerControlsConfiguration( showControls: false, ), ), betterPlayerDataSource: BetterPlayerDataSource( BetterPlayerDataSourceType.network, widget.item.url ?? "", ), ); _controller.addEventsListener(_handlePlayerEvent); // 如果初始化时就是激活状态,立即播放 if (widget.isActive && mounted) { _controller.play(); } } void _handlePlayerEvent(BetterPlayerEvent event) { if (!mounted) return; if (event.betterPlayerEventType == BetterPlayerEventType.play || event.betterPlayerEventType == BetterPlayerEventType.pause || event.betterPlayerEventType == BetterPlayerEventType.finished) { final isPlaying = _controller.isPlaying() ?? false; if (mounted && isPlaying != _isPlaying) { setState(() { _isPlaying = isPlaying; }); } } } @override void didUpdateWidget(covariant VideoPlayItemWidget oldWidget) { super.didUpdateWidget(oldWidget); if (!mounted) return; if (widget.isActive && !oldWidget.isActive) { _controller.play(); } else if (!widget.isActive && oldWidget.isActive) { _controller.pause(); } } @override void dispose() { _controller.removeEventsListener(_handlePlayerEvent); _controller.dispose(); super.dispose(); } void _togglePlay() { if (!mounted) return; if (_isPlaying) { _controller.pause(); } else { _controller.play(); } } @override Widget build(BuildContext context) { return GestureDetector( onTap: _togglePlay, child: Stack( fit: StackFit.expand, children: [ ColoredBox( color: Colors.black, child: BetterPlayer(controller: _controller), ), if (!_isPlaying) Center( child: Image.asset( Assets.images.playIcon.path, width: 60.w, height: 60.w, ), ), Positioned( right: 10.h, bottom: 100.h, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ AuthGestureDetector( onTap: () { ref .read(recommendListProvider.notifier) .fetchVideoLike( videoId: widget.item.contentId, current: widget.item.isLiked ?? false, ); }, child: Icon( Icons.favorite, color: widget.item.isLiked == true ? Colors.red : Colors.white, size: 25.sp, ), ), myTxt( text: widget.item.likeCount == null ? "" : widget.item.likeCount.toString(), color: Colors.white, fontSize: 12.sp, ), SizedBox(height: 15.h), AuthGestureDetector( onTap: () { context.push( "/video/detail", extra: VideoParam( id: widget.item.contentId ?? "", videoUrl: widget.item.url, ), ); }, child: Icon(Icons.message, color: Colors.white, size: 25.sp), ), myTxt( text: widget.item.commentCount == null ? "0" : widget.item.commentCount.toString(), color: Colors.white, fontSize: 12.sp, ), SizedBox(height: 15.h), AuthGestureDetector( onTap: () { ref .read(recommendListProvider.notifier) .fetchVideoFavorite( videoId: widget.item.contentId, current: widget.item.isFavorite ?? false, ); }, child: Icon( Icons.star, color: widget.item.isFavorite == true ? Colors.red : Colors.white, size: 25.sp, ), ), myTxt( text: widget.item.favoriteCount == null ? "0" : widget.item.favoriteCount.toString(), color: Colors.white, fontSize: 12.sp, ), SizedBox(height: 15.h), GestureDetector( onTap: () { // shareUrl( // title: widget.item.shareDesc ?? "", // url: widget.item.shareUrl ?? "", // ); shareAction(widget.item); if (uuid.isNotEmpty) { ref .read(recommendListProvider.notifier) .fetchVideoShare(contentId: widget.item.contentId); } }, child: Icon( Icons.screen_share, color: Colors.white, size: 25.sp, ), ), myTxt( text: widget.item.shareCount == null ? "0" : widget.item.shareCount.toString(), color: Colors.white, fontSize: 12.sp, ), ], ), ), ], ), ); } }