* opt: dataStatus

* tweaks

* opt: ui

* update

Signed-off-by: dom <githubaccount56556@proton.me>

---------

Co-authored-by: dom <githubaccount56556@proton.me>
This commit is contained in:
My-Responsitories
2026-02-06 14:25:45 +08:00
committed by GitHub
parent 32386bf146
commit 7ab2cf973f
12 changed files with 85 additions and 73 deletions

View File

@@ -916,7 +916,12 @@ class ListTile extends StatelessWidget {
// Show basic cursor when ListTile isn't enabled or gesture callbacks are null.
final Set<WidgetState> mouseStates = <WidgetState>{
if (!enabled || (onTap == null && onLongPress == null))
if (!enabled ||
(onTap == null &&
onTapUp == null &&
onLongPress == null &&
onSecondaryTap == null &&
onSecondaryTapUp == null))
WidgetState.disabled,
};
final MouseCursor effectiveMouseCursor =

View File

@@ -25,9 +25,9 @@ class PlDanmakuController {
late final _isLogin = Accounts.main.isLogin;
final Map<int, List<DanmakuElem>> _dmSegMap = {};
final Map<int, List<DanmakuElem>> _dmSegMap = HashMap();
// 已请求的段落标记
late final Set<int> _requestedSeg = {};
late final Set<int> _requestedSeg = HashSet();
static const int segmentLength = 60 * 6 * 1000;

View File

@@ -58,8 +58,8 @@ class _LiveHeaderControlState extends State<LiveHeaderControl>
final liveController = widget.liveController;
Widget child;
child = Obx(
key: titleKey,
() => MarqueeText(
key: titleKey,
liveController.title.value,
spacing: 30,
velocity: 30,

View File

@@ -43,7 +43,13 @@ class _RankPageState extends State<RankPage>
);
}
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(

View File

@@ -33,7 +33,6 @@ sealed class SettingsModel {
class PopupModel<T extends EnumWithLabel> extends SettingsModel {
const PopupModel({
required this.title,
super.subtitle,
super.leading,
super.contentPadding,
super.titleStyle,

View File

@@ -42,6 +42,23 @@ class _ColorSelectPageState extends State<ColorSelectPage> {
final ctr = Get.put(_ColorSelectController());
FlexSchemeVariant _dynamicSchemeVariant = Pref.schemeVariant;
Future<void> _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<ColorSelectPage> {
),
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<ColorSelectPage> {
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<ColorSelectPage> {
),
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(),
),
),
),
],

View File

@@ -42,7 +42,7 @@ class PopupListTile<T> extends StatefulWidget {
}
class _PopupListTileState<T> extends State<PopupListTile<T>> {
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<T> extends State<PopupListTile<T>> {
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<T> extends State<PopupListTile<T>> {
position: RelativeRect.fromLTRB(dx, offset.dy + 5, dx, 0),
items: widget.itemBuilder(context),
initialValue: value,
requestFocus: false,
requestFocus: true,
).then<void>((T? newValue) {
if (!mounted) {
return;
@@ -82,7 +82,7 @@ class _PopupListTileState<T> extends State<PopupListTile<T>> {
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(

View File

@@ -1723,6 +1723,7 @@ class HeaderControlState extends State<HeaderControl>
((!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<HeaderControl>
videoDetail.title!;
}
return MarqueeText(
key: titleKey,
title,
spacing: 30,
velocity: 30,

View File

@@ -76,7 +76,7 @@ class PlPlayerController {
final playerStatus = PlPlayerStatus(PlayerStatus.playing);
///
final PlPlayerDataStatus dataStatus = PlPlayerDataStatus();
final Rx<DataStatus> 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<void>? 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);

View File

@@ -2,11 +2,9 @@ import 'package:get/get.dart';
enum DataStatus { none, loading, loaded, error }
class PlPlayerDataStatus {
Rx<DataStatus> 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<DataStatus> {
bool get none => value == DataStatus.none;
bool get loading => value == DataStatus.loading;
bool get loaded => value == DataStatus.loaded;
bool get error => value == DataStatus.error;
}

View File

@@ -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';

View File

@@ -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;
}