mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
feat: 播放顺序、视频详情操作栏样式
This commit is contained in:
@@ -11,6 +11,7 @@ import 'package:pilipala/models/user/fav_folder.dart';
|
||||
import 'package:pilipala/models/video_detail_res.dart';
|
||||
import 'package:pilipala/pages/video/detail/controller.dart';
|
||||
import 'package:pilipala/pages/video/detail/reply/index.dart';
|
||||
import 'package:pilipala/plugin/pl_player/models/play_repeat.dart';
|
||||
import 'package:pilipala/utils/feed_back.dart';
|
||||
import 'package:pilipala/utils/id_utils.dart';
|
||||
import 'package:pilipala/utils/storage.dart';
|
||||
@@ -58,6 +59,7 @@ class VideoIntroController extends GetxController {
|
||||
RxString total = '1'.obs;
|
||||
Timer? timer;
|
||||
bool isPaused = false;
|
||||
String heroTag = Get.arguments['heroTag'];
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
@@ -102,9 +104,10 @@ class VideoIntroController extends GetxController {
|
||||
if (videoDetail.value.pages!.isNotEmpty && lastPlayCid.value == 0) {
|
||||
lastPlayCid.value = videoDetail.value.pages!.first.cid!;
|
||||
}
|
||||
Get.find<VideoDetailController>(tag: Get.arguments['heroTag'])
|
||||
.tabs
|
||||
.value = ['简介', '评论 ${result['data']!.stat!.reply}'];
|
||||
// Get.find<VideoDetailController>(tag: heroTag).tabs.value = [
|
||||
// '简介',
|
||||
// '评论 ${result['data']!.stat!.reply}'
|
||||
// ];
|
||||
// 获取到粉丝数再返回
|
||||
await queryUserStat();
|
||||
}
|
||||
@@ -440,16 +443,16 @@ class VideoIntroController extends GetxController {
|
||||
Future changeSeasonOrbangu(bvid, cid, aid) async {
|
||||
// 重新获取视频资源
|
||||
VideoDetailController videoDetailCtr =
|
||||
Get.find<VideoDetailController>(tag: Get.arguments['heroTag']);
|
||||
Get.find<VideoDetailController>(tag: heroTag);
|
||||
videoDetailCtr.bvid = bvid;
|
||||
videoDetailCtr.cid = cid;
|
||||
videoDetailCtr.cid.value = cid;
|
||||
videoDetailCtr.danmakuCid.value = cid;
|
||||
videoDetailCtr.queryVideoUrl();
|
||||
// 重新请求评论
|
||||
try {
|
||||
/// 未渲染回复组件时可能异常
|
||||
VideoReplyController videoReplyCtr =
|
||||
Get.find<VideoReplyController>(tag: Get.arguments['heroTag']);
|
||||
Get.find<VideoReplyController>(tag: heroTag);
|
||||
videoReplyCtr.aid = aid;
|
||||
videoReplyCtr.queryReplyList(type: 'init');
|
||||
} catch (_) {}
|
||||
@@ -486,4 +489,52 @@ class VideoIntroController extends GetxController {
|
||||
}
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
/// 列表循环或者顺序播放时,自动播放下一个
|
||||
void nextPlay() {
|
||||
late List episodes;
|
||||
// if (videoDetail.value.ugcSeason != null) {
|
||||
// UgcSeason ugcSeason = videoDetail.value.ugcSeason!;
|
||||
// List<SectionItem> sections = ugcSeason.sections!;
|
||||
// for (int i = 0; i < sections.length; i++) {
|
||||
// List<EpisodeItem> episodesList = sections[i].episodes!;
|
||||
// for (int j = 0; j < episodesList.length; j++) {
|
||||
// if (episodesList[j].cid == lastPlayCid.value) {
|
||||
// episodes = episodesList;
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
if (videoDetail.value.ugcSeason != null) {
|
||||
UgcSeason ugcSeason = videoDetail.value.ugcSeason!;
|
||||
List<SectionItem> sections = ugcSeason.sections!;
|
||||
episodes = [];
|
||||
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
List<EpisodeItem> episodesList = sections[i].episodes!;
|
||||
episodes.addAll(episodesList);
|
||||
}
|
||||
}
|
||||
|
||||
int currentIndex = episodes.indexWhere((e) => e.cid == lastPlayCid.value);
|
||||
int nextIndex = currentIndex + 1;
|
||||
VideoDetailController videoDetailCtr =
|
||||
Get.find<VideoDetailController>(tag: heroTag);
|
||||
PlayRepeat platRepeat = videoDetailCtr.plPlayerController.playRepeat;
|
||||
|
||||
// 列表循环
|
||||
if (nextIndex >= episodes.length) {
|
||||
if (platRepeat == PlayRepeat.listCycle) {
|
||||
nextIndex = 0;
|
||||
}
|
||||
if (platRepeat == PlayRepeat.listOrder) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
int cid = episodes[nextIndex].cid!;
|
||||
String bvid = episodes[nextIndex].bvid!;
|
||||
int aid = episodes[nextIndex].aid!;
|
||||
changeSeasonOrbangu(bvid, cid, aid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,17 +330,17 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
),
|
||||
const SizedBox(height: 7),
|
||||
// 点赞收藏转发 布局样式1
|
||||
SingleChildScrollView(
|
||||
padding: const EdgeInsets.only(top: 7, bottom: 7),
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: actionRow(
|
||||
context,
|
||||
videoIntroController,
|
||||
videoDetailCtr,
|
||||
),
|
||||
),
|
||||
// SingleChildScrollView(
|
||||
// padding: const EdgeInsets.only(top: 7, bottom: 7),
|
||||
// scrollDirection: Axis.horizontal,
|
||||
// child: actionRow(
|
||||
// context,
|
||||
// videoIntroController,
|
||||
// videoDetailCtr,
|
||||
// ),
|
||||
// ),
|
||||
// 点赞收藏转发 布局样式2
|
||||
// actionGrid(context, videoIntroController),
|
||||
actionGrid(context, videoIntroController),
|
||||
// 合集
|
||||
if (!loadingStatus &&
|
||||
widget.videoDetail!.ugcSeason != null) ...[
|
||||
@@ -458,7 +458,7 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
Widget actionGrid(BuildContext context, videoIntroController) {
|
||||
return LayoutBuilder(builder: (context, constraints) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.only(top: 6, bottom: 10),
|
||||
margin: const EdgeInsets.only(top: 6, bottom: 4),
|
||||
height: constraints.maxWidth / 5 * 0.8,
|
||||
child: GridView.count(
|
||||
primary: false,
|
||||
@@ -477,12 +477,12 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
? widget.videoDetail!.stat!.like!.toString()
|
||||
: '-'),
|
||||
),
|
||||
ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.clock),
|
||||
onTap: () => videoIntroController.actionShareVideo(),
|
||||
selectStatus: false,
|
||||
loadingStatus: loadingStatus,
|
||||
text: '稍后再看'),
|
||||
// ActionItem(
|
||||
// icon: const Icon(FontAwesomeIcons.clock),
|
||||
// onTap: () => videoIntroController.actionShareVideo(),
|
||||
// selectStatus: false,
|
||||
// loadingStatus: loadingStatus,
|
||||
// text: '稍后再看'),
|
||||
Obx(
|
||||
() => ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.b),
|
||||
@@ -498,22 +498,28 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
() => ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.star),
|
||||
selectIcon: const Icon(FontAwesomeIcons.solidStar),
|
||||
// onTap: () => videoIntroController.actionFavVideo(),
|
||||
onTap: () => showFavBottomSheet(),
|
||||
onLongPress: () => showFavBottomSheet(type: 'longPress'),
|
||||
selectStatus: videoIntroController.hasFav.value,
|
||||
loadingStatus: loadingStatus,
|
||||
text: !loadingStatus
|
||||
? widget.videoDetail!.stat!.favorite!.toString()
|
||||
: '-'),
|
||||
),
|
||||
ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.comment),
|
||||
onTap: () => videoDetailCtr.tabCtr.animateTo(1),
|
||||
selectStatus: false,
|
||||
loadingStatus: loadingStatus,
|
||||
text: !loadingStatus
|
||||
? widget.videoDetail!.stat!.reply!.toString()
|
||||
: '评论'),
|
||||
ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.shareFromSquare),
|
||||
onTap: () => videoIntroController.actionShareVideo(),
|
||||
selectStatus: false,
|
||||
loadingStatus: loadingStatus,
|
||||
text: !loadingStatus
|
||||
? widget.videoDetail!.stat!.share!.toString()
|
||||
: '-'),
|
||||
text: '分享'),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -6,6 +6,7 @@ class ActionItem extends StatelessWidget {
|
||||
final Icon? icon;
|
||||
final Icon? selectIcon;
|
||||
final Function? onTap;
|
||||
final Function? onLongPress;
|
||||
final bool? loadingStatus;
|
||||
final String? text;
|
||||
final bool selectStatus;
|
||||
@@ -15,6 +16,7 @@ class ActionItem extends StatelessWidget {
|
||||
this.icon,
|
||||
this.selectIcon,
|
||||
this.onTap,
|
||||
this.onLongPress,
|
||||
this.loadingStatus,
|
||||
this.text,
|
||||
this.selectStatus = false,
|
||||
@@ -27,6 +29,9 @@ class ActionItem extends StatelessWidget {
|
||||
feedBack(),
|
||||
onTap!(),
|
||||
},
|
||||
onLongPress: () => {
|
||||
if (onLongPress != null) {onLongPress!()}
|
||||
},
|
||||
borderRadius: StyleString.mdRadius,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:pilipala/models/video_detail_res.dart';
|
||||
import 'package:pilipala/pages/video/detail/index.dart';
|
||||
|
||||
class PagesPanel extends StatefulWidget {
|
||||
final List<Part> pages;
|
||||
@@ -22,13 +23,23 @@ class PagesPanel extends StatefulWidget {
|
||||
|
||||
class _PagesPanelState extends State<PagesPanel> {
|
||||
late List<Part> episodes;
|
||||
late int cid;
|
||||
late int currentIndex;
|
||||
String heroTag = Get.arguments['heroTag'];
|
||||
late VideoDetailController _videoDetailController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
cid = widget.cid!;
|
||||
episodes = widget.pages;
|
||||
currentIndex = episodes.indexWhere((e) => e.cid == widget.cid);
|
||||
_videoDetailController = Get.find<VideoDetailController>(tag: heroTag);
|
||||
currentIndex = episodes.indexWhere((e) => e.cid == cid);
|
||||
_videoDetailController.cid.listen((p0) {
|
||||
cid = p0;
|
||||
setState(() {});
|
||||
currentIndex = episodes.indexWhere((e) => e.cid == cid);
|
||||
});
|
||||
}
|
||||
|
||||
void changeFucCall(item, i) async {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:pilipala/models/video_detail_res.dart';
|
||||
import 'package:pilipala/pages/video/detail/index.dart';
|
||||
import 'package:pilipala/utils/id_utils.dart';
|
||||
|
||||
class SeasonPanel extends StatefulWidget {
|
||||
@@ -23,11 +24,16 @@ class SeasonPanel extends StatefulWidget {
|
||||
|
||||
class _SeasonPanelState extends State<SeasonPanel> {
|
||||
late List<EpisodeItem> episodes;
|
||||
late int cid;
|
||||
late int currentIndex;
|
||||
String heroTag = Get.arguments['heroTag'];
|
||||
late VideoDetailController _videoDetailController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
cid = widget.cid!;
|
||||
_videoDetailController = Get.find<VideoDetailController>(tag: heroTag);
|
||||
|
||||
/// 根据 cid 找到对应集,找到对应 episodes
|
||||
/// 有多个episodes时,只显示其中一个
|
||||
@@ -36,7 +42,7 @@ class _SeasonPanelState extends State<SeasonPanel> {
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
List<EpisodeItem> episodesList = sections[i].episodes!;
|
||||
for (int j = 0; j < episodesList.length; j++) {
|
||||
if (episodesList[j].cid == widget.cid) {
|
||||
if (episodesList[j].cid == cid) {
|
||||
episodes = episodesList;
|
||||
continue;
|
||||
}
|
||||
@@ -47,7 +53,12 @@ class _SeasonPanelState extends State<SeasonPanel> {
|
||||
// episodes = widget.ugcSeason.sections!
|
||||
// .firstWhere((e) => e.seasonId == widget.ugcSeason.id)
|
||||
// .episodes!;
|
||||
currentIndex = episodes.indexWhere((e) => e.cid == widget.cid);
|
||||
currentIndex = episodes.indexWhere((e) => e.cid == cid);
|
||||
_videoDetailController.cid.listen((p0) {
|
||||
cid = p0;
|
||||
setState(() {});
|
||||
currentIndex = episodes.indexWhere((e) => e.cid == cid);
|
||||
});
|
||||
}
|
||||
|
||||
void changeFucCall(item, i) async {
|
||||
@@ -57,6 +68,7 @@ class _SeasonPanelState extends State<SeasonPanel> {
|
||||
item.aid,
|
||||
);
|
||||
currentIndex = i;
|
||||
setState(() {});
|
||||
Get.back();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user