refactor: related

This commit is contained in:
bggRGjQaUbCoE
2024-09-08 16:58:21 +08:00
parent 15c5755392
commit 2bcddc1097
8 changed files with 94 additions and 130 deletions

View File

@@ -275,7 +275,7 @@ class VideoHttp {
} }
// 相关视频 // 相关视频
static Future relatedVideoList({required String bvid}) async { static Future<LoadingState> relatedVideoList({required String bvid}) async {
var res = await Request().get(Api.relatedList, data: {'bvid': bvid}); var res = await Request().get(Api.relatedList, data: {'bvid': bvid});
if (res.data['code'] == 0) { if (res.data['code'] == 0) {
List<HotVideoItemModel> list = []; List<HotVideoItemModel> list = [];
@@ -285,9 +285,13 @@ class VideoHttp {
list.add(videoItem); list.add(videoItem);
} }
} }
return {'status': true, 'data': list}; if (list.isNotEmpty) {
return LoadingState.success(list);
} else {
return LoadingState.empty();
}
} else { } else {
return {'status': false, 'data': [], 'msg': res.data['message']}; return LoadingState.error(res.data['message']);
} }
} }

View File

@@ -3,4 +3,9 @@ import 'package:flutter/material.dart';
abstract class PopupController extends CommonController { abstract class PopupController extends CommonController {
List<OverlayEntry?> popupDialog = <OverlayEntry?>[]; List<OverlayEntry?> popupDialog = <OverlayEntry?>[];
void removePopupDialog() {
popupDialog.last?.remove();
popupDialog.removeLast();
}
} }

View File

@@ -102,15 +102,10 @@ class _HotPageState extends State<HotPage> with AutomaticKeepAliveClientMixin {
); );
} }
void _removePopupDialog() {
_hotController.popupDialog.last?.remove();
_hotController.popupDialog.removeLast();
}
OverlayEntry _createPopupDialog(videoItem) { OverlayEntry _createPopupDialog(videoItem) {
return OverlayEntry( return OverlayEntry(
builder: (context) => AnimatedDialog( builder: (context) => AnimatedDialog(
closeFn: _removePopupDialog, closeFn: _hotController.removePopupDialog,
videoItem: videoItem, videoItem: videoItem,
), ),
); );
@@ -152,7 +147,7 @@ class _HotPageState extends State<HotPage> with AutomaticKeepAliveClientMixin {
.add(_createPopupDialog(loadingState.response[index])); .add(_createPopupDialog(loadingState.response[index]));
Overlay.of(context).insert(_hotController.popupDialog.last!); Overlay.of(context).insert(_hotController.popupDialog.last!);
}, },
longPressEnd: _removePopupDialog, longPressEnd: _hotController.removePopupDialog,
); );
}, },
childCount: loadingState.response.length, childCount: loadingState.response.length,

View File

@@ -102,15 +102,10 @@ class _ZonePageState extends State<ZonePage>
); );
} }
void _removePopupDialog() {
_zoneController.popupDialog.last?.remove();
_zoneController.popupDialog.removeLast();
}
OverlayEntry _createPopupDialog(videoItem) { OverlayEntry _createPopupDialog(videoItem) {
return OverlayEntry( return OverlayEntry(
builder: (context) => AnimatedDialog( builder: (context) => AnimatedDialog(
closeFn: _removePopupDialog, closeFn: _zoneController.removePopupDialog,
videoItem: videoItem, videoItem: videoItem,
), ),
); );
@@ -153,7 +148,7 @@ class _ZonePageState extends State<ZonePage>
.add(_createPopupDialog(loadingState.response[index])); .add(_createPopupDialog(loadingState.response[index]));
Overlay.of(context).insert(_zoneController.popupDialog.last!); Overlay.of(context).insert(_zoneController.popupDialog.last!);
}, },
longPressEnd: _removePopupDialog, longPressEnd: _zoneController.removePopupDialog,
); );
}, },
childCount: loadingState.response.length, childCount: loadingState.response.length,

View File

@@ -114,15 +114,10 @@ class _RcmdPageState extends State<RcmdPage>
); );
} }
void _removePopupDialog() {
_controller.popupDialog.last?.remove();
_controller.popupDialog.removeLast();
}
OverlayEntry _createPopupDialog(videoItem) { OverlayEntry _createPopupDialog(videoItem) {
return OverlayEntry( return OverlayEntry(
builder: (context) => AnimatedDialog( builder: (context) => AnimatedDialog(
closeFn: _removePopupDialog, closeFn: _controller.removePopupDialog,
videoItem: videoItem, videoItem: videoItem,
), ),
); );
@@ -152,7 +147,7 @@ class _RcmdPageState extends State<RcmdPage>
Overlay.of(context) Overlay.of(context)
.insert(_controller.popupDialog.last!); .insert(_controller.popupDialog.last!);
}, },
longPressEnd: _removePopupDialog, longPressEnd: _controller.removePopupDialog,
) )
: LiveCardV( : LiveCardV(
liveItem: loadingState.response[index], liveItem: loadingState.response[index],
@@ -162,7 +157,7 @@ class _RcmdPageState extends State<RcmdPage>
Overlay.of(context) Overlay.of(context)
.insert(_controller.popupDialog.last!); .insert(_controller.popupDialog.last!);
}, },
longPressEnd: _removePopupDialog, longPressEnd: _controller.removePopupDialog,
) )
: const VideoCardVSkeleton(); : const VideoCardVSkeleton();
}, },

