mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-06-11 21:31:40 +08:00
Merge branch 'main' of https://github.com/orz12/PiliPalaX
This commit is contained in:
@@ -234,7 +234,7 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
: bangumiItem!.title!,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
|
||||
@@ -50,7 +50,7 @@ class IntroDetail extends StatelessWidget {
|
||||
bangumiDetail!.title,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
|
||||
@@ -160,7 +160,7 @@ class BangumiContent extends StatelessWidget {
|
||||
bangumiItem.title,
|
||||
textAlign: TextAlign.start,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontWeight: FontWeight.w600,
|
||||
letterSpacing: 0.3,
|
||||
),
|
||||
maxLines: 1,
|
||||
|
||||
@@ -63,7 +63,7 @@ class DynamicDetailController extends GetxController {
|
||||
isLoadingMore = false;
|
||||
if (res['status']) {
|
||||
List<ReplyItemModel> replies = res['data'].replies;
|
||||
acount.value = res['data'].cursor.allCount;
|
||||
acount.value = res['data'].cursor.allCount ?? 0;
|
||||
nextOffset = res['data'].cursor.paginationReply.nextOffset ?? "";
|
||||
if (replies.isNotEmpty) {
|
||||
noMore.value = '加载中...';
|
||||
|
||||
@@ -382,7 +382,8 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
return FutureBuilder(
|
||||
future: _futureBuilderFuture,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.done) {
|
||||
if (snapshot.connectionState == ConnectionState.done &&
|
||||
snapshot.hasData) {
|
||||
Map data = snapshot.data as Map;
|
||||
if (snapshot.data['status']) {
|
||||
// 请求成功
|
||||
|
||||
@@ -63,9 +63,9 @@ class _DynamicsPageState extends State<DynamicsPage>
|
||||
scrollController.addListener(() {
|
||||
if (scrollController.position.pixels >=
|
||||
scrollController.position.maxScrollExtent - 300) {
|
||||
EasyThrottle.throttle('following', const Duration(seconds: 1), () {
|
||||
_dynamicsController.queryFollowing2();
|
||||
});
|
||||
EasyThrottle.throttle('following', const Duration(seconds: 1), () {
|
||||
_dynamicsController.queryFollowing2();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ class VideoContent extends StatelessWidget {
|
||||
favFolderItem.title,
|
||||
textAlign: TextAlign.start,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontWeight: FontWeight.w600,
|
||||
letterSpacing: 0.3,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -157,7 +157,7 @@ class VideoContent extends StatelessWidget {
|
||||
videoItem.title,
|
||||
textAlign: TextAlign.start,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontWeight: FontWeight.w600,
|
||||
letterSpacing: 0.3,
|
||||
),
|
||||
maxLines: 2,
|
||||
|
||||
@@ -301,7 +301,7 @@ class VideoContent extends StatelessWidget {
|
||||
videoItem.title,
|
||||
textAlign: TextAlign.start,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontWeight: FontWeight.w600,
|
||||
letterSpacing: 0.3,
|
||||
),
|
||||
maxLines: videoItem.videos > 1 ? 1 : 2,
|
||||
|
||||
@@ -73,7 +73,7 @@ class HtmlRenderController extends GetxController {
|
||||
);
|
||||
if (res['status']) {
|
||||
List<ReplyItemModel> replies = res['data'].replies;
|
||||
acount.value = res['data'].cursor.allCount;
|
||||
acount.value = res['data'].cursor.allCount ?? 0;
|
||||
nextOffset = res['data'].cursor.paginationReply.nextOffset ?? "";
|
||||
if (replies.isNotEmpty) {
|
||||
noMore.value = '加载中...';
|
||||
|
||||
@@ -105,7 +105,7 @@ class LiveContent extends StatelessWidget {
|
||||
liveItem.title,
|
||||
textAlign: TextAlign.start,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontWeight: FontWeight.w600,
|
||||
letterSpacing: 0.3,
|
||||
),
|
||||
maxLines: 2,
|
||||
|
||||
@@ -102,9 +102,7 @@ class _BottomControlState extends State<BottomControl> {
|
||||
canUsePiP = false;
|
||||
}
|
||||
if (canUsePiP) {
|
||||
await widget.floating!.enable(
|
||||
const EnableManual()
|
||||
);
|
||||
await widget.floating!.enable(const EnableManual());
|
||||
} else {}
|
||||
},
|
||||
icon: const Icon(
|
||||
@@ -117,9 +115,9 @@ class _BottomControlState extends State<BottomControl> {
|
||||
const SizedBox(width: 4),
|
||||
],
|
||||
ComBtn(
|
||||
tooltip: '全屏切换',
|
||||
icon: const Icon(
|
||||
Icons.fullscreen,
|
||||
semanticLabel: '全屏切换',
|
||||
size: 20,
|
||||
color: Colors.white,
|
||||
),
|
||||
|
||||
@@ -310,6 +310,7 @@ class LoginPageController extends GetxController
|
||||
Uri currentUri = Uri.parse(Url);
|
||||
var safeCenterRes = await LoginHttp.safeCenterGetInfo(
|
||||
tmpCode: currentUri.queryParameters['tmp_token']!);
|
||||
//{"code":0,"message":"0","ttl":1,"data":{"account_info":{"hide_tel":"111*****111","hide_mail":"aaa*****aaaa.aaa","bind_mail":true,"bind_tel":true,"tel_verify":true,"mail_verify":true,"unneeded_check":false,"bind_safe_question":false,"mid":1111111},"member_info":{"nickname":"xxxxxxx","face":"https://i0.hdslb.com/bfs/face/xxxxxxx.jpg","realname_status":false},"sns_info":{"bind_google":false,"bind_fb":false,"bind_apple":false,"bind_qq":true,"bind_weibo":true,"bind_wechat":false},"account_safe":{"score":80}}}
|
||||
if (!safeCenterRes['status']) {
|
||||
SmartDialog.showToast("获取安全验证信息失败,请尝试其它登录方式\n"
|
||||
"(${safeCenterRes['code']}) ${safeCenterRes['msg']}");
|
||||
@@ -317,9 +318,9 @@ class LoginPageController extends GetxController
|
||||
}
|
||||
Map<String, String> accountInfo = {
|
||||
"telVerify": safeCenterRes['data']['account_info']!['tel_verify'],
|
||||
"bindTel": safeCenterRes['data']['account_info']!["bind_tel"],
|
||||
"hindTel": safeCenterRes['data']['account_info']!["hide_tel"],
|
||||
"mailVerify": safeCenterRes['data']['account_info']!['mailVerify'],
|
||||
"bindMail": safeCenterRes['data']['account_info']!["bind_mail"],
|
||||
"hindMail": safeCenterRes['data']['account_info']!["hide_mail"],
|
||||
};
|
||||
TextEditingController _textFieldController = TextEditingController();
|
||||
String captchaKey = '';
|
||||
@@ -327,7 +328,7 @@ class LoginPageController extends GetxController
|
||||
title: const Text("本次登录需要验证您的手机号"),
|
||||
content: Column(
|
||||
children:[
|
||||
Text(accountInfo['bindTel'] ?? '未能获取手机号'),
|
||||
Text(accountInfo['hindTel'] ?? '未能获取手机号'),
|
||||
TextField(
|
||||
controller: _textFieldController,
|
||||
decoration: const InputDecoration(hintText: "请输入短信验证码"),
|
||||
|
||||
@@ -139,7 +139,7 @@ class _MainAppState extends State<MainApp> with SingleTickerProviderStateMixin {
|
||||
],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
stops: const [0.1, 0.4 ,0.7]),
|
||||
stops: const [0.1, 0.4, 0.7]),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -81,7 +81,7 @@ class _SysMsgPageState extends State<SysMsgPage> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
SelectableText(
|
||||
"$content",
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
|
||||
@@ -74,7 +74,7 @@ Widget searchArticlePanel(BuildContext context, ctr, list) {
|
||||
TextSpan(
|
||||
text: i['text'],
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontWeight: FontWeight.w600,
|
||||
letterSpacing: 0.3,
|
||||
color: i['type'] == 'em'
|
||||
? Theme.of(context)
|
||||
|
||||
@@ -114,7 +114,7 @@ class LiveContent extends StatelessWidget {
|
||||
TextSpan(
|
||||
text: i['text'],
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontWeight: FontWeight.w600,
|
||||
letterSpacing: 0.3,
|
||||
color: i['type'] == 'em'
|
||||
? Theme.of(context).colorScheme.primary
|
||||
|
||||
@@ -85,7 +85,7 @@ class _PlaySettingState extends State<PlaySetting> {
|
||||
),
|
||||
const SetSwitchItem(
|
||||
title: '双击快退/快进',
|
||||
subTitle: '左侧双击快退,右侧双击快进',
|
||||
subTitle: '左侧双击快退/右侧双击快进,关闭则双击均为暂停/播放',
|
||||
leading: Icon(Icons.touch_app_outlined),
|
||||
setKey: SettingBoxKey.enableQuickDouble,
|
||||
defaultVal: true,
|
||||
@@ -139,6 +139,13 @@ class _PlaySettingState extends State<PlaySetting> {
|
||||
setKey: SettingBoxKey.enableAutoExit,
|
||||
defaultVal: true,
|
||||
),
|
||||
const SetSwitchItem(
|
||||
title: '延长播放控件显示时间',
|
||||
subTitle: '开启后延长至30秒,便于屏幕阅读器滑动切换控件焦点',
|
||||
leading: Icon(Icons.timer_outlined),
|
||||
setKey: SettingBoxKey.enableLongShowControl,
|
||||
defaultVal: false
|
||||
),
|
||||
const SetSwitchItem(
|
||||
title: '全向旋转',
|
||||
subTitle: '小屏可受重力转为临时全屏,若系统锁定旋转仍触发请关闭,关闭会影响横屏适配',
|
||||
|
||||
@@ -69,7 +69,7 @@ class _StyleSettingState extends State<StyleSetting> {
|
||||
children: [
|
||||
SetSwitchItem(
|
||||
title: '横屏适配',
|
||||
subTitle: '启用横屏布局与逻辑,适用于平板等设备;推荐全屏方向设为【不改变当前方向】',
|
||||
subTitle: '启用横屏布局与逻辑,平板、折叠屏等可开启;建议全屏方向设为【不改变当前方向】',
|
||||
leading: const Icon(Icons.phonelink_outlined),
|
||||
setKey: SettingBoxKey.horizontalScreen,
|
||||
defaultVal: false,
|
||||
|
||||
@@ -97,7 +97,7 @@ class VideoContent extends StatelessWidget {
|
||||
subFolderItem.title!,
|
||||
textAlign: TextAlign.start,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontWeight: FontWeight.w600,
|
||||
letterSpacing: 0.3,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -130,7 +130,7 @@ class VideoContent extends StatelessWidget {
|
||||
videoItem.title,
|
||||
textAlign: TextAlign.start,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontWeight: FontWeight.w600,
|
||||
letterSpacing: 0.3,
|
||||
),
|
||||
maxLines: 2,
|
||||
|
||||
@@ -303,7 +303,7 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
// : videoItem['title'] ?? "",
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
|
||||
@@ -47,7 +47,7 @@ class IntroDetail extends StatelessWidget {
|
||||
videoDetail!.title,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
|
||||
@@ -92,7 +92,7 @@ class VideoReplyController extends GetxController {
|
||||
}
|
||||
}
|
||||
replies.insertAll(0, res['data'].topReplies);
|
||||
count.value = res['data'].cursor.allCount;
|
||||
count.value = res['data'].cursor.allCount ?? 0;
|
||||
replyList.value = replies;
|
||||
} else {
|
||||
replyList.addAll(replies);
|
||||
|
||||
@@ -11,7 +11,7 @@ class VideoReplyReplyController extends GetxController {
|
||||
int? aid;
|
||||
// rpid 请求楼中楼回复
|
||||
String? rpid;
|
||||
ReplyType replyType = ReplyType.video;
|
||||
ReplyType replyType; // = ReplyType.video;
|
||||
RxList<ReplyItemModel> replyList = <ReplyItemModel>[].obs;
|
||||
// 当前页
|
||||
int currentPage = 0;
|
||||
@@ -19,6 +19,7 @@ class VideoReplyReplyController extends GetxController {
|
||||
RxString noMore = ''.obs;
|
||||
// 当前回复的回复
|
||||
ReplyItemModel? currentReplyItem;
|
||||
ReplyItemModel? root;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
@@ -41,6 +42,7 @@ class VideoReplyReplyController extends GetxController {
|
||||
type: replyType.index,
|
||||
);
|
||||
if (res['status']) {
|
||||
if (res['data'].root != null) root = res['data'].root;
|
||||
final List<ReplyItemModel> replies = res['data'].replies;
|
||||
if (replies.isNotEmpty) {
|
||||
noMore.value = '加载中...';
|
||||
|
||||
@@ -73,7 +73,8 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: widget.source == 'videoDetail' ? Utils.getSheetHeight(context) : null,
|
||||
height:
|
||||
widget.source == 'videoDetail' ? Utils.getSheetHeight(context) : null,
|
||||
color: Theme.of(context).colorScheme.background,
|
||||
child: Column(
|
||||
children: [
|
||||
@@ -137,60 +138,91 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel> {
|
||||
FutureBuilder(
|
||||
future: _futureBuilderFuture,
|
||||
builder: (BuildContext context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.done) {
|
||||
if (snapshot.connectionState == ConnectionState.done &&
|
||||
snapshot.hasData) {
|
||||
final Map data = snapshot.data as Map;
|
||||
if (data['status']) {
|
||||
// 请求成功
|
||||
return Obx(
|
||||
() => SliverList(
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
(BuildContext context, int index) {
|
||||
if (index ==
|
||||
_videoReplyReplyController
|
||||
.replyList.length) {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: MediaQuery.of(context)
|
||||
.padding
|
||||
.bottom),
|
||||
height: MediaQuery.of(context)
|
||||
.padding
|
||||
.bottom +
|
||||
100,
|
||||
child: Center(
|
||||
child: Obx(
|
||||
() => Text(
|
||||
_videoReplyReplyController
|
||||
.noMore.value,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.outline,
|
||||
return SliverMainAxisGroup(
|
||||
slivers: <Widget>[
|
||||
if (widget.firstFloor == null &&
|
||||
_videoReplyReplyController.root != null) ...[
|
||||
SliverToBoxAdapter(
|
||||
child: ReplyItem(
|
||||
replyItem: _videoReplyReplyController.root,
|
||||
replyLevel: '2',
|
||||
showReplyRow: false,
|
||||
addReply: (replyItem) {
|
||||
_videoReplyReplyController.replyList
|
||||
.add(replyItem);
|
||||
},
|
||||
replyType: widget.replyType,
|
||||
replyReply: (replyItem) =>
|
||||
replyReply(replyItem),
|
||||
),
|
||||
),
|
||||
SliverToBoxAdapter(
|
||||
child: Divider(
|
||||
height: 20,
|
||||
color: Theme.of(context)
|
||||
.dividerColor
|
||||
.withOpacity(0.1),
|
||||
thickness: 6,
|
||||
),
|
||||
),
|
||||
],
|
||||
Obx(
|
||||
() => SliverList(
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
(BuildContext context, int index) {
|
||||
if (index ==
|
||||
_videoReplyReplyController
|
||||
.replyList.length) {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: MediaQuery.of(context)
|
||||
.padding
|
||||
.bottom),
|
||||
height: MediaQuery.of(context)
|
||||
.padding
|
||||
.bottom +
|
||||
100,
|
||||
child: Center(
|
||||
child: Obx(
|
||||
() => Text(
|
||||
_videoReplyReplyController
|
||||
.noMore.value,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.outline,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return ReplyItem(
|
||||
replyItem: _videoReplyReplyController
|
||||
.replyList[index],
|
||||
replyLevel: '2',
|
||||
showReplyRow: false,
|
||||
addReply: (replyItem) {
|
||||
_videoReplyReplyController.replyList
|
||||
.add(replyItem);
|
||||
},
|
||||
replyType: widget.replyType,
|
||||
);
|
||||
}
|
||||
},
|
||||
childCount: _videoReplyReplyController
|
||||
.replyList.length +
|
||||
1,
|
||||
);
|
||||
} else {
|
||||
return ReplyItem(
|
||||
replyItem: _videoReplyReplyController
|
||||
.replyList[index],
|
||||
replyLevel: '2',
|
||||
showReplyRow: false,
|
||||
addReply: (replyItem) {
|
||||
_videoReplyReplyController.replyList
|
||||
.add(replyItem);
|
||||
},
|
||||
replyType: widget.replyType,
|
||||
);
|
||||
}
|
||||
},
|
||||
childCount: _videoReplyReplyController
|
||||
.replyList.length +
|
||||
1,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
// 请求错误
|
||||
|
||||
@@ -453,7 +453,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
bottom: 10,
|
||||
child: IconButton(
|
||||
tooltip: '播放',
|
||||
onPressed: () => handlePlay(),
|
||||
onPressed: handlePlay,
|
||||
icon: Image.asset(
|
||||
'assets/images/play.png',
|
||||
width: 60,
|
||||
@@ -565,9 +565,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
handlePlay();
|
||||
},
|
||||
onTap: handlePlay,
|
||||
child: NetworkImgLayer(
|
||||
type: 'emote',
|
||||
src: videoDetailController
|
||||
@@ -698,9 +696,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
handlePlay();
|
||||
},
|
||||
onTap: handlePlay,
|
||||
child: NetworkImgLayer(
|
||||
type: 'emote',
|
||||
src: videoDetailController.videoItem['pic'],
|
||||
@@ -793,9 +789,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
handlePlay();
|
||||
},
|
||||
onTap: handlePlay,
|
||||
child: NetworkImgLayer(
|
||||
type: 'emote',
|
||||
src: videoDetailController.videoItem['pic'],
|
||||
@@ -891,9 +885,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
handlePlay();
|
||||
},
|
||||
onTap: handlePlay,
|
||||
child: NetworkImgLayer(
|
||||
type: 'emote',
|
||||
src: videoDetailController.videoItem['pic'],
|
||||
@@ -997,9 +989,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
handlePlay();
|
||||
},
|
||||
onTap: handlePlay,
|
||||
child: NetworkImgLayer(
|
||||
type: 'emote',
|
||||
src: videoDetailController
|
||||
|
||||
@@ -4,11 +4,13 @@ import 'dart:math';
|
||||
|
||||
import 'package:floating/floating.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.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:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
import 'package:media_kit/media_kit.dart';
|
||||
import 'package:ns_danmaku/ns_danmaku.dart';
|
||||
import 'package:PiliPalaX/http/user.dart';
|
||||
import 'package:PiliPalaX/models/video/play/quality.dart';
|
||||
@@ -223,6 +225,22 @@ class _HeaderControlState extends State<HeaderControl> {
|
||||
}
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Get.back();
|
||||
Player? player =
|
||||
widget.controller?.videoPlayerController;
|
||||
if (player == null) {
|
||||
SmartDialog.showToast('播放器未初始化');
|
||||
return;
|
||||
}
|
||||
var pp = player.platform as NativePlayer;
|
||||
pp.setProperty("video", "no");
|
||||
},
|
||||
dense: true,
|
||||
leading: const Icon(Icons.headphones_outlined, size: 20),
|
||||
title: const Text('听视频(需返回首页才能终止该状态)', style: titleStyle),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () => {Get.back(), showSetVideoQa()},
|
||||
dense: true,
|
||||
@@ -265,6 +283,172 @@ class _HeaderControlState extends State<HeaderControl> {
|
||||
leading: const Icon(Icons.subtitles_outlined, size: 20),
|
||||
title: const Text('弹幕设置', style: titleStyle),
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('播放信息', style: titleStyle),
|
||||
leading: const Icon(Icons.info_outline, size: 20),
|
||||
onTap: () {
|
||||
Player? player =
|
||||
widget.controller?.videoPlayerController;
|
||||
if (player == null) {
|
||||
SmartDialog.showToast('播放器未初始化');
|
||||
return;
|
||||
}
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: const Text('播放信息'),
|
||||
content: SizedBox(
|
||||
width: double.maxFinite,
|
||||
child: ListView(
|
||||
children: [
|
||||
ListTile(
|
||||
title: const Text("Resolution"),
|
||||
subtitle: Text(
|
||||
'${player.state.width}x${player.state.height}'),
|
||||
onTap: () {
|
||||
Clipboard.setData(
|
||||
ClipboardData(
|
||||
text:
|
||||
"Resolution\n${player.state.width}x${player.state.height}",
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: const Text("VideoParams"),
|
||||
subtitle: Text(player.state.videoParams
|
||||
.toString()),
|
||||
onTap: () {
|
||||
Clipboard.setData(
|
||||
ClipboardData(
|
||||
text:
|
||||
"VideoParams\n${player.state.videoParams}",
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: const Text("AudioParams"),
|
||||
subtitle: Text(player.state.audioParams
|
||||
.toString()),
|
||||
onTap: () {
|
||||
Clipboard.setData(
|
||||
ClipboardData(
|
||||
text:
|
||||
"AudioParams\n${player.state.audioParams}",
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: const Text("Media"),
|
||||
subtitle: Text(
|
||||
player.state.playlist.toString()),
|
||||
onTap: () {
|
||||
Clipboard.setData(
|
||||
ClipboardData(
|
||||
text:
|
||||
"Media\n${player.state.playlist}",
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: const Text("AudioTrack"),
|
||||
subtitle: Text(player.state.track.audio
|
||||
.toString()),
|
||||
onTap: () {
|
||||
Clipboard.setData(
|
||||
ClipboardData(
|
||||
text:
|
||||
"AudioTrack\n${player.state.track.audio}",
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: const Text("VideoTrack"),
|
||||
subtitle: Text(player.state.track.video
|
||||
.toString()),
|
||||
onTap: () {
|
||||
Clipboard.setData(
|
||||
ClipboardData(
|
||||
text:
|
||||
"VideoTrack\n${player.state.track.audio}",
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: const Text("pitch"),
|
||||
subtitle: Text(
|
||||
player.state.pitch.toString()),
|
||||
onTap: () {
|
||||
Clipboard.setData(
|
||||
ClipboardData(
|
||||
text:
|
||||
"pitch\n${player.state.pitch}",
|
||||
),
|
||||
);
|
||||
}),
|
||||
ListTile(
|
||||
title: const Text("rate"),
|
||||
subtitle: Text(
|
||||
player.state.rate.toString()),
|
||||
onTap: () {
|
||||
Clipboard.setData(
|
||||
ClipboardData(
|
||||
text:
|
||||
"rate\n${player.state.rate}",
|
||||
),
|
||||
);
|
||||
}),
|
||||
ListTile(
|
||||
title: const Text("AudioBitrate"),
|
||||
subtitle: Text(player.state.audioBitrate
|
||||
.toString()),
|
||||
onTap: () {
|
||||
Clipboard.setData(
|
||||
ClipboardData(
|
||||
text:
|
||||
"AudioBitrate\n${player.state.audioBitrate}",
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: const Text("Volume"),
|
||||
subtitle: Text(
|
||||
player.state.volume.toString()),
|
||||
onTap: () {
|
||||
Clipboard.setData(
|
||||
ClipboardData(
|
||||
text:
|
||||
"Volume\n${player.state.volume}",
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Get.back(),
|
||||
child: Text(
|
||||
'确定',
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.outline),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
})
|
||||
],
|
||||
),
|
||||
))
|
||||
|
||||
@@ -79,25 +79,27 @@ class _WebviewPageState extends State<WebviewPage> {
|
||||
),
|
||||
],
|
||||
Expanded(
|
||||
child: WebViewWidget(
|
||||
controller: _webviewController.controller,
|
||||
gestureRecognizers: <Factory<OneSequenceGestureRecognizer>>{
|
||||
Factory<VerticalDragGestureRecognizer>(
|
||||
() => VerticalDragGestureRecognizer(),
|
||||
),
|
||||
Factory<PanGestureRecognizer>(
|
||||
() => PanGestureRecognizer(),
|
||||
),
|
||||
Factory<ForcePressGestureRecognizer>(
|
||||
() => ForcePressGestureRecognizer(),
|
||||
),
|
||||
Factory<EagerGestureRecognizer>(
|
||||
() => EagerGestureRecognizer(),
|
||||
),
|
||||
Factory<HorizontalDragGestureRecognizer>(
|
||||
() => HorizontalDragGestureRecognizer(),
|
||||
),
|
||||
}),
|
||||
child: SafeArea(
|
||||
child: WebViewWidget(
|
||||
controller: _webviewController.controller,
|
||||
gestureRecognizers: <Factory<OneSequenceGestureRecognizer>>{
|
||||
Factory<VerticalDragGestureRecognizer>(
|
||||
() => VerticalDragGestureRecognizer(),
|
||||
),
|
||||
Factory<PanGestureRecognizer>(
|
||||
() => PanGestureRecognizer(),
|
||||
),
|
||||
Factory<ForcePressGestureRecognizer>(
|
||||
() => ForcePressGestureRecognizer(),
|
||||
),
|
||||
Factory<EagerGestureRecognizer>(
|
||||
() => EagerGestureRecognizer(),
|
||||
),
|
||||
Factory<HorizontalDragGestureRecognizer>(
|
||||
() => HorizontalDragGestureRecognizer(),
|
||||
),
|
||||
}),
|
||||
),
|
||||
),
|
||||
],
|
||||
));
|
||||
|
||||
Reference in New Issue
Block a user