diff --git a/lib/common/widgets/flutter/list_tile.dart b/lib/common/widgets/flutter/list_tile.dart index c655257b9..50749e80f 100644 --- a/lib/common/widgets/flutter/list_tile.dart +++ b/lib/common/widgets/flutter/list_tile.dart @@ -916,7 +916,12 @@ class ListTile extends StatelessWidget { // Show basic cursor when ListTile isn't enabled or gesture callbacks are null. final Set mouseStates = { - if (!enabled || (onTap == null && onLongPress == null)) + if (!enabled || + (onTap == null && + onTapUp == null && + onLongPress == null && + onSecondaryTap == null && + onSecondaryTapUp == null)) WidgetState.disabled, }; final MouseCursor effectiveMouseCursor = diff --git a/lib/pages/danmaku/controller.dart b/lib/pages/danmaku/controller.dart index e5f65424e..f91be9d43 100644 --- a/lib/pages/danmaku/controller.dart +++ b/lib/pages/danmaku/controller.dart @@ -25,9 +25,9 @@ class PlDanmakuController { late final _isLogin = Accounts.main.isLogin; - final Map> _dmSegMap = {}; + final Map> _dmSegMap = HashMap(); // 已请求的段落标记 - late final Set _requestedSeg = {}; + late final Set _requestedSeg = HashSet(); static const int segmentLength = 60 * 6 * 1000; diff --git a/lib/pages/live_room/widgets/header_control.dart b/lib/pages/live_room/widgets/header_control.dart index 2284eefc7..1b1cad040 100644 --- a/lib/pages/live_room/widgets/header_control.dart +++ b/lib/pages/live_room/widgets/header_control.dart @@ -58,8 +58,8 @@ class _LiveHeaderControlState extends State final liveController = widget.liveController; Widget child; child = Obx( + key: titleKey, () => MarqueeText( - key: titleKey, liveController.title.value, spacing: 30, velocity: 30, diff --git a/lib/pages/rank/view.dart b/lib/pages/rank/view.dart index ad178d1ef..ec2dbc304 100644 --- a/lib/pages/rank/view.dart +++ b/lib/pages/rank/view.dart @@ -43,7 +43,13 @@ class _RankPageState extends State ); } - static const double _tabHeight = 35.0; + @override + void didChangeDependencies() { + super.didChangeDependencies(); + _tabHeight = MediaQuery.textScalerOf(context).scale(21) + 14; + } + + late double _tabHeight; Widget _buildTab(ThemeData theme) { return SizedBox( diff --git a/lib/pages/setting/models/model.dart b/lib/pages/setting/models/model.dart index 90e3805fc..fc7d443fe 100644 --- a/lib/pages/setting/models/model.dart +++ b/lib/pages/setting/models/model.dart @@ -33,7 +33,6 @@ sealed class SettingsModel { class PopupModel extends SettingsModel { const PopupModel({ required this.title, - super.subtitle, super.leading, super.contentPadding, super.titleStyle, diff --git a/lib/pages/setting/pages/color_select.dart b/lib/pages/setting/pages/color_select.dart index bf6c7cb2a..c62396c09 100644 --- a/lib/pages/setting/pages/color_select.dart +++ b/lib/pages/setting/pages/color_select.dart @@ -42,6 +42,23 @@ class _ColorSelectPageState extends State { final ctr = Get.put(_ColorSelectController()); FlexSchemeVariant _dynamicSchemeVariant = Pref.schemeVariant; + Future _onChanged([bool? val]) async { + val ??= !ctr.dynamicColor.value; + if (val) { + if (await MyApp.initPlatformState()) { + Get.forceAppUpdate(); + } else { + SmartDialog.showToast('该设备可能不支持动态取色'); + return; + } + } else { + Get.forceAppUpdate(); + } + ctr + ..dynamicColor.value = val + ..setting.put(SettingBoxKey.dynamicColor, val); + } + @override Widget build(BuildContext context) { final theme = Theme.of(context); @@ -107,37 +124,21 @@ class _ColorSelectPageState extends State { ), if (!Platform.isIOS) Obx( - () { - final dynamicColor = ctr.dynamicColor.value; - return ListTile( - title: const Text('动态取色'), - leading: Checkbox( - value: dynamicColor, - onChanged: (value) {}, + () => ListTile( + title: const Text('动态取色'), + leading: ExcludeFocus( + child: Checkbox( + value: ctr.dynamicColor.value, + onChanged: _onChanged, materialTapTargetSize: .shrinkWrap, visualDensity: const VisualDensity( horizontal: -4, vertical: -4, ), ), - onTap: () async { - final val = !dynamicColor; - if (val) { - if (await MyApp.initPlatformState()) { - Get.forceAppUpdate(); - } else { - SmartDialog.showToast('该设备可能不支持动态取色'); - return; - } - } else { - Get.forceAppUpdate(); - } - ctr - ..dynamicColor.value = val - ..setting.put(SettingBoxKey.dynamicColor, val); - }, - ); - }, + ), + onTap: _onChanged, + ), ), Padding( padding: padding, @@ -147,9 +148,8 @@ class _ColorSelectPageState extends State { duration: const Duration(milliseconds: 200), child: Obx( () => ctr.dynamicColor.value - ? const SizedBox.shrink(key: ValueKey(false)) + ? const SizedBox.shrink() : Padding( - key: const ValueKey(true), padding: const EdgeInsets.all(12), child: Wrap( alignment: WrapAlignment.center, @@ -201,25 +201,29 @@ class _ColorSelectPageState extends State { ), Padding( padding: padding, - child: IgnorePointer( - child: Container( - height: size.height / 2, - width: size.width, - color: theme.colorScheme.surface, - child: const HomePage(), + child: ExcludeFocus( + child: IgnorePointer( + child: Container( + height: size.height / 2, + width: size.width, + color: theme.colorScheme.surface, + child: const HomePage(), + ), ), ), ), - IgnorePointer( - child: NavigationBar( - destinations: NavigationBarType.values - .map( - (item) => NavigationDestination( - icon: item.icon, - label: item.label, - ), - ) - .toList(), + ExcludeFocus( + child: IgnorePointer( + child: NavigationBar( + destinations: NavigationBarType.values + .map( + (item) => NavigationDestination( + icon: item.icon, + label: item.label, + ), + ) + .toList(), + ), ), ), ], diff --git a/lib/pages/setting/widgets/popup_item.dart b/lib/pages/setting/widgets/popup_item.dart index cd1da8af4..ea11038e1 100644 --- a/lib/pages/setting/widgets/popup_item.dart +++ b/lib/pages/setting/widgets/popup_item.dart @@ -42,7 +42,7 @@ class PopupListTile extends StatefulWidget { } class _PopupListTileState extends State> { - final _key = GlobalKey(); + final _key = PlatformUtils.isDesktop ? null : GlobalKey(); void _showButtonMenu(TapUpDetails details, T value) { final box = context.findRenderObject() as RenderBox; @@ -51,7 +51,7 @@ class _PopupListTileState extends State> { if (PlatformUtils.isDesktop) { dx = details.globalPosition.dx + 1; } else { - final box = _key.currentContext!.findRenderObject() as RenderBox; + final box = _key!.currentContext!.findRenderObject() as RenderBox; final offset = box.localToGlobal(box.size.topLeft(.zero)); dx = offset.dx; } @@ -60,7 +60,7 @@ class _PopupListTileState extends State> { position: RelativeRect.fromLTRB(dx, offset.dy + 5, dx, 0), items: widget.itemBuilder(context), initialValue: value, - requestFocus: false, + requestFocus: true, ).then((T? newValue) { if (!mounted) { return; @@ -82,7 +82,7 @@ class _PopupListTileState extends State> { Widget build(BuildContext context) { final theme = Theme.of(context); final (value, descStr) = widget.value(); - Widget title = Builder(key: _key, builder: (_) => widget.title); + Widget title = KeyedSubtree(key: _key, child: widget.title); Widget? subtitle; Widget? trailing; final desc = Text( diff --git a/lib/pages/video/widgets/header_control.dart b/lib/pages/video/widgets/header_control.dart index 41a0fd53d..59d3f14a1 100644 --- a/lib/pages/video/widgets/header_control.dart +++ b/lib/pages/video/widgets/header_control.dart @@ -1723,6 +1723,7 @@ class HeaderControlState extends State ((!horizontalScreen || plPlayerController.isDesktopPip) && !isPortrait))) { title = Padding( + key: titleKey, padding: isPortrait ? EdgeInsets.zero : const EdgeInsets.only(right: 10), @@ -1742,7 +1743,6 @@ class HeaderControlState extends State videoDetail.title!; } return MarqueeText( - key: titleKey, title, spacing: 30, velocity: 30, diff --git a/lib/plugin/pl_player/controller.dart b/lib/plugin/pl_player/controller.dart index e06a51985..474f10b90 100644 --- a/lib/plugin/pl_player/controller.dart +++ b/lib/plugin/pl_player/controller.dart @@ -76,7 +76,7 @@ class PlPlayerController { final playerStatus = PlPlayerStatus(PlayerStatus.playing); /// - final PlPlayerDataStatus dataStatus = PlPlayerDataStatus(); + final Rx dataStatus = Rx(DataStatus.none); // bool controlsEnabled = false; @@ -635,7 +635,7 @@ class PlPlayerController { // 初始化视频倍速 // _playbackSpeed.value = speed; // 初始化数据加载状态 - dataStatus.status.value = DataStatus.loading; + dataStatus.value = DataStatus.loading; // 初始化全屏方向 _isVertical = isVertical ?? false; _aid = aid; @@ -673,14 +673,14 @@ class PlPlayerController { updateSliderPositionSecond(); updateBufferedSecond(); // 数据加载完成 - dataStatus.status.value = DataStatus.loaded; + dataStatus.value = DataStatus.loaded; // listen the video player events startListeners(); await _initializePlayer(); onInit?.call(); } catch (err, stackTrace) { - dataStatus.status.value = DataStatus.error; + dataStatus.value = DataStatus.error; if (kDebugMode) { debugPrint(stackTrace.toString()); debugPrint('plPlayer err: $err'); @@ -984,9 +984,9 @@ class PlPlayerController { Future? autoEnterFullscreen() { if (enableAutoEnter) { return Future.delayed(const Duration(milliseconds: 500), () { - if (dataStatus.status.value != DataStatus.loaded) { + if (!dataStatus.loaded) { _stopListenerForEnterFullScreen(); - _dataListenerForEnterFullScreen = dataStatus.status.listen((status) { + _dataListenerForEnterFullScreen = dataStatus.listen((status) { if (status == DataStatus.loaded) { _stopListenerForEnterFullScreen(); triggerFullScreen(status: true); @@ -1386,7 +1386,7 @@ class PlPlayerController { if (buffered.value == Duration.zero) { attr = VideoFitType.contain; _stopListenerForVideoFit(); - _dataListenerForVideoFit = dataStatus.status.listen((status) { + _dataListenerForVideoFit = dataStatus.listen((status) { if (status == DataStatus.loaded) { _stopListenerForVideoFit(); final attr = VideoFitType.values[fitValue]; @@ -1731,7 +1731,7 @@ class PlPlayerController { // _controlsLock.close(); // playerStatus.close(); - // dataStatus.status.close(); + // dataStatus.close(); if (PlatformUtils.isDesktop && isAlwaysOnTop.value) { windowManager.setAlwaysOnTop(false); diff --git a/lib/plugin/pl_player/models/data_status.dart b/lib/plugin/pl_player/models/data_status.dart index a2cbb163b..f0d7d6c1a 100644 --- a/lib/plugin/pl_player/models/data_status.dart +++ b/lib/plugin/pl_player/models/data_status.dart @@ -2,11 +2,9 @@ import 'package:get/get.dart'; enum DataStatus { none, loading, loaded, error } -class PlPlayerDataStatus { - Rx status = Rx(DataStatus.none); - - bool get none => status.value == DataStatus.none; - bool get loading => status.value == DataStatus.loading; - bool get loaded => status.value == DataStatus.loaded; - bool get error => status.value == DataStatus.error; +extension PlPlayerDataStatus on Rx { + bool get none => value == DataStatus.none; + bool get loading => value == DataStatus.loading; + bool get loaded => value == DataStatus.loaded; + bool get error => value == DataStatus.error; } diff --git a/lib/plugin/pl_player/view.dart b/lib/plugin/pl_player/view.dart index 940fee7d4..f36e99aac 100644 --- a/lib/plugin/pl_player/view.dart +++ b/lib/plugin/pl_player/view.dart @@ -36,6 +36,7 @@ import 'package:PiliPlus/pages/video/widgets/header_control.dart'; import 'package:PiliPlus/plugin/pl_player/controller.dart'; import 'package:PiliPlus/plugin/pl_player/models/bottom_control_type.dart'; import 'package:PiliPlus/plugin/pl_player/models/bottom_progress_behavior.dart'; +import 'package:PiliPlus/plugin/pl_player/models/data_status.dart'; import 'package:PiliPlus/plugin/pl_player/models/double_tap_type.dart'; import 'package:PiliPlus/plugin/pl_player/models/fullscreen_mode.dart'; import 'package:PiliPlus/plugin/pl_player/models/gesture_type.dart'; diff --git a/lib/utils/id_utils.dart b/lib/utils/id_utils.dart index fb8f55d2d..20321f3e3 100644 --- a/lib/utils/id_utils.dart +++ b/lib/utils/id_utils.dart @@ -48,12 +48,11 @@ abstract final class IdUtils { /// bv转av static int bv2av(String bvid) { - final bvidArr = List.of(bvid.codeUnits); + final bvidArr = bvid.codeUnits.sublist(3); - swap(bvidArr, 3, 9); - swap(bvidArr, 4, 7); + swap(bvidArr, 0, 6); + swap(bvidArr, 1, 4); - bvidArr.removeRange(0, 3); final tmp = bvidArr.fold(0, (pre, char) => pre * BASE + invData[char]!); return (tmp & MASK_CODE) ^ XOR_CODE; }