mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
feat: custom show reply
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -387,7 +387,9 @@ class BangumiIntroController extends CommonController {
|
||||
if (cover is String && cover.isNotEmpty) {
|
||||
videoDetailCtr.videoItem['pic'] = cover;
|
||||
}
|
||||
|
||||
// 重新请求评论
|
||||
if (videoDetailCtr.showReply) {
|
||||
try {
|
||||
/// 未渲染回复组件时可能异常
|
||||
VideoReplyController videoReplyCtr =
|
||||
@@ -395,6 +397,8 @@ class BangumiIntroController extends CommonController {
|
||||
videoReplyCtr.aid = aid;
|
||||
videoReplyCtr.onRefresh();
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
if (userLogin) {
|
||||
queryBangumiLikeCoinFav();
|
||||
}
|
||||
|
||||
@@ -229,6 +229,18 @@ class _ExtraSettingState extends State<ExtraSetting> {
|
||||
setKey: SettingBoxKey.showRelatedVideo,
|
||||
defaultVal: true,
|
||||
),
|
||||
SetSwitchItem(
|
||||
title: '显示视频评论',
|
||||
leading: Icon(Icons.reply_all),
|
||||
setKey: SettingBoxKey.showVideoReply,
|
||||
defaultVal: true,
|
||||
),
|
||||
SetSwitchItem(
|
||||
title: '显示番剧评论',
|
||||
leading: Icon(Icons.reply_all),
|
||||
setKey: SettingBoxKey.showBangumiReply,
|
||||
defaultVal: true,
|
||||
),
|
||||
SetSwitchItem(
|
||||
title: '默认展开视频简介',
|
||||
leading: Icon(Icons.expand_more),
|
||||
|
||||
@@ -218,6 +218,11 @@ class VideoDetailController extends GetxController
|
||||
|
||||
late final showRelatedVideo = GStorage.showRelatedVideo;
|
||||
|
||||
late final _showVideoReply = GStorage.showVideoReply;
|
||||
late final _showBangumiReply = GStorage.showBangumiReply;
|
||||
bool get showReply =>
|
||||
videoType == SearchType.video ? _showVideoReply : _showBangumiReply;
|
||||
|
||||
late final bool enableSponsorBlock;
|
||||
PlayerStatus? playerStatus;
|
||||
StreamSubscription<Duration>? positionSubscription;
|
||||
@@ -361,9 +366,11 @@ class VideoDetailController extends GetxController
|
||||
videoItem['pic'] = cover;
|
||||
queryVideoUrl();
|
||||
|
||||
if (showReply) {
|
||||
Get.find<VideoReplyController>(tag: heroTag)
|
||||
..aid = aid
|
||||
..onRefresh();
|
||||
}
|
||||
|
||||
Get.find<VideoIntroController>(tag: heroTag)
|
||||
..lastPlayCid.value = cid
|
||||
|
||||
@@ -549,6 +549,7 @@ class VideoIntroController extends GetxController
|
||||
}
|
||||
videoDetailCtr.danmakuCid.value = cid;
|
||||
videoDetailCtr.queryVideoUrl();
|
||||
|
||||
// 重新请求相关视频
|
||||
if (videoDetailCtr.showRelatedVideo) {
|
||||
try {
|
||||
@@ -557,13 +558,16 @@ class VideoIntroController extends GetxController
|
||||
..queryData();
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
// 重新请求评论
|
||||
if (videoDetailCtr.showReply) {
|
||||
try {
|
||||
final VideoReplyController videoReplyCtr =
|
||||
Get.find<VideoReplyController>(tag: heroTag);
|
||||
videoReplyCtr.aid = aid;
|
||||
videoReplyCtr.onRefresh();
|
||||
Get.find<VideoReplyController>(tag: heroTag)
|
||||
..aid = aid
|
||||
..onRefresh();
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
this.bvid = bvid;
|
||||
lastPlayCid.value = cid;
|
||||
queryVideoIntro();
|
||||
|
||||
@@ -542,7 +542,7 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
'${videoIntroController.videoDetail.value.bvid}');
|
||||
},
|
||||
child: Text(
|
||||
'${videoIntroController.videoDetail.value.bvid}',
|
||||
videoIntroController.videoDetail.value.bvid ?? '',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
|
||||
@@ -100,9 +100,11 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
}
|
||||
videoDetailController = Get.put(VideoDetailController(), tag: heroTag);
|
||||
|
||||
if (videoDetailController.showReply) {
|
||||
_videoReplyController = Get.put(
|
||||
VideoReplyController(videoDetailController.oid.value, '0', '1'),
|
||||
tag: heroTag);
|
||||
}
|
||||
videoIntroController = Get.put(VideoIntroController(), tag: heroTag);
|
||||
videoIntroController.videoDetail.listen((value) {
|
||||
if (!context.mounted) return;
|
||||
@@ -179,7 +181,9 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
// 获取视频资源,初始化播放器
|
||||
Future<void> videoSourceInit() async {
|
||||
_futureBuilderFuture = videoDetailController.queryVideoUrl();
|
||||
if (videoDetailController.showReply) {
|
||||
_videoReplyController.queryData();
|
||||
}
|
||||
if (videoDetailController.autoPlay.value) {
|
||||
plPlayerController = videoDetailController.plPlayerController;
|
||||
plPlayerController!.addStatusLister(playerListener);
|
||||
@@ -561,13 +565,16 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
resizeToAvoidBottomInset: false,
|
||||
body: Column(
|
||||
children: [
|
||||
tabbarBuild(),
|
||||
buildTabbar(
|
||||
showReply: videoDetailController.showReply,
|
||||
),
|
||||
Expanded(
|
||||
child: TabBarView(
|
||||
physics: const ClampingScrollPhysics(),
|
||||
controller: videoDetailController.tabCtr,
|
||||
children: [
|
||||
videoIntro(),
|
||||
if (videoDetailController.showReply)
|
||||
videoReplyPanel,
|
||||
],
|
||||
),
|
||||
@@ -610,13 +617,14 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
resizeToAvoidBottomInset: false,
|
||||
body: Column(
|
||||
children: [
|
||||
tabbarBuild(),
|
||||
buildTabbar(showReply: videoDetailController.showReply),
|
||||
Expanded(
|
||||
child: TabBarView(
|
||||
physics: const ClampingScrollPhysics(),
|
||||
controller: videoDetailController.tabCtr,
|
||||
children: [
|
||||
videoIntro(),
|
||||
if (videoDetailController.showReply)
|
||||
videoReplyPanel,
|
||||
],
|
||||
),
|
||||
@@ -653,14 +661,16 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
resizeToAvoidBottomInset: false,
|
||||
body: Column(
|
||||
children: [
|
||||
tabbarBuild(false),
|
||||
buildTabbar(
|
||||
needIndicator: false,
|
||||
showReply: videoDetailController.showReply,
|
||||
),
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(child: videoIntro()),
|
||||
Expanded(
|
||||
child: videoReplyPanel,
|
||||
)
|
||||
if (videoDetailController.showReply)
|
||||
Expanded(child: videoReplyPanel)
|
||||
],
|
||||
),
|
||||
)
|
||||
@@ -699,7 +709,11 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
resizeToAvoidBottomInset: false,
|
||||
body: Column(
|
||||
children: [
|
||||
tabbarBuild(false, '', true),
|
||||
buildTabbar(
|
||||
showIntro: false,
|
||||
showReply: videoDetailController.showReply,
|
||||
),
|
||||
if (videoDetailController.showReply)
|
||||
Expanded(child: videoReplyPanel),
|
||||
],
|
||||
),
|
||||
@@ -790,13 +804,12 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
resizeToAvoidBottomInset: false,
|
||||
body: Column(
|
||||
children: [
|
||||
tabbarBuild(
|
||||
videoDetailController.videoType !=
|
||||
SearchType.media_bangumi,
|
||||
'相关视频',
|
||||
videoDetailController.videoType ==
|
||||
SearchType.media_bangumi ||
|
||||
videoDetailController.showRelatedVideo.not,
|
||||
buildTabbar(
|
||||
introText: '相关视频',
|
||||
showIntro: videoDetailController.videoType ==
|
||||
SearchType.video &&
|
||||
videoDetailController.showRelatedVideo,
|
||||
showReply: videoDetailController.showReply,
|
||||
),
|
||||
Expanded(
|
||||
child: TabBarView(
|
||||
@@ -812,6 +825,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
RelatedVideoPanel(heroTag: heroTag),
|
||||
],
|
||||
),
|
||||
if (videoDetailController.showReply)
|
||||
videoReplyPanel,
|
||||
],
|
||||
),
|
||||
@@ -1133,15 +1147,58 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
);
|
||||
}
|
||||
|
||||
Widget tabbarBuild([
|
||||
Widget buildTabbar({
|
||||
bool needIndicator = true,
|
||||
String introText = '简介',
|
||||
bool isSingle = false,
|
||||
]) {
|
||||
if (videoDetailController.tabCtr.length != (isSingle ? 1 : 2)) {
|
||||
videoDetailController.tabCtr =
|
||||
TabController(length: isSingle ? 1 : 2, vsync: this);
|
||||
bool showIntro = true,
|
||||
bool showReply = true,
|
||||
}) {
|
||||
int length = (showIntro ? 1 : 0) + (showReply ? 1 : 0);
|
||||
if (length != 0 && videoDetailController.tabCtr.length != length) {
|
||||
videoDetailController.tabCtr = TabController(length: length, vsync: this);
|
||||
}
|
||||
|
||||
Widget tabbar() => TabBar(
|
||||
labelColor: needIndicator.not || length == 1
|
||||
? Theme.of(context).colorScheme.onSurface
|
||||
: null,
|
||||
indicatorColor:
|
||||
needIndicator.not || length == 1 ? Colors.transparent : null,
|
||||
padding: EdgeInsets.zero,
|
||||
controller: videoDetailController.tabCtr,
|
||||
labelStyle: const TextStyle(fontSize: 13),
|
||||
labelPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 10.0), // 设置每个标签的宽度
|
||||
dividerColor: Colors.transparent,
|
||||
onTap: (value) {
|
||||
void animToTop() {
|
||||
if (value == 0) {
|
||||
if (showIntro) {
|
||||
_introController.animToTop();
|
||||
} else if (showReply) {
|
||||
_videoReplyController.animateToTop();
|
||||
}
|
||||
} else {
|
||||
_videoReplyController.animateToTop();
|
||||
}
|
||||
}
|
||||
|
||||
if (needIndicator.not || length == 1) {
|
||||
animToTop();
|
||||
} else if (videoDetailController.tabCtr.indexIsChanging.not) {
|
||||
animToTop();
|
||||
}
|
||||
},
|
||||
tabs: [
|
||||
if (showIntro) Tab(text: introText),
|
||||
if (showReply)
|
||||
Tab(
|
||||
text:
|
||||
'评论${_videoReplyController.count.value == -1 ? '' : ' ${_videoReplyController.count.value}'}',
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
height: 45,
|
||||
@@ -1156,41 +1213,12 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
child: Material(
|
||||
child: Row(
|
||||
children: [
|
||||
if (length == 0)
|
||||
const Spacer()
|
||||
else
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: Obx(
|
||||
() => TabBar(
|
||||
labelColor: needIndicator
|
||||
? null
|
||||
: Theme.of(context).colorScheme.onSurface,
|
||||
indicatorColor: needIndicator ? null : Colors.transparent,
|
||||
padding: EdgeInsets.zero,
|
||||
controller: videoDetailController.tabCtr,
|
||||
labelStyle: const TextStyle(fontSize: 13),
|
||||
labelPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 10.0), // 设置每个标签的宽度
|
||||
dividerColor: Colors.transparent,
|
||||
onTap: (value) {
|
||||
if (isSingle) {
|
||||
_videoReplyController.animateToTop();
|
||||
} else if (!needIndicator ||
|
||||
!videoDetailController.tabCtr.indexIsChanging) {
|
||||
if (value == 0) {
|
||||
_introController.animToTop();
|
||||
} else {
|
||||
_videoReplyController.animateToTop();
|
||||
}
|
||||
}
|
||||
},
|
||||
tabs: [
|
||||
if (!isSingle) Tab(text: introText),
|
||||
Tab(
|
||||
text:
|
||||
'评论${_videoReplyController.count.value == -1 ? '' : ' ${_videoReplyController.count.value}'}',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
child: showReply ? Obx(() => tabbar()) : tabbar(),
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
@@ -1289,7 +1317,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
|
||||
Widget videoIntro([bool needRelated = true]) {
|
||||
Widget introPanel() => CustomScrollView(
|
||||
controller: _introController,
|
||||
controller: needRelated ? _introController : null,
|
||||
slivers: [
|
||||
if (videoDetailController.videoType == SearchType.video) ...[
|
||||
VideoIntroPanel(
|
||||
|
||||
Reference in New Issue
Block a user