mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
refactor: related
This commit is contained in:
@@ -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']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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}',
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user