refactor: bangumi intro

This commit is contained in:
bggRGjQaUbCoE
2024-09-12 17:47:58 +08:00
parent 5a72da5085
commit 8197bf116d
7 changed files with 94 additions and 78 deletions

View File

@@ -146,6 +146,22 @@ class SearchHttp {
} }
} }
static Future<LoadingState> bangumiInfoNew({int? seasonId, int? epId}) async {
final dynamic res = await Request().get(
Api.bangumiInfo,
data: {
if (seasonId != null) 'season_id': seasonId,
if (epId != null) 'ep_id': epId,
},
);
if (res.data['code'] == 0) {
return LoadingState.success(
BangumiInfoModel.fromJson(res.data['result']));
} else {
return LoadingState.error(res.data['message']);
}
}
static Future<Map<String, dynamic>> bangumiInfo( static Future<Map<String, dynamic>> bangumiInfo(
{int? seasonId, int? epId}) async { {int? seasonId, int? epId}) async {
final Map<String, dynamic> data = {}; final Map<String, dynamic> data = {};

View File

@@ -1,3 +1,5 @@
import 'package:PiliPalaX/http/loading_state.dart';
import 'package:PiliPalaX/pages/common/common_controller.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
@@ -17,7 +19,7 @@ import 'package:PiliPalaX/utils/storage.dart';
import 'package:share_plus/share_plus.dart'; import 'package:share_plus/share_plus.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
class BangumiIntroController extends GetxController { class BangumiIntroController extends CommonController {
// 视频bvid // 视频bvid
String bvid = Get.parameters['bvid'] ?? ''; String bvid = Get.parameters['bvid'] ?? '';
var seasonId = Get.parameters['seasonId'] != null var seasonId = Get.parameters['seasonId'] != null
@@ -34,15 +36,6 @@ class BangumiIntroController extends GetxController {
Map? videoItem = {}; Map? videoItem = {};
BangumiInfoModel? bangumiItem; BangumiInfoModel? bangumiItem;
// 请求状态
RxBool isLoading = false.obs;
// 视频详情 请求返回
Rx<BangumiInfoModel> bangumiDetail = BangumiInfoModel().obs;
// 请求返回的信息
String responseMsg = '请求异常';
// up主粉丝数 // up主粉丝数
Map userStat = {'follower': '-'}; Map userStat = {'follower': '-'};
@@ -88,10 +81,7 @@ class BangumiIntroController extends GetxController {
} }
userInfo = userInfoCache.get('userInfoCache'); userInfo = userInfoCache.get('userInfoCache');
userLogin = userInfo != null; userLogin = userInfo != null;
}
// 获取番剧简介&选集
Future queryBangumiIntro() async {
if (userLogin) { if (userLogin) {
// 获取点赞状态 // 获取点赞状态
queryHasLikeVideo(); queryHasLikeVideo();
@@ -100,16 +90,21 @@ class BangumiIntroController extends GetxController {
// 获取收藏状态 // 获取收藏状态
queryHasFavVideo(); queryHasFavVideo();
} }
var result = await SearchHttp.bangumiInfo(seasonId: seasonId, epId: epId);
if (result['status']) { queryData();
bangumiDetail.value = result['data'];
epId = bangumiDetail.value.episodes!.first.id;
} else {
SmartDialog.showToast(result['msg']);
}
return result;
} }
@override
bool customHandleResponse(Success response) {
epId = response.response.episodes!.first.id;
loadingState.value = response;
return true;
}
@override
Future<LoadingState> customGetData() =>
SearchHttp.bangumiInfoNew(seasonId: seasonId, epId: epId);
// 获取点赞状态 // 获取点赞状态
Future queryHasLikeVideo() async { Future queryHasLikeVideo() async {
var result = await VideoHttp.hasLikeVideo(bvid: bvid); var result = await VideoHttp.hasLikeVideo(bvid: bvid);
@@ -139,8 +134,10 @@ class BangumiIntroController extends GetxController {
if (result['status']) { if (result['status']) {
SmartDialog.showToast(!hasLike.value ? result['data']['toast'] : '取消赞'); SmartDialog.showToast(!hasLike.value ? result['data']['toast'] : '取消赞');
hasLike.value = !hasLike.value; hasLike.value = !hasLike.value;
bangumiDetail.value.stat!['likes'] = dynamic bangumiDetail = (loadingState.value as Success).response;
bangumiDetail.value.stat!['likes'] + (!hasLike.value ? 1 : -1); bangumiDetail.stat!['likes'] =
bangumiDetail.stat!['likes'] + (!hasLike.value ? 1 : -1);
loadingState.value = LoadingState.success(bangumiDetail);
hasLike.refresh(); hasLike.refresh();
} else { } else {
SmartDialog.showToast(result['msg']); SmartDialog.showToast(result['msg']);
@@ -193,8 +190,11 @@ class BangumiIntroController extends GetxController {
if (res['status']) { if (res['status']) {
SmartDialog.showToast('投币成功'); SmartDialog.showToast('投币成功');
hasCoin.value = true; hasCoin.value = true;
bangumiDetail.value.stat!['coins'] = dynamic bangumiDetail =
bangumiDetail.value.stat!['coins'] + _tempThemeValue; (loadingState.value as Success).response;
bangumiDetail.stat!['coins'] =
bangumiDetail.stat!['coins'] + _tempThemeValue;
loadingState.value = LoadingState.success(bangumiDetail);
} else { } else {
SmartDialog.showToast(res['msg']); SmartDialog.showToast(res['msg']);
} }
@@ -300,15 +300,15 @@ class BangumiIntroController extends GetxController {
// 追番 // 追番
Future bangumiAdd() async { Future bangumiAdd() async {
var result = var result = await VideoHttp.bangumiAdd(
await VideoHttp.bangumiAdd(seasonId: bangumiDetail.value.seasonId); seasonId: (loadingState.value as Success).response.seasonId);
SmartDialog.showToast(result['msg']); SmartDialog.showToast(result['msg']);
} }
// 取消追番 // 取消追番
Future bangumiDel() async { Future bangumiDel() async {
var result = var result = await VideoHttp.bangumiDel(
await VideoHttp.bangumiDel(seasonId: bangumiDetail.value.seasonId); seasonId: (loadingState.value as Success).response.seasonId);
SmartDialog.showToast(result['msg']); SmartDialog.showToast(result['msg']);
} }
@@ -323,8 +323,8 @@ class BangumiIntroController extends GetxController {
bool prevPlay() { bool prevPlay() {
late List episodes; late List episodes;
if (bangumiDetail.value.episodes != null) { if ((loadingState.value as Success).response.episodes != null) {
episodes = bangumiDetail.value.episodes!; episodes = (loadingState.value as Success).response.episodes!;
} }
VideoDetailController videoDetailCtr = VideoDetailController videoDetailCtr =
Get.find<VideoDetailController>(tag: Get.arguments['heroTag']); Get.find<VideoDetailController>(tag: Get.arguments['heroTag']);
@@ -353,8 +353,8 @@ class BangumiIntroController extends GetxController {
Get.find<VideoDetailController>(tag: Get.arguments['heroTag']); Get.find<VideoDetailController>(tag: Get.arguments['heroTag']);
PlayRepeat platRepeat = videoDetailCtr.plPlayerController.playRepeat; PlayRepeat platRepeat = videoDetailCtr.plPlayerController.playRepeat;
if (bangumiDetail.value.episodes != null) { if ((loadingState.value as Success).response.episodes != null) {
episodes = bangumiDetail.value.episodes!; episodes = (loadingState.value as Success).response.episodes!;
} else { } else {
if (platRepeat == PlayRepeat.autoPlayRelated) { if (platRepeat == PlayRepeat.autoPlayRelated) {
return playRelated(); return playRelated();

View File

@@ -1,3 +1,5 @@
import 'package:PiliPalaX/common/widgets/http_error.dart';
import 'package:PiliPalaX/http/loading_state.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
@@ -36,7 +38,6 @@ class _BangumiIntroPanelState extends State<BangumiIntroPanel>
with AutomaticKeepAliveClientMixin { with AutomaticKeepAliveClientMixin {
late BangumiIntroController bangumiIntroController; late BangumiIntroController bangumiIntroController;
late VideoDetailController videoDetailCtr; late VideoDetailController videoDetailCtr;
BangumiInfoModel? bangumiDetail;
late Future _futureBuilderFuture; late Future _futureBuilderFuture;
late int cid; late int cid;
late String heroTag; late String heroTag;
@@ -53,10 +54,6 @@ class _BangumiIntroPanelState extends State<BangumiIntroPanel>
cid = widget.cid!; cid = widget.cid!;
bangumiIntroController = Get.put(BangumiIntroController(), tag: heroTag); bangumiIntroController = Get.put(BangumiIntroController(), tag: heroTag);
videoDetailCtr = Get.find<VideoDetailController>(tag: heroTag); videoDetailCtr = Get.find<VideoDetailController>(tag: heroTag);
bangumiIntroController.bangumiDetail.listen((BangumiInfoModel value) {
bangumiDetail = value;
});
_futureBuilderFuture = bangumiIntroController.queryBangumiIntro();
videoDetailCtr.cid.listen((int p0) { videoDetailCtr.cid.listen((int p0) {
cid = p0; cid = p0;
if (!mounted) return; if (!mounted) return;
@@ -67,35 +64,26 @@ class _BangumiIntroPanelState extends State<BangumiIntroPanel>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
super.build(context); super.build(context);
return FutureBuilder( return Obx(() => _buildBody(bangumiIntroController.loadingState.value));
future: _futureBuilderFuture, }
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.data['status']) {
// 请求成功
return BangumiInfo( _buildBody(LoadingState loadingState) {
loadingStatus: false, return loadingState is Success
bangumiDetail: bangumiDetail, ? BangumiInfo(
cid: cid, loadingStatus: false,
); bangumiDetail: loadingState.response,
} else {
// 请求错误
// return HttpError(
// errMsg: snapshot.data['msg'],
// fn: () => Get.back(),
// );
return const SizedBox();
}
} else {
return BangumiInfo(
loadingStatus: true,
bangumiDetail: bangumiDetail,
cid: cid, cid: cid,
); )
} : loadingState is Error
}, ? HttpError(
); errMsg: loadingState.errMsg,
fn: bangumiIntroController.onReload,
)
: BangumiInfo(
loadingStatus: true,
bangumiDetail: null,
cid: cid,
);
} }
} }
@@ -218,7 +206,7 @@ class _BangumiInfoState extends State<BangumiInfo> {
const SizedBox(width: 10), const SizedBox(width: 10),
Expanded( Expanded(
child: InkWell( child: InkWell(
onTap: () => showIntroDetail(), onTap: showIntroDetail,
child: SizedBox( child: SizedBox(
height: isLandscape ? 103 : 158, height: isLandscape ? 103 : 158,
child: Column( child: Column(

View File

@@ -325,7 +325,7 @@ class VideoContent extends StatelessWidget {
videoItem.title, videoItem.title,
textAlign: TextAlign.start, textAlign: TextAlign.start,
style: const TextStyle( style: const TextStyle(
fontWeight: FontWeight.w600, fontWeight: FontWeight.w400,
letterSpacing: 0.3, letterSpacing: 0.3,
), ),
maxLines: videoItem.videos > 1 ? 1 : 2, maxLines: videoItem.videos > 1 ? 1 : 2,

View File

@@ -3,6 +3,7 @@ import 'dart:io';
import 'dart:math'; import 'dart:math';
import 'package:PiliPalaX/common/constants.dart'; import 'package:PiliPalaX/common/constants.dart';
import 'package:PiliPalaX/http/loading_state.dart';
import 'package:PiliPalaX/utils/extension.dart'; import 'package:PiliPalaX/utils/extension.dart';
import 'package:auto_orientation/auto_orientation.dart'; import 'package:auto_orientation/auto_orientation.dart';
import 'package:floating/floating.dart'; import 'package:floating/floating.dart';
@@ -90,15 +91,21 @@ class _VideoDetailPageState extends State<VideoDetailPage>
value, videoDetailController.cid.value); value, videoDetailController.cid.value);
}); });
bangumiIntroController = Get.put(BangumiIntroController(), tag: heroTag); bangumiIntroController = Get.put(BangumiIntroController(), tag: heroTag);
bangumiIntroController.bangumiDetail.listen((value) { bangumiIntroController.loadingState.listen((value) {
if (!context.mounted) return; if (!context.mounted) return;
videoPlayerServiceHandler.onVideoDetailChange( if (value is Success) {
value, videoDetailController.cid.value); videoPlayerServiceHandler.onVideoDetailChange(
value.response,
videoDetailController.cid.value,
);
}
}); });
videoDetailController.cid.listen((p0) { videoDetailController.cid.listen((p0) {
if (!context.mounted) return; if (!context.mounted) return;
videoPlayerServiceHandler.onVideoDetailChange( videoPlayerServiceHandler.onVideoDetailChange(
bangumiIntroController.bangumiDetail.value, p0); (bangumiIntroController.loadingState.value as Success).response,
p0,
);
}); });
autoExitFullscreen = autoExitFullscreen =
setting.get(SettingBoxKey.enableAutoExit, defaultValue: true); setting.get(SettingBoxKey.enableAutoExit, defaultValue: true);
@@ -272,7 +279,6 @@ class _VideoDetailPageState extends State<VideoDetailPage>
floating.dispose(); floating.dispose();
videoDetailController.floating?.dispose(); videoDetailController.floating?.dispose();
videoIntroController.videoDetail.close(); videoIntroController.videoDetail.close();
bangumiIntroController.bangumiDetail.close();
videoDetailController.cid.close(); videoDetailController.cid.close();
if (!horizontalScreen) { if (!horizontalScreen) {
AutoOrientation.portraitUpMode(); AutoOrientation.portraitUpMode();
@@ -650,7 +656,8 @@ class _VideoDetailPageState extends State<VideoDetailPage>
(horizontalScreen || (horizontalScreen ||
MediaQuery.of(context).orientation == MediaQuery.of(context).orientation ==
Orientation.portrait), Orientation.portrait),
onPopInvokedWithResult: (bool didPop, Object? result) { onPopInvokedWithResult:
(bool didPop, Object? result) {
if (isFullScreen.value == true) { if (isFullScreen.value == true) {
plPlayerController! plPlayerController!
.triggerFullScreen(status: false); .triggerFullScreen(status: false);

View File

@@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:ui'; import 'dart:ui';
import 'package:PiliPalaX/http/loading_state.dart';
import 'package:PiliPalaX/pages/video/detail/introduction/controller.dart'; import 'package:PiliPalaX/pages/video/detail/introduction/controller.dart';
import 'package:PiliPalaX/utils/id_utils.dart'; import 'package:PiliPalaX/utils/id_utils.dart';
import 'package:easy_debounce/easy_throttle.dart'; import 'package:easy_debounce/easy_throttle.dart';
@@ -226,7 +227,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
bool isSeason = videoIntroController?.videoDetail.value.ugcSeason != null; bool isSeason = videoIntroController?.videoDetail.value.ugcSeason != null;
bool isPage = videoIntroController?.videoDetail.value.pages != null && bool isPage = videoIntroController?.videoDetail.value.pages != null &&
videoIntroController!.videoDetail.value.pages!.length > 1; videoIntroController!.videoDetail.value.pages!.length > 1;
bool isBangumi = bangumiIntroController?.bangumiDetail.value != null; bool isBangumi = bangumiIntroController?.loadingState.value is Success;
bool anySeason = isSeason || isPage || isBangumi; bool anySeason = isSeason || isPage || isBangumi;
Map<BottomControlType, Widget> videoProgressWidgets = { Map<BottomControlType, Widget> videoProgressWidgets = {
/// 上一集 /// 上一集
@@ -357,7 +358,9 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
changeFucCall = videoIntroController!.changeSeasonOrbangu; changeFucCall = videoIntroController!.changeSeasonOrbangu;
} else if (isBangumi) { } else if (isBangumi) {
episodes.addAll( episodes.addAll(
bangumiIntroController!.bangumiDetail.value.episodes!); (bangumiIntroController!.loadingState.value as Success)
.response
.episodes!);
changeFucCall = bangumiIntroController!.changeSeasonOrbangu; changeFucCall = bangumiIntroController!.changeSeasonOrbangu;
} }
ListSheet( ListSheet(
@@ -1241,7 +1244,8 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
Duration.zero, Duration.zero,
player.state.duration, player.state.duration,
); );
widget.controller.seekTo(result, type: 'slider'); widget.controller
.seekTo(result, type: 'slider');
widget.controller.play(); widget.controller.play();
}, },
), ),
@@ -1286,7 +1290,8 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
Duration.zero, Duration.zero,
player.state.duration, player.state.duration,
); );
widget.controller.seekTo(result, type: 'slider'); widget.controller
.seekTo(result, type: 'slider');
widget.controller.play(); widget.controller.play();
}, },
), ),

View File

@@ -111,7 +111,7 @@ class VideoPlayerServiceHandler extends BaseAudioHandler with SeekHandler {
if (!PlPlayerController.instanceExists()) return; if (!PlPlayerController.instanceExists()) return;
if (data == null) return; if (data == null) return;
late MediaItem? mediaItem; MediaItem? mediaItem;
if (data is VideoDetailData) { if (data is VideoDetailData) {
if ((data.pages?.length ?? 0) > 1) { if ((data.pages?.length ?? 0) > 1) {
final current = data.pages?.firstWhere((element) => element.cid == cid); final current = data.pages?.firstWhere((element) => element.cid == cid);