Merge branch 'main' into feature-minePage
This commit is contained in:
@ -675,7 +675,6 @@ class VideoDetailController extends GetxController
|
||||
@override
|
||||
void onClose() {
|
||||
super.onClose();
|
||||
plPlayerController.dispose();
|
||||
tabCtr.removeListener(() {
|
||||
onTabChanged();
|
||||
});
|
||||
|
||||
@ -3,7 +3,6 @@ import 'dart:async';
|
||||
import 'package:bottom_sheet/bottom_sheet.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:pilipala/http/constants.dart';
|
||||
@ -154,11 +153,10 @@ class VideoIntroController extends GetxController {
|
||||
}
|
||||
if (hasLike.value && hasCoin.value && hasFav.value) {
|
||||
// 已点赞、投币、收藏
|
||||
SmartDialog.showToast('🙏 UP已经收到了~');
|
||||
SmartDialog.showToast('UP已经收到了~');
|
||||
return false;
|
||||
}
|
||||
var result = await VideoHttp.oneThree(bvid: bvid);
|
||||
print('🤣🦴:${result["data"]}');
|
||||
if (result['status']) {
|
||||
hasLike.value = result["data"]["like"];
|
||||
hasCoin.value = result["data"]["coin"];
|
||||
@ -413,7 +411,12 @@ class VideoIntroController extends GetxController {
|
||||
}
|
||||
|
||||
// 修改分P或番剧分集
|
||||
Future changeSeasonOrbangu(bvid, cid, aid, cover) async {
|
||||
Future changeSeasonOrbangu(
|
||||
String bvid,
|
||||
int cid,
|
||||
int? aid,
|
||||
String? cover,
|
||||
) async {
|
||||
// 重新获取视频资源
|
||||
final VideoDetailController videoDetailCtr =
|
||||
Get.find<VideoDetailController>(tag: heroTag);
|
||||
@ -424,13 +427,14 @@ class VideoIntroController extends GetxController {
|
||||
releatedCtr.queryRelatedVideo();
|
||||
}
|
||||
|
||||
videoDetailCtr.bvid = bvid;
|
||||
videoDetailCtr.oid.value = aid ?? IdUtils.bv2av(bvid);
|
||||
videoDetailCtr.cid.value = cid;
|
||||
videoDetailCtr.danmakuCid.value = cid;
|
||||
videoDetailCtr.cover.value = cover;
|
||||
videoDetailCtr.queryVideoUrl();
|
||||
videoDetailCtr.clearSubtitleContent();
|
||||
videoDetailCtr
|
||||
..bvid = bvid
|
||||
..oid.value = aid ?? IdUtils.bv2av(bvid)
|
||||
..cid.value = cid
|
||||
..danmakuCid.value = cid
|
||||
..cover.value = cover ?? ''
|
||||
..queryVideoUrl()
|
||||
..clearSubtitleContent();
|
||||
await videoDetailCtr.getSubtitle();
|
||||
videoDetailCtr.setSubtitleContent();
|
||||
// 重新请求评论
|
||||
@ -480,7 +484,13 @@ class VideoIntroController extends GetxController {
|
||||
final List episodes = [];
|
||||
bool isPages = false;
|
||||
late String cover;
|
||||
if (videoDetail.value.ugcSeason != null) {
|
||||
final VideoDetailController videoDetailCtr =
|
||||
Get.find<VideoDetailController>(tag: heroTag);
|
||||
|
||||
/// 优先稍后再看、收藏夹
|
||||
if (videoDetailCtr.isWatchLaterVisible.value) {
|
||||
episodes.addAll(videoDetailCtr.mediaList);
|
||||
} else if (videoDetail.value.ugcSeason != null) {
|
||||
final UgcSeason ugcSeason = videoDetail.value.ugcSeason!;
|
||||
final List<SectionItem> sections = ugcSeason.sections!;
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
@ -497,10 +507,15 @@ class VideoIntroController extends GetxController {
|
||||
episodes.indexWhere((e) => e.cid == lastPlayCid.value);
|
||||
int nextIndex = currentIndex + 1;
|
||||
cover = episodes[nextIndex].cover;
|
||||
final VideoDetailController videoDetailCtr =
|
||||
Get.find<VideoDetailController>(tag: heroTag);
|
||||
final PlayRepeat platRepeat = videoDetailCtr.plPlayerController.playRepeat;
|
||||
|
||||
int cid = episodes[nextIndex].cid!;
|
||||
while (cid == -1) {
|
||||
nextIndex += 1;
|
||||
SmartDialog.showToast('当前视频暂不支持播放,自动跳过');
|
||||
cid = episodes[nextIndex].cid!;
|
||||
}
|
||||
|
||||
// 列表循环
|
||||
if (nextIndex >= episodes.length) {
|
||||
if (platRepeat == PlayRepeat.listCycle) {
|
||||
@ -510,7 +525,6 @@ class VideoIntroController extends GetxController {
|
||||
return;
|
||||
}
|
||||
}
|
||||
final int cid = episodes[nextIndex].cid!;
|
||||
final String rBvid = isPages ? bvid : episodes[nextIndex].bvid;
|
||||
final int rAid = isPages ? IdUtils.bv2av(bvid) : episodes[nextIndex].aid!;
|
||||
changeSeasonOrbangu(rBvid, cid, rAid, cover);
|
||||
@ -604,4 +618,34 @@ class VideoIntroController extends GetxController {
|
||||
).buildShowContent(Get.context!),
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
oneThreeDialog() {
|
||||
showDialog(
|
||||
context: Get.context!,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: const Text('提示'),
|
||||
content: const Text('是否一键三连'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => navigator!.pop(),
|
||||
child: Text(
|
||||
'取消',
|
||||
style: TextStyle(
|
||||
color: Theme.of(Get.context!).colorScheme.outline),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
actionOneThree();
|
||||
navigator!.pop();
|
||||
},
|
||||
child: const Text('确认'),
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,4 @@
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'package:bottom_sheet/bottom_sheet.dart';
|
||||
import 'package:easy_debounce/easy_throttle.dart';
|
||||
import 'package:expandable/expandable.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
@ -151,11 +148,6 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
RxBool isExpand = false.obs;
|
||||
late ExpandableController _expandableCtr;
|
||||
|
||||
// 一键三连动画
|
||||
late AnimationController _controller;
|
||||
late Animation<double> _scaleTransition;
|
||||
final RxDouble _progress = 0.0.obs;
|
||||
|
||||
void Function()? handleState(Future<dynamic> Function() action) {
|
||||
return isProcessing
|
||||
? null
|
||||
@ -178,26 +170,6 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
owner = widget.videoDetail!.owner;
|
||||
enableAi = setting.get(SettingBoxKey.enableAi, defaultValue: true);
|
||||
_expandableCtr = ExpandableController(initialExpanded: false);
|
||||
|
||||
/// 一键三连动画
|
||||
_controller = AnimationController(
|
||||
duration: const Duration(milliseconds: 1500),
|
||||
reverseDuration: const Duration(milliseconds: 300),
|
||||
vsync: this,
|
||||
);
|
||||
_scaleTransition = Tween<double>(begin: 0.5, end: 1.5).animate(_controller)
|
||||
..addListener(() async {
|
||||
_progress.value =
|
||||
double.parse((_scaleTransition.value - 0.5).toStringAsFixed(3));
|
||||
if (_progress.value == 1) {
|
||||
if (_controller.status == AnimationStatus.completed) {
|
||||
await videoIntroController.actionOneThree();
|
||||
}
|
||||
_progress.value = 0;
|
||||
_scaleTransition.removeListener(() {});
|
||||
_controller.stop();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 收藏
|
||||
@ -279,8 +251,6 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
@override
|
||||
void dispose() {
|
||||
_expandableCtr.dispose();
|
||||
_controller.dispose();
|
||||
_scaleTransition.removeListener(() {});
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@ -573,131 +543,34 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
Widget actionGrid(BuildContext context, videoIntroController) {
|
||||
final actionTypeSort = GlobalDataCache().actionTypeSort;
|
||||
|
||||
Widget progressWidget(progress) {
|
||||
return SizedBox(
|
||||
width: const IconThemeData.fallback().size! + 5,
|
||||
height: const IconThemeData.fallback().size! + 5,
|
||||
child: CircularProgressIndicator(
|
||||
value: progress.value,
|
||||
strokeWidth: 2,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, Widget> menuListWidgets = {
|
||||
'like': Obx(
|
||||
() {
|
||||
bool likeStatus = videoIntroController.hasLike.value;
|
||||
ColorScheme colorScheme = Theme.of(context).colorScheme;
|
||||
return Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
top: ((Get.size.width - 24) / 5) / 2 -
|
||||
(const IconThemeData.fallback().size!),
|
||||
left: ((Get.size.width - 24) / 5) / 2 -
|
||||
(const IconThemeData.fallback().size! + 5) / 2,
|
||||
child: progressWidget(_progress)),
|
||||
InkWell(
|
||||
onTapDown: (details) {
|
||||
feedBack();
|
||||
if (videoIntroController.userInfo == null) {
|
||||
SmartDialog.showToast('账号未登录');
|
||||
return;
|
||||
}
|
||||
_controller.forward();
|
||||
},
|
||||
onTapUp: (TapUpDetails details) {
|
||||
if (_progress.value == 0) {
|
||||
feedBack();
|
||||
EasyThrottle.throttle(
|
||||
'my-throttler', const Duration(milliseconds: 200), () {
|
||||
videoIntroController.actionLikeVideo();
|
||||
});
|
||||
}
|
||||
_controller.reverse();
|
||||
},
|
||||
onTapCancel: () {
|
||||
_controller.reverse();
|
||||
},
|
||||
borderRadius: StyleString.mdRadius,
|
||||
child: SizedBox(
|
||||
width: (Get.size.width - 24) / 5,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const SizedBox(height: 4),
|
||||
AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
transitionBuilder:
|
||||
(Widget child, Animation<double> animation) {
|
||||
return ScaleTransition(
|
||||
scale: animation, child: child);
|
||||
},
|
||||
child: Icon(
|
||||
key: ValueKey<bool>(likeStatus),
|
||||
likeStatus
|
||||
? FontAwesomeIcons.solidThumbsUp
|
||||
: FontAwesomeIcons.thumbsUp,
|
||||
color: likeStatus
|
||||
? colorScheme.primary
|
||||
: colorScheme.outline,
|
||||
size: 21,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
Text(
|
||||
widget.videoDetail!.stat!.like!.toString(),
|
||||
style: TextStyle(
|
||||
color: likeStatus ? colorScheme.primary : null,
|
||||
fontSize:
|
||||
Theme.of(context).textTheme.labelSmall!.fontSize,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
() => ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.thumbsUp),
|
||||
selectIcon: const Icon(FontAwesomeIcons.solidThumbsUp),
|
||||
onTap: handleState(videoIntroController.actionLikeVideo),
|
||||
onLongPress: () => videoIntroController.oneThreeDialog(),
|
||||
selectStatus: videoIntroController.hasLike.value,
|
||||
text: widget.videoDetail!.stat!.like!.toString(),
|
||||
),
|
||||
),
|
||||
'coin': Obx(
|
||||
() => Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
top: ((Get.size.width - 24) / 5) / 2 -
|
||||
(const IconThemeData.fallback().size!),
|
||||
left: ((Get.size.width - 24) / 5) / 2 -
|
||||
(const IconThemeData.fallback().size! + 5) / 2,
|
||||
child: progressWidget(_progress)),
|
||||
ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.b),
|
||||
selectIcon: const Icon(FontAwesomeIcons.b),
|
||||
onTap: handleState(videoIntroController.actionCoinVideo),
|
||||
selectStatus: videoIntroController.hasCoin.value,
|
||||
text: widget.videoDetail!.stat!.coin!.toString(),
|
||||
),
|
||||
],
|
||||
() => ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.b),
|
||||
selectIcon: const Icon(FontAwesomeIcons.b),
|
||||
onTap: handleState(videoIntroController.actionCoinVideo),
|
||||
selectStatus: videoIntroController.hasCoin.value,
|
||||
text: widget.videoDetail!.stat!.coin!.toString(),
|
||||
),
|
||||
),
|
||||
'collect': Obx(
|
||||
() => Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
top: ((Get.size.width - 24) / 5) / 2 -
|
||||
(const IconThemeData.fallback().size!),
|
||||
left: ((Get.size.width - 24) / 5) / 2 -
|
||||
(const IconThemeData.fallback().size! + 5) / 2,
|
||||
child: progressWidget(_progress)),
|
||||
ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.star),
|
||||
selectIcon: const Icon(FontAwesomeIcons.solidStar),
|
||||
onTap: () => showFavBottomSheet(),
|
||||
onLongPress: () => showFavBottomSheet(type: 'longPress'),
|
||||
selectStatus: videoIntroController.hasFav.value,
|
||||
text: widget.videoDetail!.stat!.favorite!.toString(),
|
||||
),
|
||||
],
|
||||
() => ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.star),
|
||||
selectIcon: const Icon(FontAwesomeIcons.solidStar),
|
||||
onTap: () => showFavBottomSheet(),
|
||||
onLongPress: () => showFavBottomSheet(type: 'longPress'),
|
||||
selectStatus: videoIntroController.hasFav.value,
|
||||
text: widget.videoDetail!.stat!.favorite!.toString(),
|
||||
),
|
||||
),
|
||||
'watchLater': ActionItem(
|
||||
|
||||
@ -153,7 +153,17 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
|
||||
child: Container(
|
||||
height: 40,
|
||||
padding: const EdgeInsets.fromLTRB(12, 0, 6, 0),
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
blurRadius: 0.0,
|
||||
spreadRadius: 0.0,
|
||||
offset: const Offset(2, 0),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
|
||||
@ -9,6 +9,7 @@ import 'package:get/get.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:pilipala/common/widgets/badge.dart';
|
||||
import 'package:pilipala/common/widgets/network_img_layer.dart';
|
||||
import 'package:pilipala/http/reply.dart';
|
||||
import 'package:pilipala/models/common/reply_type.dart';
|
||||
import 'package:pilipala/models/video/reply/item.dart';
|
||||
import 'package:pilipala/pages/main/index.dart';
|
||||
@ -18,6 +19,7 @@ import 'package:pilipala/plugin/pl_gallery/index.dart';
|
||||
import 'package:pilipala/plugin/pl_popup/index.dart';
|
||||
import 'package:pilipala/utils/app_scheme.dart';
|
||||
import 'package:pilipala/utils/feed_back.dart';
|
||||
import 'package:pilipala/utils/global_data_cache.dart';
|
||||
import 'package:pilipala/utils/id_utils.dart';
|
||||
import 'package:pilipala/utils/storage.dart';
|
||||
import 'package:pilipala/utils/url_utils.dart';
|
||||
@ -48,6 +50,8 @@ class ReplyItem extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final bool isOwner = int.parse(replyItem!.member!.mid!) ==
|
||||
(GlobalDataCache().userInfo?.mid ?? -1);
|
||||
return Material(
|
||||
child: InkWell(
|
||||
// 点击整个评论区 评论详情/回复
|
||||
@ -73,6 +77,7 @@ class ReplyItem extends StatelessWidget {
|
||||
return MorePanel(
|
||||
item: replyItem,
|
||||
mainFloor: true,
|
||||
isOwner: isOwner,
|
||||
);
|
||||
},
|
||||
);
|
||||
@ -195,25 +200,36 @@ class ReplyItem extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Text(
|
||||
Utils.dateFormat(replyItem!.ctime),
|
||||
style: TextStyle(
|
||||
fontSize: textTheme.labelSmall!.fontSize,
|
||||
color: colorScheme.outline,
|
||||
),
|
||||
),
|
||||
if (replyItem!.replyControl != null &&
|
||||
replyItem!.replyControl!.location != '')
|
||||
Text(
|
||||
' • ${replyItem!.replyControl!.location!}',
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: Utils.dateFormat(replyItem!.ctime),
|
||||
style: TextStyle(
|
||||
fontSize: textTheme.labelSmall!.fontSize,
|
||||
color: colorScheme.outline),
|
||||
fontSize: textTheme.labelSmall!.fontSize,
|
||||
color: colorScheme.outline,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
if (replyItem!.replyControl != null &&
|
||||
replyItem!.replyControl!.location != '')
|
||||
TextSpan(
|
||||
text: ' • ${replyItem!.replyControl!.location!}',
|
||||
style: TextStyle(
|
||||
fontSize: textTheme.labelSmall!.fontSize,
|
||||
color: colorScheme.outline,
|
||||
),
|
||||
),
|
||||
if (replyItem!.invisible!)
|
||||
TextSpan(
|
||||
text: ' • 隐藏的评论',
|
||||
style: TextStyle(
|
||||
color: colorScheme.outline,
|
||||
fontSize: textTheme.labelSmall!.fontSize,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
@ -698,14 +714,11 @@ InlineSpan buildContent(
|
||||
'',
|
||||
);
|
||||
} else if (RegExp(r'^cv\d+$').hasMatch(matchStr)) {
|
||||
Get.toNamed(
|
||||
'/webview',
|
||||
parameters: {
|
||||
'url': 'https://www.bilibili.com/read/$matchStr',
|
||||
'type': 'url',
|
||||
'pageTitle': title
|
||||
},
|
||||
);
|
||||
Get.toNamed('/read', parameters: {
|
||||
'title': title,
|
||||
'id': Utils.matchNum(matchStr).first.toString(),
|
||||
'articleType': 'read',
|
||||
});
|
||||
} else {
|
||||
Uri uri = Uri.parse(matchStr.replaceAll('/?', '?'));
|
||||
SchemeEntity scheme = SchemeEntity(
|
||||
@ -717,7 +730,7 @@ InlineSpan buildContent(
|
||||
source: '',
|
||||
dataString: matchStr,
|
||||
);
|
||||
PiliSchame.fullPathPush(scheme);
|
||||
PiliSchame.httpsScheme(scheme);
|
||||
}
|
||||
} else {
|
||||
if (appUrlSchema.startsWith('bilibili://search')) {
|
||||
@ -1004,10 +1017,12 @@ InlineSpan buildContent(
|
||||
class MorePanel extends StatelessWidget {
|
||||
final dynamic item;
|
||||
final bool mainFloor;
|
||||
final bool isOwner;
|
||||
const MorePanel({
|
||||
super.key,
|
||||
required this.item,
|
||||
this.mainFloor = false,
|
||||
this.isOwner = false,
|
||||
});
|
||||
|
||||
Future<dynamic> menuActionHandler(String type) async {
|
||||
@ -1043,9 +1058,43 @@ class MorePanel extends StatelessWidget {
|
||||
// case 'report':
|
||||
// SmartDialog.showToast('举报');
|
||||
// break;
|
||||
// case 'delete':
|
||||
// SmartDialog.showToast('删除');
|
||||
// break;
|
||||
case 'delete':
|
||||
// 删除评论提示
|
||||
await showDialog(
|
||||
context: Get.context!,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: const Text('删除评论'),
|
||||
content: const Text('删除评论后,评论下所有回复将被删除,确定删除吗?'),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
onPressed: () => Get.back(),
|
||||
child: Text('取消',
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.outline)),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
Get.back();
|
||||
var result = await ReplyHttp.replyDel(
|
||||
type: item.type!,
|
||||
oid: item.oid!,
|
||||
rpid: item.rpid!,
|
||||
);
|
||||
if (result['status']) {
|
||||
SmartDialog.showToast('评论删除成功,需手动刷新');
|
||||
Get.back();
|
||||
} else {
|
||||
SmartDialog.showToast(result['msg']);
|
||||
}
|
||||
},
|
||||
child: const Text('确定'),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
@ -1054,6 +1103,7 @@ class MorePanel extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
ColorScheme colorScheme = Theme.of(context).colorScheme;
|
||||
TextTheme textTheme = Theme.of(context).textTheme;
|
||||
Color errorColor = colorScheme.error;
|
||||
return Container(
|
||||
padding: EdgeInsets.only(bottom: MediaQuery.of(context).padding.bottom),
|
||||
child: Column(
|
||||
@ -1106,12 +1156,14 @@ class MorePanel extends StatelessWidget {
|
||||
// leading: Icon(Icons.report_outlined, color: errorColor),
|
||||
// title: Text('举报', style: TextStyle(color: errorColor)),
|
||||
// ),
|
||||
// ListTile(
|
||||
// onTap: () async => await menuActionHandler('del'),
|
||||
// minLeadingWidth: 0,
|
||||
// leading: Icon(Icons.delete_outline, color: errorColor),
|
||||
// title: Text('删除', style: TextStyle(color: errorColor)),
|
||||
// ),
|
||||
if (isOwner)
|
||||
ListTile(
|
||||
onTap: () async => await menuActionHandler('delete'),
|
||||
minLeadingWidth: 0,
|
||||
leading: Icon(Icons.delete_outline, color: errorColor),
|
||||
title: Text('删除评论',
|
||||
style: textTheme.titleSmall!.copyWith(color: errorColor)),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@ -3,6 +3,7 @@ import 'dart:io';
|
||||
|
||||
import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart';
|
||||
import 'package:floating/floating.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
@ -68,10 +69,6 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
late final AppLifecycleListener _lifecycleListener;
|
||||
late double statusHeight;
|
||||
|
||||
// 稍后再看控制器
|
||||
// late AnimationController _laterCtr;
|
||||
// late Animation<Offset> _laterOffsetAni;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@ -85,14 +82,16 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
videoIntroController.videoDetail.listen((value) {
|
||||
videoPlayerServiceHandler.onVideoDetailChange(value, vdCtr.cid.value);
|
||||
});
|
||||
bangumiIntroController = Get.put(BangumiIntroController(), tag: heroTag);
|
||||
bangumiIntroController.bangumiDetail.listen((value) {
|
||||
videoPlayerServiceHandler.onVideoDetailChange(value, vdCtr.cid.value);
|
||||
});
|
||||
vdCtr.cid.listen((p0) {
|
||||
videoPlayerServiceHandler.onVideoDetailChange(
|
||||
bangumiIntroController.bangumiDetail.value, p0);
|
||||
});
|
||||
if (vdCtr.videoType == SearchType.media_bangumi) {
|
||||
bangumiIntroController = Get.put(BangumiIntroController(), tag: heroTag);
|
||||
bangumiIntroController.bangumiDetail.listen((value) {
|
||||
videoPlayerServiceHandler.onVideoDetailChange(value, vdCtr.cid.value);
|
||||
});
|
||||
vdCtr.cid.listen((p0) {
|
||||
videoPlayerServiceHandler.onVideoDetailChange(
|
||||
bangumiIntroController.bangumiDetail.value, p0);
|
||||
});
|
||||
}
|
||||
statusBarHeight = localCache.get('statusBarHeight');
|
||||
autoExitFullcreen =
|
||||
setting.get(SettingBoxKey.enableAutoExit, defaultValue: false);
|
||||
@ -108,7 +107,6 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
}
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
lifecycleListener();
|
||||
// watchLaterControllerInit();
|
||||
}
|
||||
|
||||
// 获取视频资源,初始化播放器
|
||||
@ -242,8 +240,6 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
appbarStream.close();
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
_lifecycleListener.dispose();
|
||||
// _laterCtr.dispose();
|
||||
// _laterOffsetAni.removeListener(() {});
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@ -297,6 +293,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
plPlayerController?.play();
|
||||
}
|
||||
plPlayerController?.addStatusLister(playerListener);
|
||||
appbarStream.add(0);
|
||||
super.didPopNext();
|
||||
}
|
||||
|
||||
@ -490,21 +487,6 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
);
|
||||
}
|
||||
|
||||
/// 稍后再看控制器初始化
|
||||
// void watchLaterControllerInit() {
|
||||
// _laterCtr = AnimationController(
|
||||
// duration: const Duration(milliseconds: 300),
|
||||
// vsync: this,
|
||||
// );
|
||||
// _laterOffsetAni = Tween<Offset>(
|
||||
// begin: const Offset(0.0, 1.0),
|
||||
// end: Offset.zero,
|
||||
// ).animate(CurvedAnimation(
|
||||
// parent: _laterCtr,
|
||||
// curve: Curves.easeInOut,
|
||||
// ));
|
||||
// }
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final sizeContext = MediaQuery.sizeOf(context);
|
||||
@ -529,6 +511,14 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
exitFullScreen();
|
||||
}
|
||||
|
||||
SystemChrome.setSystemUIOverlayStyle(
|
||||
SystemUiOverlayStyle(
|
||||
systemNavigationBarColor: Colors.transparent,
|
||||
systemNavigationBarIconBrightness:
|
||||
Get.isDarkMode ? Brightness.light : Brightness.dark,
|
||||
),
|
||||
);
|
||||
|
||||
Widget buildLoadingWidget() {
|
||||
return Center(child: Lottie.asset('assets/loading.json', width: 200));
|
||||
}
|
||||
@ -615,10 +605,16 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
key: vdCtr.scaffoldKey,
|
||||
appBar: PreferredSize(
|
||||
preferredSize: const Size.fromHeight(0),
|
||||
child: AppBar(
|
||||
backgroundColor: Colors.black,
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 0,
|
||||
child: StreamBuilder(
|
||||
stream: appbarStream.stream.distinct(),
|
||||
initialData: 0,
|
||||
builder: ((context, snapshot) {
|
||||
return AppBar(
|
||||
backgroundColor: Colors.black,
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 0,
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
body: ExtendedNestedScrollView(
|
||||
|
||||
@ -109,7 +109,7 @@ class _MediaListPanelState extends State<MediaListPanel> {
|
||||
var item = mediaList[index];
|
||||
return InkWell(
|
||||
onTap: () async {
|
||||
String bvid = item.bvId!;
|
||||
String bvid = item.bvid!;
|
||||
int? aid = item.id;
|
||||
String cover = item.cover ?? '';
|
||||
final int cid =
|
||||
@ -173,7 +173,7 @@ class _MediaListPanelState extends State<MediaListPanel> {
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: item.bvId == widget.bvid
|
||||
color: item.bvid == widget.bvid
|
||||
? Theme.of(context)
|
||||
.colorScheme
|
||||
.primary
|
||||
|
||||
Reference in New Issue
Block a user