mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
refactor: related
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:PiliPalaX/http/loading_state.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
@@ -480,7 +481,7 @@ class VideoIntroController extends GetxController {
|
||||
final RelatedController relatedCtr =
|
||||
Get.find<RelatedController>(tag: heroTag);
|
||||
relatedCtr.bvid = bvid;
|
||||
relatedCtr.queryRelatedVideo();
|
||||
relatedCtr.queryData();
|
||||
} catch (_) {}
|
||||
// 重新请求评论
|
||||
try {
|
||||
@@ -614,13 +615,13 @@ class VideoIntroController extends GetxController {
|
||||
late RelatedController relatedCtr;
|
||||
try {
|
||||
relatedCtr = Get.find<RelatedController>(tag: heroTag);
|
||||
if (relatedCtr.relatedVideoList.isEmpty) {
|
||||
if (relatedCtr.loadingState.value is Empty) {
|
||||
SmartDialog.showToast('暂无相关视频,停止连播');
|
||||
return false;
|
||||
}
|
||||
} catch (_) {
|
||||
relatedCtr = Get.put(RelatedController(), tag: heroTag);
|
||||
relatedCtr.queryRelatedVideo().then((value) {
|
||||
relatedCtr.queryData().then((value) {
|
||||
if (value['status']) {
|
||||
playRelated();
|
||||
}
|
||||
@@ -628,7 +629,8 @@ class VideoIntroController extends GetxController {
|
||||
return false;
|
||||
}
|
||||
|
||||
final HotVideoItemModel videoItem = relatedCtr.relatedVideoList[0];
|
||||
final HotVideoItemModel videoItem =
|
||||
(relatedCtr.loadingState.value as Success).response[0];
|
||||
try {
|
||||
if (videoItem.cid != null) {
|
||||
Get.offNamed('/video?bvid=${videoItem.bvid}&cid=${videoItem.cid}',
|
||||
|
||||
@@ -1,25 +1,19 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:PiliPalaX/http/loading_state.dart';
|
||||
import 'package:PiliPalaX/pages/common/popup_controller.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:PiliPalaX/http/video.dart';
|
||||
import '../../../../models/model_hot_video_item.dart';
|
||||
|
||||
class RelatedController extends GetxController {
|
||||
class RelatedController extends PopupController {
|
||||
// 视频aid
|
||||
String bvid = Get.parameters['bvid'] ?? "";
|
||||
// 推荐视频列表
|
||||
RxList relatedVideoList = <HotVideoItemModel>[].obs;
|
||||
|
||||
List<OverlayEntry?> popupDialog = <OverlayEntry?>[];
|
||||
|
||||
Future<dynamic> queryRelatedVideo() async {
|
||||
return VideoHttp.relatedVideoList(bvid: bvid).then((value) {
|
||||
if (value['status']) {
|
||||
relatedVideoList.value = value['data'];
|
||||
} else {
|
||||
SmartDialog.showToast(value['msg']);
|
||||
}
|
||||
return value;
|
||||
});
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
queryData();
|
||||
}
|
||||
|
||||
@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:get/get.dart';
|
||||
import 'package:PiliPalaX/common/skeleton/video_card_h.dart';
|
||||
@@ -17,107 +18,80 @@ class RelatedVideoPanel extends StatefulWidget {
|
||||
|
||||
class _RelatedVideoPanelState extends State<RelatedVideoPanel>
|
||||
with AutomaticKeepAliveClientMixin {
|
||||
late RelatedController _relatedController;
|
||||
late Future _futureBuilder;
|
||||
late final RelatedController _relatedController =
|
||||
Get.put(RelatedController(), tag: widget.heroTag);
|
||||
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_relatedController = Get.put(RelatedController(), tag: widget.heroTag);
|
||||
_futureBuilder = _relatedController.queryRelatedVideo();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
return SliverPadding(
|
||||
padding: const EdgeInsets.all(StyleString.safeSpace),
|
||||
sliver: FutureBuilder(
|
||||
future: _futureBuilder,
|
||||
builder: (BuildContext context, AsyncSnapshot snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.done) {
|
||||
if (snapshot.data == null) {
|
||||
return const SliverToBoxAdapter(child: SizedBox());
|
||||
}
|
||||
if (snapshot.data!['status'] && snapshot.hasData) {
|
||||
RxList relatedVideoList = _relatedController.relatedVideoList;
|
||||
// 请求成功
|
||||
return Obx(
|
||||
() => SliverGrid(
|
||||
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||
mainAxisSpacing: StyleString.safeSpace,
|
||||
crossAxisSpacing: StyleString.safeSpace,
|
||||
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
||||
childAspectRatio: StyleString.aspectRatio * 2.4,
|
||||
mainAxisExtent: 0),
|
||||
delegate: SliverChildBuilderDelegate((context, index) {
|
||||
if (index == relatedVideoList.length) {
|
||||
return SizedBox(
|
||||
height: MediaQuery.of(context).padding.bottom);
|
||||
} else {
|
||||
return Material(
|
||||
child: VideoCardH(
|
||||
videoItem: relatedVideoList[index],
|
||||
showPubdate: true,
|
||||
longPress: () {
|
||||
try {
|
||||
_relatedController.popupDialog.add(
|
||||
_createPopupDialog(_relatedController
|
||||
.relatedVideoList[index]));
|
||||
Overlay.of(context).insert(
|
||||
_relatedController.popupDialog.last!);
|
||||
} catch (err) {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
longPressEnd: _removePopupDialog,
|
||||
),
|
||||
);
|
||||
}
|
||||
}, childCount: relatedVideoList.length + 1),
|
||||
padding: const EdgeInsets.all(StyleString.safeSpace),
|
||||
sliver: Obx(() => _buildBody(_relatedController.loadingState.value)),
|
||||
);
|
||||
}
|
||||
|
||||
OverlayEntry _createPopupDialog(videoItem) {
|
||||
return OverlayEntry(
|
||||
builder: (BuildContext context) => AnimatedDialog(
|
||||
closeFn: _relatedController.removePopupDialog,
|
||||
videoItem: videoItem,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBody(LoadingState loadingState) {
|
||||
return loadingState is Success
|
||||
? SliverGrid(
|
||||
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||
mainAxisSpacing: StyleString.safeSpace,
|
||||
crossAxisSpacing: StyleString.safeSpace,
|
||||
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
||||
childAspectRatio: StyleString.aspectRatio * 2.4,
|
||||
mainAxisExtent: 0),
|
||||
delegate: SliverChildBuilderDelegate((context, index) {
|
||||
if (index == loadingState.response.length) {
|
||||
return SizedBox(height: MediaQuery.of(context).padding.bottom);
|
||||
} else {
|
||||
return Material(
|
||||
child: VideoCardH(
|
||||
videoItem: loadingState.response[index],
|
||||
showPubdate: true,
|
||||
longPress: () {
|
||||
_relatedController.popupDialog.add(
|
||||
_createPopupDialog(loadingState.response[index]));
|
||||
Overlay.of(context)
|
||||
.insert(_relatedController.popupDialog.last!);
|
||||
},
|
||||
longPressEnd: _relatedController.removePopupDialog,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
// 请求错误
|
||||
return HttpError(
|
||||
errMsg: '出错了',
|
||||
fn: () {
|
||||
_futureBuilder = _relatedController.queryRelatedVideo();
|
||||
_futureBuilder.then((value) => setState(() {}));
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// 骨架屏
|
||||
return SliverGrid(
|
||||
}, childCount: loadingState.response.length + 1),
|
||||
)
|
||||
: loadingState is Error
|
||||
? HttpError(
|
||||
errMsg: '出错了',
|
||||
fn: () {
|
||||
_relatedController.loadingState.value =
|
||||
LoadingState.loading();
|
||||
_relatedController.queryData();
|
||||
})
|
||||
: SliverGrid(
|
||||
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||
mainAxisSpacing: StyleString.safeSpace,
|
||||
crossAxisSpacing: StyleString.safeSpace,
|
||||
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
||||
childAspectRatio: StyleString.aspectRatio * 2.4,
|
||||
mainAxisExtent: 0),
|
||||
delegate: SliverChildBuilderDelegate((context, index) {
|
||||
return const VideoCardHSkeleton();
|
||||
}, childCount: 5),
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
(context, index) {
|
||||
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