From e9dc1546424e85b3c4633faf0c2511a07bb30fb3 Mon Sep 17 00:00:00 2001 From: bggRGjQaUbCoE Date: Sat, 25 Oct 2025 12:21:16 +0800 Subject: [PATCH] tweaks Signed-off-by: bggRGjQaUbCoE --- lib/common/widgets/image/image_save.dart | 17 +- lib/common/widgets/video_popup_menu.dart | 680 ++++++++++---------- lib/http/init.dart | 3 +- lib/models/model_avatar.dart | 20 - lib/pages/live_room/view.dart | 1 + lib/pages/member_video/view.dart | 2 +- lib/pages/save_panel/view.dart | 36 +- lib/pages/setting/models/play_settings.dart | 2 +- lib/pages/video/ai_conclusion/view.dart | 3 +- lib/pages/video/reply_reply/view.dart | 10 +- lib/pages/video/view.dart | 4 +- lib/plugin/pl_player/view.dart | 2 + lib/utils/app_scheme.dart | 51 +- 13 files changed, 423 insertions(+), 408 deletions(-) diff --git a/lib/common/widgets/image/image_save.dart b/lib/common/widgets/image/image_save.dart index 9718d25a..7da6da54 100644 --- a/lib/common/widgets/image/image_save.dart +++ b/lib/common/widgets/image/image_save.dart @@ -28,6 +28,7 @@ void imageSaveDialog({ return iconButton( icon: icon, iconSize: 20, + tooltip: tooltip, onPressed: onPressed, ); } @@ -57,19 +58,19 @@ void imageSaveDialog({ Positioned( right: 8, top: 8, - child: Container( + child: SizedBox( width: 30, height: 30, - decoration: BoxDecoration( - color: Colors.black.withValues(alpha: 0.3), - shape: BoxShape.circle, - ), - child: const IconButton( + child: IconButton( + tooltip: '关闭', style: ButtonStyle( - padding: WidgetStatePropertyAll(EdgeInsets.zero), + backgroundColor: WidgetStatePropertyAll( + Colors.black.withValues(alpha: 0.3), + ), + padding: const WidgetStatePropertyAll(EdgeInsets.zero), ), onPressed: SmartDialog.dismiss, - icon: Icon( + icon: const Icon( Icons.close, size: 18, color: Colors.white, diff --git a/lib/common/widgets/video_popup_menu.dart b/lib/common/widgets/video_popup_menu.dart index 0a71e3bc..6d12a671 100644 --- a/lib/common/widgets/video_popup_menu.dart +++ b/lib/common/widgets/video_popup_menu.dart @@ -9,329 +9,25 @@ import 'package:PiliPlus/pages/search/widgets/search_text.dart'; import 'package:PiliPlus/pages/video/ai_conclusion/view.dart'; import 'package:PiliPlus/pages/video/introduction/ugc/controller.dart'; import 'package:PiliPlus/utils/accounts.dart'; +import 'package:PiliPlus/utils/storage_pref.dart'; import 'package:PiliPlus/utils/utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; -class VideoCustomAction { +class _VideoCustomAction { final String title; final Widget icon; - final VoidCallback? onTap; - const VideoCustomAction(this.title, this.icon, this.onTap); -} - -class VideoCustomActions { - BaseSimpleVideoItemModel videoItem; - BuildContext context; - late List actions; - VoidCallback? onRemove; - - VideoCustomActions(this.videoItem, this.context, [this.onRemove]) { - actions = [ - if (videoItem.bvid?.isNotEmpty == true) ...[ - VideoCustomAction( - videoItem.bvid!, - const Stack( - clipBehavior: Clip.none, - children: [ - Icon(MdiIcons.identifier, size: 16), - Icon(MdiIcons.circleOutline, size: 16), - ], - ), - () => Utils.copyText(videoItem.bvid!), - ), - VideoCustomAction( - '稍后再看', - const Icon(MdiIcons.clockTimeEightOutline, size: 16), - () async { - var res = await UserHttp.toViewLater(bvid: videoItem.bvid); - SmartDialog.showToast(res['msg']); - }, - ), - VideoCustomAction( - 'AI总结', - const Stack( - alignment: Alignment.center, - clipBehavior: Clip.none, - children: [ - Icon(Icons.circle_outlined, size: 16), - ExcludeSemantics( - child: Text( - 'AI', - style: TextStyle( - fontSize: 8, - height: 1, - fontWeight: FontWeight.w900, - ), - textScaler: TextScaler.noScaling, - ), - ), - ], - ), - () async { - final res = await UgcIntroController.getAiConclusion( - videoItem.bvid!, - videoItem.cid!, - videoItem.owner.mid, - ); - if (res != null && context.mounted) { - showDialog( - context: context, - builder: (context) { - final theme = Theme.of(context); - return Dialog( - child: ConstrainedBox( - constraints: const BoxConstraints(maxWidth: 420), - child: Padding( - padding: const EdgeInsets.only(top: 14), - child: AiConclusionPanel.buildContent( - context, - theme, - res, - tap: false, - ), - ), - ), - ); - }, - ); - } - }, - ), - ], - if (videoItem is! SpaceArchiveItem) - VideoCustomAction( - '访问:${videoItem.owner.name}', - const Icon(MdiIcons.accountCircleOutline, size: 16), - () => Get.toNamed('/member?mid=${videoItem.owner.mid}'), - ), - if (videoItem is! SpaceArchiveItem) - VideoCustomAction( - '不感兴趣', - const Icon(MdiIcons.thumbDownOutline, size: 16), - () { - String? accessKey = Accounts.get(AccountType.recommend).accessKey; - if (accessKey == null || accessKey == "") { - SmartDialog.showToast("请退出账号后重新登录"); - return; - } - if (videoItem case RecVideoItemAppModel item) { - ThreePoint? tp = item.threePoint; - if (tp == null) { - SmartDialog.showToast("未能获取threePoint"); - return; - } - if (tp.dislikeReasons == null && tp.feedbacks == null) { - SmartDialog.showToast("未能获取dislikeReasons或feedbacks"); - return; - } - Widget actionButton(Reason? r, Reason? f) { - return SearchText( - text: r?.name ?? f?.name ?? '未知', - onTap: (_) async { - Get.back(); - SmartDialog.showLoading(msg: '正在提交'); - var res = await VideoHttp.feedDislike( - reasonId: r?.id, - feedbackId: f?.id, - id: item.param!, - goto: item.goto!, - ); - SmartDialog.dismiss(); - SmartDialog.showToast( - res['status'] ? (r?.toast ?? f?.toast) : res['msg'], - ); - if (res['status']) { - onRemove?.call(); - } - }, - ); - } - - showDialog( - context: context, - builder: (context) { - return AlertDialog( - content: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (tp.dislikeReasons != null) ...[ - const Text('我不想看'), - const SizedBox(height: 5), - Wrap( - spacing: 8.0, - runSpacing: 8.0, - children: tp.dislikeReasons!.map((item) { - return actionButton(item, null); - }).toList(), - ), - ], - if (tp.feedbacks != null) ...[ - const SizedBox(height: 5), - const Text('反馈'), - const SizedBox(height: 5), - Wrap( - spacing: 8.0, - runSpacing: 8.0, - children: tp.feedbacks!.map((item) { - return actionButton(null, item); - }).toList(), - ), - ], - const Divider(), - Center( - child: FilledButton.tonal( - onPressed: () async { - SmartDialog.showLoading(msg: '正在提交'); - var res = await VideoHttp.feedDislikeCancel( - id: item.param!, - goto: item.goto!, - ); - SmartDialog.dismiss(); - SmartDialog.showToast( - res['status'] ? "成功" : res['msg'], - ); - Get.back(); - }, - style: FilledButton.styleFrom( - visualDensity: VisualDensity.compact, - ), - child: const Text("撤销"), - ), - ), - ], - ), - ), - ); - }, - ); - } else { - showDialog( - context: context, - builder: (context) { - return AlertDialog( - content: SingleChildScrollView( - child: Column( - children: [ - const SizedBox(height: 5), - const Text("web端暂不支持精细选择"), - const SizedBox(height: 5), - Wrap( - spacing: 5.0, - runSpacing: 2.0, - children: [ - FilledButton.tonal( - onPressed: () async { - Get.back(); - SmartDialog.showLoading(msg: '正在提交'); - var res = await VideoHttp.dislikeVideo( - bvid: videoItem.bvid!, - type: true, - ); - SmartDialog.dismiss(); - SmartDialog.showToast( - res['status'] ? "点踩成功" : res['msg'], - ); - if (res['status']) { - onRemove?.call(); - } - }, - style: FilledButton.styleFrom( - visualDensity: VisualDensity.compact, - ), - child: const Text("点踩"), - ), - FilledButton.tonal( - onPressed: () async { - Get.back(); - SmartDialog.showLoading(msg: '正在提交'); - var res = await VideoHttp.dislikeVideo( - bvid: videoItem.bvid!, - type: false, - ); - SmartDialog.dismiss(); - SmartDialog.showToast( - res['status'] ? "取消踩" : res['msg'], - ); - }, - style: FilledButton.styleFrom( - visualDensity: VisualDensity.compact, - ), - child: const Text("撤销"), - ), - ], - ), - ], - ), - ), - ); - }, - ); - } - }, - ), - if (videoItem is! SpaceArchiveItem) - VideoCustomAction( - '拉黑:${videoItem.owner.name}', - const Icon(MdiIcons.cancel, size: 16), - () => showDialog( - context: context, - builder: (context) { - return AlertDialog( - title: const Text('提示'), - content: Text( - '确定拉黑:${videoItem.owner.name}(${videoItem.owner.mid})?' - '\n\n注:被拉黑的Up可以在隐私设置-黑名单管理中解除', - ), - actions: [ - TextButton( - onPressed: Get.back, - child: Text( - '点错了', - style: TextStyle( - color: Theme.of(context).colorScheme.outline, - ), - ), - ), - TextButton( - onPressed: () async { - Get.back(); - var res = await VideoHttp.relationMod( - mid: videoItem.owner.mid!, - act: 5, - reSrc: 11, - ); - if (res['status']) { - onRemove?.call(); - } - SmartDialog.showToast(res['msg'] ?? '成功'); - }, - child: const Text('确认'), - ), - ], - ); - }, - ), - ), - VideoCustomAction( - "${MineController.anonymity.value ? '退出' : '进入'}无痕模式", - MineController.anonymity.value - ? const Icon(MdiIcons.incognitoOff, size: 16) - : const Icon(MdiIcons.incognito, size: 16), - MineController.onChangeAnonymity, - ), - ]; - } + final VoidCallback onTap; + const _VideoCustomAction(this.title, this.icon, this.onTap); } class VideoPopupMenu extends StatelessWidget { final double? size; final double? iconSize; final double menuItemHeight; - final dynamic videoItem; + final BaseSimpleVideoItemModel videoItem; final VoidCallback? onRemove; const VideoPopupMenu({ @@ -349,7 +45,7 @@ class VideoPopupMenu extends StatelessWidget { child: SizedBox( width: size, height: size, - child: PopupMenuButton( + child: PopupMenuButton( padding: EdgeInsets.zero, icon: Icon( Icons.more_vert_outlined, @@ -357,20 +53,358 @@ class VideoPopupMenu extends StatelessWidget { size: iconSize, ), position: PopupMenuPosition.under, - itemBuilder: (BuildContext context) => - VideoCustomActions(videoItem, context, onRemove).actions.map((e) { - return PopupMenuItem( - height: menuItemHeight, - onTap: e.onTap, - child: Row( - children: [ - e.icon, - const SizedBox(width: 6), - Text(e.title, style: const TextStyle(fontSize: 13)), + itemBuilder: (context) => + [ + if (videoItem.bvid?.isNotEmpty == true) ...[ + _VideoCustomAction( + videoItem.bvid!, + const Stack( + clipBehavior: Clip.none, + children: [ + Icon(MdiIcons.identifier, size: 16), + Icon(MdiIcons.circleOutline, size: 16), + ], + ), + () => Utils.copyText(videoItem.bvid!), + ), + _VideoCustomAction( + '稍后再看', + const Icon(MdiIcons.clockTimeEightOutline, size: 16), + () async { + var res = await UserHttp.toViewLater( + bvid: videoItem.bvid, + ); + SmartDialog.showToast(res['msg']); + }, + ), + if (videoItem.cid != null && Pref.enableAi) + _VideoCustomAction( + 'AI总结', + const Stack( + alignment: Alignment.center, + clipBehavior: Clip.none, + children: [ + Icon(Icons.circle_outlined, size: 16), + ExcludeSemantics( + child: Text( + 'AI', + style: TextStyle( + fontSize: 10, + height: 1, + fontWeight: FontWeight.w700, + ), + strutStyle: StrutStyle( + fontSize: 10, + height: 1, + leading: 0, + fontWeight: FontWeight.w700, + ), + textScaler: TextScaler.noScaling, + ), + ), + ], + ), + () async { + final res = + await UgcIntroController.getAiConclusion( + videoItem.bvid!, + videoItem.cid!, + videoItem.owner.mid, + ); + if (res != null && context.mounted) { + showDialog( + context: context, + builder: (context) { + return Dialog( + child: ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: 420, + ), + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 14, + ), + child: AiConclusionPanel.buildContent( + context, + Theme.of(context), + res, + tap: false, + ), + ), + ), + ); + }, + ); + } + }, + ), ], - ), - ); - }).toList(), + if (videoItem is! SpaceArchiveItem) ...[ + _VideoCustomAction( + '访问:${videoItem.owner.name}', + const Icon(MdiIcons.accountCircleOutline, size: 16), + () => Get.toNamed('/member?mid=${videoItem.owner.mid}'), + ), + _VideoCustomAction( + '不感兴趣', + const Icon(MdiIcons.thumbDownOutline, size: 16), + () { + String? accessKey = Accounts.get( + AccountType.recommend, + ).accessKey; + if (accessKey == null || accessKey == "") { + SmartDialog.showToast("请退出账号后重新登录"); + return; + } + if (videoItem case RecVideoItemAppModel item) { + ThreePoint? tp = item.threePoint; + if (tp == null) { + SmartDialog.showToast("未能获取threePoint"); + return; + } + if (tp.dislikeReasons == null && + tp.feedbacks == null) { + SmartDialog.showToast( + "未能获取dislikeReasons或feedbacks", + ); + return; + } + Widget actionButton(Reason? r, Reason? f) { + return SearchText( + text: r?.name ?? f?.name ?? '未知', + onTap: (_) async { + Get.back(); + SmartDialog.showLoading(msg: '正在提交'); + var res = await VideoHttp.feedDislike( + reasonId: r?.id, + feedbackId: f?.id, + id: item.param!, + goto: item.goto!, + ); + SmartDialog.dismiss(); + SmartDialog.showToast( + res['status'] + ? (r?.toast ?? f?.toast) + : res['msg'], + ); + if (res['status']) { + onRemove?.call(); + } + }, + ); + } + + showDialog( + context: context, + builder: (context) { + return AlertDialog( + content: SingleChildScrollView( + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + if (tp.dislikeReasons != null) ...[ + const Text('我不想看'), + const SizedBox(height: 5), + Wrap( + spacing: 8.0, + runSpacing: 8.0, + children: tp.dislikeReasons!.map(( + item, + ) { + return actionButton(item, null); + }).toList(), + ), + ], + if (tp.feedbacks != null) ...[ + const SizedBox(height: 5), + const Text('反馈'), + const SizedBox(height: 5), + Wrap( + spacing: 8.0, + runSpacing: 8.0, + children: tp.feedbacks!.map((item) { + return actionButton(null, item); + }).toList(), + ), + ], + const Divider(), + Center( + child: FilledButton.tonal( + onPressed: () async { + SmartDialog.showLoading( + msg: '正在提交', + ); + var res = + await VideoHttp.feedDislikeCancel( + id: item.param!, + goto: item.goto!, + ); + SmartDialog.dismiss(); + SmartDialog.showToast( + res['status'] + ? "成功" + : res['msg'], + ); + Get.back(); + }, + style: FilledButton.styleFrom( + visualDensity: + VisualDensity.compact, + ), + child: const Text("撤销"), + ), + ), + ], + ), + ), + ); + }, + ); + } else { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + content: SingleChildScrollView( + child: Column( + children: [ + const SizedBox(height: 5), + const Text("web端暂不支持精细选择"), + const SizedBox(height: 5), + Wrap( + spacing: 5.0, + runSpacing: 2.0, + children: [ + FilledButton.tonal( + onPressed: () async { + Get.back(); + SmartDialog.showLoading( + msg: '正在提交', + ); + var res = + await VideoHttp.dislikeVideo( + bvid: videoItem.bvid!, + type: true, + ); + SmartDialog.dismiss(); + SmartDialog.showToast( + res['status'] + ? "点踩成功" + : res['msg'], + ); + if (res['status']) { + onRemove?.call(); + } + }, + style: FilledButton.styleFrom( + visualDensity: + VisualDensity.compact, + ), + child: const Text("点踩"), + ), + FilledButton.tonal( + onPressed: () async { + Get.back(); + SmartDialog.showLoading( + msg: '正在提交', + ); + var res = + await VideoHttp.dislikeVideo( + bvid: videoItem.bvid!, + type: false, + ); + SmartDialog.dismiss(); + SmartDialog.showToast( + res['status'] + ? "取消踩" + : res['msg'], + ); + }, + style: FilledButton.styleFrom( + visualDensity: + VisualDensity.compact, + ), + child: const Text("撤销"), + ), + ], + ), + ], + ), + ), + ); + }, + ); + } + }, + ), + _VideoCustomAction( + '拉黑:${videoItem.owner.name}', + const Icon(MdiIcons.cancel, size: 16), + () => showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: const Text('提示'), + content: Text( + '确定拉黑:${videoItem.owner.name}(${videoItem.owner.mid})?' + '\n\n注:被拉黑的Up可以在隐私设置-黑名单管理中解除', + ), + actions: [ + TextButton( + onPressed: Get.back, + child: Text( + '点错了', + style: TextStyle( + color: Theme.of( + context, + ).colorScheme.outline, + ), + ), + ), + TextButton( + onPressed: () async { + Get.back(); + var res = await VideoHttp.relationMod( + mid: videoItem.owner.mid!, + act: 5, + reSrc: 11, + ); + if (res['status']) { + onRemove?.call(); + } + SmartDialog.showToast(res['msg'] ?? '成功'); + }, + child: const Text('确认'), + ), + ], + ); + }, + ), + ), + ], + _VideoCustomAction( + "${MineController.anonymity.value ? '退出' : '进入'}无痕模式", + MineController.anonymity.value + ? const Icon(MdiIcons.incognitoOff, size: 16) + : const Icon(MdiIcons.incognito, size: 16), + MineController.onChangeAnonymity, + ), + ] + .map( + (e) => PopupMenuItem( + height: menuItemHeight, + onTap: e.onTap, + child: Row( + children: [ + e.icon, + const SizedBox(width: 6), + Text(e.title, style: const TextStyle(fontSize: 13)), + ], + ), + ), + ) + .toList(), ), ), ); diff --git a/lib/http/init.dart b/lib/http/init.dart index f8342bc4..f0c0e2c6 100644 --- a/lib/http/init.dart +++ b/lib/http/init.dart @@ -70,8 +70,7 @@ class Request { String jsonData = json.encode({ '3064': 1, - '39c8': - '${account is AnonymousAccount ? '333.1365' : '333.788'}.fp.risk', + '39c8': '333.1387.fp.risk', '3c43': { 'adca': 'Linux', 'bfe9': randPngEnd.substring(randPngEnd.length - 50), diff --git a/lib/models/model_avatar.dart b/lib/models/model_avatar.dart index 2966fd45..16aec7e9 100644 --- a/lib/models/model_avatar.dart +++ b/lib/models/model_avatar.dart @@ -15,13 +15,9 @@ class Avatar extends Owner { } class Pendant { - int? pid; - String? name; String? image; Pendant.fromJson(Map json) { - pid = json['pid']; - name = json['name']; image = json['image']; } } @@ -39,35 +35,19 @@ class BaseOfficialVerify { class Vip { int? type; late int status; - int? dueDate; Label? label; Vip.fromJson(Map json) { type = json['type'] ?? json['vipType']; status = json['status'] ?? json['vipStatus'] ?? 0; - dueDate = json['due_date'] ?? json['vipDueDate']; if (json['label'] != null) label = Label.fromJson(json['label']); } } class Label { - String? path; String? text; - String? labelTheme; - String? textColor; - int? bgStyle; - String? bgColor; - String? borderColor; - String? image; Label.fromJson(Map json) { - path = json['path']; text = json['text']; - labelTheme = json['label_theme']; - textColor = json['text_color']; - bgStyle = json['bg_style']; - bgColor = json['bg_color']; - borderColor = json['border_color']; - image = json['image']; } } diff --git a/lib/pages/live_room/view.dart b/lib/pages/live_room/view.dart index beb04dba..d3cae5df 100644 --- a/lib/pages/live_room/view.dart +++ b/lib/pages/live_room/view.dart @@ -385,6 +385,7 @@ class _LiveRoomPageState extends State }, ), Scaffold( + resizeToAvoidBottomInset: false, backgroundColor: Colors.transparent, appBar: _buildAppBar(isFullScreen), body: isPortrait diff --git a/lib/pages/member_video/view.dart b/lib/pages/member_video/view.dart index e0169f21..31bcb441 100644 --- a/lib/pages/member_video/view.dart +++ b/lib/pages/member_video/view.dart @@ -119,7 +119,7 @@ class _MemberVideoState extends State Obx( () => !_controller.isLocating.value ? Positioned( - right: kFloatingActionButtonMargin + padding.right, + right: kFloatingActionButtonMargin, bottom: kFloatingActionButtonMargin + padding.bottom, child: FloatingActionButton.extended( onPressed: () { diff --git a/lib/pages/save_panel/view.dart b/lib/pages/save_panel/view.dart index d3dfb2cd..5cb5a214 100644 --- a/lib/pages/save_panel/view.dart +++ b/lib/pages/save_panel/view.dart @@ -501,28 +501,24 @@ class _SavePanelState extends State { GestureDetector( onTap: () => Utils.copyText(uri), child: Container( - width: 100, - height: 100, - padding: const EdgeInsets.all( + width: 88, + height: 88, + margin: const EdgeInsets.all( 12, ), - child: Container( - color: Get.isDarkMode - ? Colors.white - : theme - .colorScheme - .surface, - padding: const EdgeInsets.all( - 3, - ), - child: PrettyQrView.data( - data: uri, - decoration: - const PrettyQrDecoration( - shape: - PrettyQrSquaresSymbol(), - ), - ), + padding: const EdgeInsets.all( + 3, + ), + color: Get.isDarkMode + ? Colors.white + : theme.colorScheme.surface, + child: PrettyQrView.data( + data: uri, + decoration: + const PrettyQrDecoration( + shape: + PrettyQrSquaresSymbol(), + ), ), ), ), diff --git a/lib/pages/setting/models/play_settings.dart b/lib/pages/setting/models/play_settings.dart index 26737dd2..9cefdf95 100644 --- a/lib/pages/setting/models/play_settings.dart +++ b/lib/pages/setting/models/play_settings.dart @@ -162,7 +162,7 @@ List get playSettings => [ ), const SettingsModel( settingsType: SettingsType.sw1tch, - title: '显示 SuperChat', + title: '显示 SuperChat (醒目留言)', leading: Icon(Icons.live_tv), setKey: SettingBoxKey.showSuperChat, defaultVal: true, diff --git a/lib/pages/video/ai_conclusion/view.dart b/lib/pages/video/ai_conclusion/view.dart index b005c951..5eb918a7 100644 --- a/lib/pages/video/ai_conclusion/view.dart +++ b/lib/pages/video/ai_conclusion/view.dart @@ -28,6 +28,7 @@ class AiConclusionPanel extends CommonSlidePage { }) { return CustomScrollView( key: key, + shrinkWrap: !tap, physics: const AlwaysScrollableScrollPhysics(), slivers: [ if (res.summary?.isNotEmpty == true) ...[ @@ -57,7 +58,7 @@ class AiConclusionPanel extends CommonSlidePage { padding: EdgeInsets.only( left: 14, right: 14, - bottom: MediaQuery.viewPaddingOf(context).bottom + 100, + bottom: !tap ? 0 : MediaQuery.viewPaddingOf(context).bottom + 100, ), sliver: SliverList.builder( itemCount: res.outline!.length, diff --git a/lib/pages/video/reply_reply/view.dart b/lib/pages/video/reply_reply/view.dart index 15561741..aaecdbb8 100644 --- a/lib/pages/video/reply_reply/view.dart +++ b/lib/pages/video/reply_reply/view.dart @@ -47,13 +47,13 @@ class VideoReplyReplyPanel extends CommonSlidePage { @override State createState() => _VideoReplyReplyPanelState(); - static Future? toReply( - int oid, - int rootId, + static Future? toReply({ + required int oid, + required int rootId, String? rpIdStr, - int type, + required int type, Uri? uri, - ) { + }) { final rpId = rpIdStr == null ? null : int.tryParse(rpIdStr); return Get.to( arguments: { diff --git a/lib/pages/video/view.dart b/lib/pages/video/view.dart index b167d33d..1f5f1e5c 100644 --- a/lib/pages/video/view.dart +++ b/lib/pages/video/view.dart @@ -1370,7 +1370,7 @@ class _VideoDetailPageVState extends State child = plPlayer(width: maxWidth, height: maxHeight, isPipMode: true); } else if (!videoDetailController.horizontalScreen) { child = childWhenDisabled; - } else if (maxWidth > maxHeight * kScreenRatio) { + } else if (maxWidth / maxHeight >= kScreenRatio) { child = childWhenDisabledLandscape; } else if (maxWidth * (9 / 16) < (2 / 5) * maxHeight) { child = childWhenDisabled; @@ -1742,7 +1742,7 @@ class _VideoDetailPageVState extends State showEpisodes: showEpisodes, onShowMemberPage: onShowMemberPage, isPortrait: isPortrait, - isHorizontal: isHorizontal ?? width! > height! * kScreenRatio, + isHorizontal: isHorizontal ?? width! / height! >= kScreenRatio, ), if (needRelated && videoDetailController diff --git a/lib/plugin/pl_player/view.dart b/lib/plugin/pl_player/view.dart index 65535325..2d6727fa 100644 --- a/lib/plugin/pl_player/view.dart +++ b/lib/plugin/pl_player/view.dart @@ -1157,10 +1157,12 @@ class _PLVideoPlayerState extends State final item = ctr.findSingleDanmaku(pos); if (item == null) { _suspendedDm?.suspend = false; + _suspendedDm = null; _dmOffset.value = null; } else if (item != _suspendedDm) { _suspendedDm?.suspend = false; if (item.content.extra == null) { + _suspendedDm = null; _dmOffset.value = null; return; } diff --git a/lib/utils/app_scheme.dart b/lib/utils/app_scheme.dart index e3e818b1..209d83ac 100644 --- a/lib/utils/app_scheme.dart +++ b/lib/utils/app_scheme.dart @@ -125,11 +125,11 @@ abstract final class PiliScheme { int? rpid = int.tryParse(queryParameters['comment_root_id']!); if (oid != null && rpid != null) { VideoReplyReplyPanel.toReply( - int.parse(oid), - rpid, - queryParameters['comment_secondary_id'], - 1, - uri.replace(query: ''), + oid: int.parse(oid), + rootId: rpid, + rpIdStr: queryParameters['comment_secondary_id'], + type: 1, + uri: uri.replace(query: ''), ); return true; } @@ -225,11 +225,12 @@ abstract final class PiliScheme { // int.parse(queryParameters['extraIntentId'] ?? '0'); final enterUri = queryParameters['enterUri']; VideoReplyReplyPanel.toReply( - oid, - rootId, - queryParameters['anchor'], // source_id - type, - enterUri != null + oid: oid, + rootId: rootId, + rpIdStr: + queryParameters['anchor'] ?? pathSegments[3], // source_id + type: type, + uri: enterUri != null ? Uri.parse(enterUri) : const [11, 16, 17].contains(type) ? Uri( @@ -270,11 +271,11 @@ abstract final class PiliScheme { int? rpid = int.tryParse(commentRootId); if (dynId != null && rpid != null) { VideoReplyReplyPanel.toReply( - oid ?? int.parse(dynId), - rpid, - queryParameters['comment_secondary_id'], - businessId ?? 17, - uri.replace(query: ''), + oid: oid ?? int.parse(dynId), + rootId: rpid, + rpIdStr: queryParameters['comment_secondary_id'], + type: businessId ?? 17, + uri: uri.replace(query: ''), ); return true; } @@ -647,11 +648,11 @@ abstract final class PiliScheme { final part = queryParameters['p']; if (rootIdStr != null) { VideoReplyReplyPanel.toReply( - res.av ?? IdUtils.bv2av(res.bv!), - int.parse(rootIdStr), - queryParameters['comment_secondary_id'], - 1, - uri.replace(query: part != null ? 'p=$part' : ''), + oid: res.av ?? IdUtils.bv2av(res.bv!), + rootId: int.parse(rootIdStr), + rpIdStr: queryParameters['comment_secondary_id'], + type: 1, + uri: uri.replace(query: part != null ? 'p=$part' : ''), ); return true; } @@ -748,11 +749,11 @@ abstract final class PiliScheme { final pageType = queryParameters['pageType']; if (oid != null && root != null && pageType != null) { VideoReplyReplyPanel.toReply( - int.parse(oid), - int.parse(root), - queryParameters['comment_secondary_id'], - int.parse(pageType), - Uri(scheme: 'bilibili', host: 'video', path: oid), + oid: int.parse(oid), + rootId: int.parse(root), + rpIdStr: queryParameters['comment_secondary_id'], + type: int.parse(pageType), + uri: Uri(scheme: 'bilibili', host: 'video', path: oid), ); return true; }