View File

@@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:PiliPalaX/http/loading_state.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';
@@ -480,7 +481,7 @@ class VideoIntroController extends GetxController {
final RelatedController relatedCtr = final RelatedController relatedCtr =
Get.find<RelatedController>(tag: heroTag); Get.find<RelatedController>(tag: heroTag);
relatedCtr.bvid = bvid; relatedCtr.bvid = bvid;
relatedCtr.queryRelatedVideo(); relatedCtr.queryData();
} catch (_) {} } catch (_) {}
// 重新请求评论 // 重新请求评论
try { try {
@@ -614,13 +615,13 @@ class VideoIntroController extends GetxController {
late RelatedController relatedCtr; late RelatedController relatedCtr;
try { try {
relatedCtr = Get.find<RelatedController>(tag: heroTag); relatedCtr = Get.find<RelatedController>(tag: heroTag);
if (relatedCtr.relatedVideoList.isEmpty) { if (relatedCtr.loadingState.value is Empty) {
SmartDialog.showToast('暂无相关视频,停止连播'); SmartDialog.showToast('暂无相关视频,停止连播');
return false; return false;
} }
} catch (_) { } catch (_) {
relatedCtr = Get.put(RelatedController(), tag: heroTag); relatedCtr = Get.put(RelatedController(), tag: heroTag);
relatedCtr.queryRelatedVideo().then((value) { relatedCtr.queryData().then((value) {
if (value['status']) { if (value['status']) {
playRelated(); playRelated();
} }
@@ -628,7 +629,8 @@ class VideoIntroController extends GetxController {
return false; return false;
} }
final HotVideoItemModel videoItem = relatedCtr.relatedVideoList[0]; final HotVideoItemModel videoItem =
(relatedCtr.loadingState.value as Success).response[0];
try { try {
if (videoItem.cid != null) { if (videoItem.cid != null) {
Get.offNamed('/video?bvid=${videoItem.bvid}&cid=${videoItem.cid}', Get.offNamed('/video?bvid=${videoItem.bvid}&cid=${videoItem.cid}',

View File

@@ -1,25 +1,19 @@
import 'package:flutter/material.dart'; import 'package:PiliPalaX/http/loading_state.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:PiliPalaX/pages/common/popup_controller.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:PiliPalaX/http/video.dart'; import 'package:PiliPalaX/http/video.dart';
import '../../../../models/model_hot_video_item.dart';
class RelatedController extends GetxController { class RelatedController extends PopupController {
// 视频aid // 视频aid
String bvid = Get.parameters['bvid'] ?? ""; String bvid = Get.parameters['bvid'] ?? "";
// 推荐视频列表
RxList relatedVideoList = <HotVideoItemModel>[].obs;
List<OverlayEntry?> popupDialog = <OverlayEntry?>[]; @override
void onInit() {
Future<dynamic> queryRelatedVideo() async { super.onInit();
return VideoHttp.relatedVideoList(bvid: bvid).then((value) { queryData();
if (value['status']) {
relatedVideoList.value = value['data'];
} else {
SmartDialog.showToast(value['msg']);
}
return value;
});
} }
@override
Future<LoadingState> customGetData() =>
VideoHttp.relatedVideoList(bvid: bvid);
} }

View File

@@ -1,3 +1,4 @@
import 'package:PiliPalaX/http/loading_state.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:PiliPalaX/common/skeleton/video_card_h.dart'; import 'package:PiliPalaX/common/skeleton/video_card_h.dart';
@@ -17,107 +18,80 @@ class RelatedVideoPanel extends StatefulWidget {
class _RelatedVideoPanelState extends State<RelatedVideoPanel> class _RelatedVideoPanelState extends State<RelatedVideoPanel>
with AutomaticKeepAliveClientMixin { with AutomaticKeepAliveClientMixin {
late RelatedController _relatedController; late final RelatedController _relatedController =
late Future _futureBuilder; Get.put(RelatedController(), tag: widget.heroTag);
@override @override
bool get wantKeepAlive => true; bool get wantKeepAlive => true;
@override
void initState() {
super.initState();
_relatedController = Get.put(RelatedController(), tag: widget.heroTag);
_futureBuilder = _relatedController.queryRelatedVideo();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
super.build(context); super.build(context);
return SliverPadding( return SliverPadding(
padding: const EdgeInsets.all(StyleString.safeSpace), padding: const EdgeInsets.all(StyleString.safeSpace),
sliver: FutureBuilder( sliver: Obx(() => _buildBody(_relatedController.loadingState.value)),
future: _futureBuilder, );
builder: (BuildContext context, AsyncSnapshot snapshot) { }
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.data == null) { OverlayEntry _createPopupDialog(videoItem) {
return const SliverToBoxAdapter(child: SizedBox()); return OverlayEntry(
} builder: (BuildContext context) => AnimatedDialog(
if (snapshot.data!['status'] && snapshot.hasData) { closeFn: _relatedController.removePopupDialog,
RxList relatedVideoList = _relatedController.relatedVideoList; videoItem: videoItem,
// 请求成功 ),
return Obx( );
() => SliverGrid( }
gridDelegate: SliverGridDelegateWithExtentAndRatio(
mainAxisSpacing: StyleString.safeSpace, Widget _buildBody(LoadingState loadingState) {
crossAxisSpacing: StyleString.safeSpace, return loadingState is Success
maxCrossAxisExtent: Grid.maxRowWidth * 2, ? SliverGrid(
childAspectRatio: StyleString.aspectRatio * 2.4, gridDelegate: SliverGridDelegateWithExtentAndRatio(
mainAxisExtent: 0), mainAxisSpacing: StyleString.safeSpace,
delegate: SliverChildBuilderDelegate((context, index) { crossAxisSpacing: StyleString.safeSpace,
if (index == relatedVideoList.length) { maxCrossAxisExtent: Grid.maxRowWidth * 2,
return SizedBox( childAspectRatio: StyleString.aspectRatio * 2.4,
height: MediaQuery.of(context).padding.bottom); mainAxisExtent: 0),
} else { delegate: SliverChildBuilderDelegate((context, index) {
return Material( if (index == loadingState.response.length) {
child: VideoCardH( return SizedBox(height: MediaQuery.of(context).padding.bottom);
videoItem: relatedVideoList[index], } else {
showPubdate: true, return Material(
longPress: () { child: VideoCardH(
try { videoItem: loadingState.response[index],
_relatedController.popupDialog.add( showPubdate: true,
_createPopupDialog(_relatedController longPress: () {
.relatedVideoList[index])); _relatedController.popupDialog.add(
Overlay.of(context).insert( _createPopupDialog(loadingState.response[index]));
_relatedController.popupDialog.last!); Overlay.of(context)
} catch (err) { .insert(_relatedController.popupDialog.last!);
return {}; },
} longPressEnd: _relatedController.removePopupDialog,
},
longPressEnd: _removePopupDialog,
),
);
}
}, childCount: relatedVideoList.length + 1),
), ),
); );
} else {
// 请求错误
return HttpError(
errMsg: '出错了',
fn: () {
_futureBuilder = _relatedController.queryRelatedVideo();
_futureBuilder.then((value) => setState(() {}));
});
} }
} else { }, childCount: loadingState.response.length + 1),
// 骨架屏 )
return SliverGrid( : loadingState is Error
? HttpError(
errMsg: '出错了',
fn: () {
_relatedController.loadingState.value =
LoadingState.loading();
_relatedController.queryData();
})
: SliverGrid(
gridDelegate: SliverGridDelegateWithExtentAndRatio( gridDelegate: SliverGridDelegateWithExtentAndRatio(
mainAxisSpacing: StyleString.safeSpace, mainAxisSpacing: StyleString.safeSpace,
crossAxisSpacing: StyleString.safeSpace, crossAxisSpacing: StyleString.safeSpace,
maxCrossAxisExtent: Grid.maxRowWidth * 2, maxCrossAxisExtent: Grid.maxRowWidth * 2,
childAspectRatio: StyleString.aspectRatio * 2.4, childAspectRatio: StyleString.aspectRatio * 2.4,
mainAxisExtent: 0), mainAxisExtent: 0),
delegate: SliverChildBuilderDelegate((context, index) { delegate: SliverChildBuilderDelegate(
return const VideoCardHSkeleton(); (context, index) {
}, childCount: 5), return const VideoCardHSkeleton();
},
childCount: 5,
),
); );
}
},
));
}
void _removePopupDialog() {
_relatedController.popupDialog.last?.remove();
_relatedController.popupDialog.removeLast();
}
OverlayEntry _createPopupDialog(videoItem) {
return OverlayEntry(
builder: (BuildContext context) => AnimatedDialog(
closeFn: _removePopupDialog,
videoItem: videoItem,
),
);
} }
} }