diff --git a/lib/common/widgets/image/custom_grid_view.dart b/lib/common/widgets/image/custom_grid_view.dart
index a7e9bc519..edc0aa3b2 100644
--- a/lib/common/widgets/image/custom_grid_view.dart
+++ b/lib/common/widgets/image/custom_grid_view.dart
@@ -15,6 +15,7 @@
* along with PiliPlus. If not, see .
*/
+import 'dart:io' show Platform;
import 'dart:math' show min;
import 'package:PiliPlus/common/constants.dart';
@@ -26,10 +27,13 @@ import 'package:PiliPlus/models/common/image_preview_type.dart';
import 'package:PiliPlus/utils/extension/context_ext.dart';
import 'package:PiliPlus/utils/extension/num_ext.dart';
import 'package:PiliPlus/utils/extension/size_ext.dart';
+import 'package:PiliPlus/utils/image_utils.dart';
import 'package:PiliPlus/utils/page_utils.dart';
+import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:PiliPlus/utils/storage_pref.dart';
import 'package:flutter/material.dart'
hide CustomMultiChildLayout, MultiChildLayoutDelegate;
+import 'package:flutter/services.dart' show HapticFeedback;
import 'package:get/get_core/src/get_main.dart';
import 'package:get/get_navigation/get_navigation.dart';
@@ -138,6 +142,56 @@ class CustomGridView extends StatelessWidget {
);
}
+ static bool enableImgMenu = Pref.enableImgMenu;
+
+ void _showMenu(BuildContext context, Offset offset, ImageModel item) {
+ HapticFeedback.mediumImpact();
+ showMenu(
+ context: context,
+ position: .fromLTRB(offset.dx, offset.dy, offset.dx, 0),
+ items: [
+ if (PlatformUtils.isMobile)
+ PopupMenuItem(
+ height: 42,
+ onTap: () => ImageUtils.onShareImg(item.url),
+ child: const Text('分享', style: TextStyle(fontSize: 14)),
+ ),
+ PopupMenuItem(
+ height: 42,
+ onTap: () => ImageUtils.downloadImg([item.url]),
+ child: const Text('保存图片', style: TextStyle(fontSize: 14)),
+ ),
+ if (PlatformUtils.isDesktop)
+ PopupMenuItem(
+ height: 42,
+ onTap: () => PageUtils.launchURL(item.url),
+ child: const Text('网页打开', style: TextStyle(fontSize: 14)),
+ )
+ else if (picArr.length > 1)
+ PopupMenuItem(
+ height: 42,
+ onTap: () =>
+ ImageUtils.downloadImg(picArr.map((item) => item.url).toList()),
+ child: const Text('保存全部', style: TextStyle(fontSize: 14)),
+ ),
+ if (item.isLivePhoto)
+ PopupMenuItem(
+ height: 42,
+ onTap: () => ImageUtils.downloadLivePhoto(
+ url: item.url,
+ liveUrl: item.liveUrl!,
+ width: item.width.toInt(),
+ height: item.height.toInt(),
+ ),
+ child: Text(
+ '保存${Platform.isIOS ? '实况' : '视频'}',
+ style: const TextStyle(fontSize: 14),
+ ),
+ ),
+ ],
+ );
+ }
+
@override
Widget build(BuildContext context) {
double imageWidth;
@@ -205,6 +259,14 @@ class CustomGridView extends StatelessWidget {
id: index,
child: GestureDetector(
onTap: () => onTap(context, index),
+ onSecondaryTapUp: enableImgMenu && PlatformUtils.isDesktop
+ ? (details) =>
+ _showMenu(context, details.globalPosition, item)
+ : null,
+ onLongPressStart: enableImgMenu && PlatformUtils.isMobile
+ ? (details) =>
+ _showMenu(context, details.globalPosition, item)
+ : null,
child: Hero(
tag: item.url,
child: Stack(
diff --git a/lib/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart b/lib/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart
index 66518bd87..f7b476427 100644
--- a/lib/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart
+++ b/lib/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart
@@ -11,6 +11,7 @@ import 'package:PiliPlus/utils/utils.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:easy_debounce/easy_throttle.dart';
import 'package:flutter/material.dart';
+import 'package:flutter/services.dart' show HapticFeedback;
import 'package:get/get.dart';
import 'package:media_kit/media_kit.dart';
import 'package:media_kit_video/media_kit_video.dart';
@@ -336,6 +337,9 @@ class _InteractiveviewerGalleryState extends State
imageUrl: _getActualUrl(item.url),
placeholderFadeInDuration: Duration.zero,
placeholder: (context, url) {
+ if (widget.quality == _quality) {
+ return const SizedBox.expand();
+ }
return CachedNetworkImage(
fadeInDuration: Duration.zero,
fadeOutDuration: Duration.zero,
@@ -408,6 +412,7 @@ class _InteractiveviewerGalleryState extends State
}
void onLongPress(SourceModel item) {
+ HapticFeedback.mediumImpact();
showDialog(
context: context,
builder: (context) {
diff --git a/lib/http/validate.dart b/lib/http/validate.dart
index bbc5f30c9..9f03a80c7 100644
--- a/lib/http/validate.dart
+++ b/lib/http/validate.dart
@@ -25,10 +25,10 @@ abstract final class ValidateHttp {
}
static Future gaiaVgateValidate({
- required challenge,
- required seccode,
- required token,
- required validate,
+ required dynamic challenge,
+ required dynamic seccode,
+ required dynamic token,
+ required dynamic validate,
}) async {
final res = await Request().post(
Api.gaiaVgateValidate,
diff --git a/lib/main.dart b/lib/main.dart
index 85a0acdc8..2a397584a 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -29,7 +29,6 @@ import 'package:PiliPlus/utils/theme_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:catcher_2/catcher_2.dart';
import 'package:dynamic_color/dynamic_color.dart';
-import 'package:flex_seed_scheme/flex_seed_scheme.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart' show PointerDeviceKind;
import 'package:flutter/material.dart';
@@ -263,7 +262,7 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
final dynamicColor = Pref.dynamicColor && _light != null && _dark != null;
late final brandColor = colorThemeTypes[Pref.customColor].color;
- late final variant = FlexSchemeVariant.values[Pref.schemeVariant];
+ late final variant = Pref.schemeVariant;
return GetMaterialApp(
title: Constants.appName,
theme: ThemeUtils.getThemeData(
@@ -395,7 +394,7 @@ class MyApp extends StatelessWidget {
if (kDebugMode) {
debugPrint('dynamic_color: Accent color detected.');
}
- final variant = FlexSchemeVariant.values[Pref.schemeVariant];
+ final variant = Pref.schemeVariant;
_light = accentColor.asColorSchemeSeed(variant, .light);
_dark = accentColor.asColorSchemeSeed(variant, .dark);
return true;
diff --git a/lib/models/dynamics/result.dart b/lib/models/dynamics/result.dart
index 1e8ed47f2..05a69529e 100644
--- a/lib/models/dynamics/result.dart
+++ b/lib/models/dynamics/result.dart
@@ -170,7 +170,7 @@ class ItemModulesModel {
ModuleBlocked? moduleBlocked;
ModuleFold? moduleFold;
- static bool showArgueMsg = Pref.showArgueMsg;
+ static bool showDynDispute = Pref.showDynDispute;
static bool showDynInteraction = Pref.showDynInteraction;
ItemModulesModel.fromJson(Map json) {
@@ -194,7 +194,7 @@ class ItemModulesModel {
? ModuleInteraction.fromJson(json['module_interaction'])
: null;
}
- if (showArgueMsg) {
+ if (showDynDispute) {
moduleDispute = json['module_dispute'] != null
? ModuleDispute.fromJson(json['module_dispute'])
: null;
diff --git a/lib/models_new/live/live_danmaku/danmaku_msg.dart b/lib/models_new/live/live_danmaku/danmaku_msg.dart
index 4e7a8d764..b0fe0ae17 100644
--- a/lib/models_new/live/live_danmaku/danmaku_msg.dart
+++ b/lib/models_new/live/live_danmaku/danmaku_msg.dart
@@ -57,4 +57,14 @@ class DanmakuMsg {
reply: reply,
);
}
+
+ Map toJson() => {
+ 'name': name,
+ 'uid': uid,
+ 'text': text,
+ 'emots': emots,
+ 'uemote': uemote?.toJson(),
+ 'extra': extra.toJson(),
+ 'reply': reply?.toJson(),
+ };
}
diff --git a/lib/models_new/live/live_danmaku/live_emote.dart b/lib/models_new/live/live_danmaku/live_emote.dart
index 583268437..3c80dad17 100644
--- a/lib/models_new/live/live_danmaku/live_emote.dart
+++ b/lib/models_new/live/live_danmaku/live_emote.dart
@@ -11,6 +11,13 @@ class BaseEmote {
width = (json['width'] as num).toDouble();
height = (json['height'] as num?)?.toDouble();
}
+
+ Map toJson() => {
+ 'url': url,
+ 'emoticon_unique': emoticonUnique,
+ 'width': width,
+ 'height': height,
+ };
}
// class Emote extends BaseEmote {
diff --git a/lib/models_new/live/live_superchat/item.dart b/lib/models_new/live/live_superchat/item.dart
index 8ce5895e2..c0b72d613 100644
--- a/lib/models_new/live/live_superchat/item.dart
+++ b/lib/models_new/live/live_superchat/item.dart
@@ -91,4 +91,19 @@ class SuperChatItem {
userInfo: userInfo ?? this.userInfo,
);
}
+
+ Map toJson() => {
+ 'id': id,
+ 'uid': uid,
+ 'price': price,
+ 'background_color': backgroundColor,
+ 'background_bottom_color': backgroundBottomColor,
+ 'background_price_color': backgroundPriceColor,
+ 'message_font_color': messageFontColor,
+ 'end_time': endTime,
+ 'message': message,
+ 'token': token,
+ 'ts': ts,
+ 'user_info': userInfo.toJson(),
+ };
}
diff --git a/lib/models_new/live/live_superchat/user_info.dart b/lib/models_new/live/live_superchat/user_info.dart
index 19089f6e4..13ce96f17 100644
--- a/lib/models_new/live/live_superchat/user_info.dart
+++ b/lib/models_new/live/live_superchat/user_info.dart
@@ -14,4 +14,10 @@ class UserInfo {
uname: json['uname'],
nameColor: json['name_color'] ?? '#666666',
);
+
+ Map toJson() => {
+ 'face': face,
+ 'uname': uname,
+ 'name_color': nameColor,
+ };
}
diff --git a/lib/pages/common/publish/common_rich_text_pub_page.dart b/lib/pages/common/publish/common_rich_text_pub_page.dart
index adc4c4245..2e0176785 100644
--- a/lib/pages/common/publish/common_rich_text_pub_page.dart
+++ b/lib/pages/common/publish/common_rich_text_pub_page.dart
@@ -110,7 +110,10 @@ abstract class CommonRichTextPubPageState
);
controller.restoreChatPanel();
},
- onLongPress: onClear,
+ onLongPress: () {
+ Feedback.forLongPress(context);
+ onClear();
+ },
onSecondaryTap: PlatformUtils.isMobile ? null : onClear,
child: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(4)),
diff --git a/lib/pages/common/reply_controller.dart b/lib/pages/common/reply_controller.dart
index d99e953d6..3875c906b 100644
--- a/lib/pages/common/reply_controller.dart
+++ b/lib/pages/common/reply_controller.dart
@@ -45,9 +45,10 @@ abstract class ReplyController extends CommonListController {
@override
void onInit() {
super.onInit();
- int replySortType = Pref.replySortType;
- sortType = ReplySortType.values[replySortType].obs;
- mode = (replySortType == 0 ? Mode.MAIN_LIST_TIME : Mode.MAIN_LIST_HOT).obs;
+ final cacheSortType = Pref.replySortType;
+ sortType = cacheSortType.obs;
+ mode =
+ (cacheSortType == .time ? Mode.MAIN_LIST_TIME : Mode.MAIN_LIST_HOT).obs;
}
@override
diff --git a/lib/pages/danmaku/danmaku_model.dart b/lib/pages/danmaku/danmaku_model.dart
index 72009e234..0177bbc1c 100644
--- a/lib/pages/danmaku/danmaku_model.dart
+++ b/lib/pages/danmaku/danmaku_model.dart
@@ -41,4 +41,12 @@ class LiveDanmaku extends DanmakuExtra {
required this.ts,
required this.ct,
});
+
+ Map toJson() => {
+ 'id': id,
+ 'mid': mid,
+ 'dm_type': dmType,
+ 'ts': ts,
+ 'ct': ct,
+ };
}
diff --git a/lib/pages/dynamics/controller.dart b/lib/pages/dynamics/controller.dart
index 7eef83034..4301e8cab 100644
--- a/lib/pages/dynamics/controller.dart
+++ b/lib/pages/dynamics/controller.dart
@@ -58,7 +58,7 @@ class DynamicsController extends GetxController
tabController = TabController(
length: DynamicsTabType.values.length,
vsync: this,
- initialIndex: Pref.defaultDynamicType,
+ initialIndex: Pref.defaultDynamicTypeIndex,
);
queryFollowUp();
}
diff --git a/lib/pages/dynamics/widgets/dynamic_panel.dart b/lib/pages/dynamics/widgets/dynamic_panel.dart
index eab217f96..ee1189b37 100644
--- a/lib/pages/dynamics/widgets/dynamic_panel.dart
+++ b/lib/pages/dynamics/widgets/dynamic_panel.dart
@@ -249,7 +249,7 @@ class DynamicPanel extends StatelessWidget {
Widget _buildDispute(ThemeData theme, ModuleDispute moduleDispute) {
final child = Container(
width: .infinity,
- margin: const .fromLTRB(12, 0, 12, 6),
+ margin: const .fromLTRB(12, 2, 12, 6),
padding: const .symmetric(horizontal: 8, vertical: 6),
decoration: BoxDecoration(
color: theme.colorScheme.secondaryContainer.withValues(
diff --git a/lib/pages/live_room/superchat/superchat_card.dart b/lib/pages/live_room/superchat/superchat_card.dart
index 70a83433c..feec5e892 100644
--- a/lib/pages/live_room/superchat/superchat_card.dart
+++ b/lib/pages/live_room/superchat/superchat_card.dart
@@ -103,6 +103,14 @@ class _SuperChatCardState extends State {
style: const TextStyle(fontSize: 13),
),
),
+ PopupMenuItem(
+ height: 38,
+ onTap: () => Utils.copyText(Utils.jsonEncoder.convert(item.toJson())),
+ child: const Text(
+ '复制 SC 信息',
+ style: TextStyle(fontSize: 13),
+ ),
+ ),
PopupMenuItem(
height: 38,
onTap: widget.onReport,
diff --git a/lib/pages/live_room/widgets/chat_panel.dart b/lib/pages/live_room/widgets/chat_panel.dart
index 497007606..179270e70 100644
--- a/lib/pages/live_room/widgets/chat_panel.dart
+++ b/lib/pages/live_room/widgets/chat_panel.dart
@@ -9,6 +9,7 @@ import 'package:PiliPlus/pages/live_room/superchat/superchat_card.dart';
import 'package:PiliPlus/pages/video/widgets/header_control.dart';
import 'package:PiliPlus/utils/accounts.dart';
import 'package:PiliPlus/utils/extension/theme_ext.dart';
+import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/foundation.dart' show kDebugMode;
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
@@ -314,6 +315,14 @@ class LiveRoomChatPanel extends StatelessWidget {
),
),
const CustomPopupMenuDivider(height: 1),
+ PopupMenuItem(
+ height: 38,
+ onTap: () => Utils.copyText(Utils.jsonEncoder.convert(item.toJson())),
+ child: const Text(
+ '复制弹幕信息',
+ style: TextStyle(fontSize: 13),
+ ),
+ ),
PopupMenuItem(
height: 38,
onTap: () => Get.toNamed('/member?mid=${item.uid}'),
diff --git a/lib/pages/main/controller.dart b/lib/pages/main/controller.dart
index 52b2b0802..e39c7ccec 100644
--- a/lib/pages/main/controller.dart
+++ b/lib/pages/main/controller.dart
@@ -1,5 +1,4 @@
import 'dart:async';
-import 'dart:math' show max;
import 'package:PiliPlus/common/widgets/view_safe_area.dart';
import 'package:PiliPlus/grpc/dyn.dart';
@@ -85,7 +84,7 @@ class MainController extends GetxController
if (navigationBars.length > 1 && Pref.hideTabBar) {
bottomBar = true.obs;
}
- dynamicBadgeMode = DynamicBadgeMode.values[Pref.dynamicBadgeMode];
+ dynamicBadgeMode = Pref.dynamicBadgeMode;
hasDyn = navigationBars.contains(NavigationBarType.dynamics);
if (dynamicBadgeMode != DynamicBadgeMode.hidden) {
@@ -211,7 +210,6 @@ class MainController extends GetxController
void setNavBarConfig() {
List? navBarSort =
(GStorage.setting.get(SettingBoxKey.navBarSort) as List?)?.fromCast();
- int defaultHomePage = Pref.defaultHomePage;
late final List navigationBars;
if (navBarSort == null || navBarSort.isEmpty) {
navigationBars = NavigationBarType.values;
@@ -221,10 +219,7 @@ class MainController extends GetxController
.toList();
}
this.navigationBars = navigationBars;
- selectedIndex.value = max(
- 0,
- navigationBars.indexWhere((e) => e.index == defaultHomePage),
- );
+ selectedIndex.value = Pref.defaultHomePageIndex;
}
void checkDefaultSearch([bool shouldCheck = false]) {
diff --git a/lib/pages/setting/models/extra_settings.dart b/lib/pages/setting/models/extra_settings.dart
index 2b33a24f4..a91f32632 100644
--- a/lib/pages/setting/models/extra_settings.dart
+++ b/lib/pages/setting/models/extra_settings.dart
@@ -405,12 +405,18 @@ List get extraSettings => [
);
},
),
- SwitchModel(
+ const SwitchModel(
title: '显示视频警告/争议信息',
- leading: const Icon(Icons.warning_amber_rounded),
+ leading: Icon(Icons.warning_amber_rounded),
setKey: SettingBoxKey.showArgueMsg,
defaultVal: true,
- onChanged: (val) => ItemModulesModel.showArgueMsg = val,
+ ),
+ SwitchModel(
+ title: '显示动态警告/争议信息',
+ leading: const Icon(Icons.warning_amber_rounded),
+ setKey: SettingBoxKey.showDynDispute,
+ defaultVal: false,
+ onChanged: (val) => ItemModulesModel.showDynDispute = val,
),
const SwitchModel(
title: '分P/合集:倒序播放从首集开始播放',
@@ -746,6 +752,13 @@ List get extraSettings => [
defaultVal: false,
onChanged: (value) => ImageUtils.silentDownImg = value,
),
+ SwitchModel(
+ title: '长按/右键显示图片菜单',
+ leading: const Icon(Icons.menu),
+ setKey: SettingBoxKey.enableImgMenu,
+ defaultVal: false,
+ onChanged: (value) => CustomGridView.enableImgMenu = value,
+ ),
SwitchModel(
setKey: SettingBoxKey.feedBackEnable,
onChanged: (value) {
@@ -929,23 +942,20 @@ List get extraSettings => [
NormalModel(
title: '评论展示',
leading: const Icon(Icons.whatshot_outlined),
- getSubtitle: () =>
- '当前优先展示「${ReplySortType.values[Pref.replySortType].title}」',
+ getSubtitle: () => '当前优先展示「${Pref.replySortType.title}」',
onTap: (context, setState) async {
- final result = await showDialog(
+ final result = await showDialog(
context: context,
builder: (context) {
- return SelectDialog(
+ return SelectDialog(
title: '评论展示',
value: Pref.replySortType,
- values: ReplySortType.values
- .map((e) => (e.index, e.title))
- .toList(),
+ values: ReplySortType.values.map((e) => (e, e.title)).toList(),
);
},
);
if (result != null) {
- await GStorage.setting.put(SettingBoxKey.replySortType, result);
+ await GStorage.setting.put(SettingBoxKey.replySortType, result.index);
setState();
}
},
@@ -953,24 +963,26 @@ List get extraSettings => [
NormalModel(
title: '动态展示',
leading: const Icon(Icons.dynamic_feed_rounded),
- getSubtitle: () =>
- '当前优先展示「${DynamicsTabType.values[Pref.defaultDynamicType].label}」',
+ getSubtitle: () => '当前优先展示「${Pref.defaultDynamicType.label}」',
onTap: (context, setState) async {
- final result = await showDialog(
+ final result = await showDialog(
context: context,
builder: (context) {
- return SelectDialog(
+ return SelectDialog(
title: '动态展示',
value: Pref.defaultDynamicType,
values: DynamicsTabType.values
.take(4)
- .map((e) => (e.index, e.label))
+ .map((e) => (e, e.label))
.toList(),
);
},
);
if (result != null) {
- await GStorage.setting.put(SettingBoxKey.defaultDynamicType, result);
+ await GStorage.setting.put(
+ SettingBoxKey.defaultDynamicType,
+ result.index,
+ );
setState();
}
},
diff --git a/lib/pages/setting/models/play_settings.dart b/lib/pages/setting/models/play_settings.dart
index 57d427acc..18a28999e 100644
--- a/lib/pages/setting/models/play_settings.dart
+++ b/lib/pages/setting/models/play_settings.dart
@@ -119,23 +119,23 @@ List get playSettings => [
NormalModel(
title: '自动启用字幕',
leading: const Icon(Icons.closed_caption_outlined),
- getSubtitle: () =>
- '当前选择偏好:${SubtitlePrefType.values[Pref.subtitlePreferenceV2].desc}',
+ getSubtitle: () => '当前选择偏好:${Pref.subtitlePreferenceV2.desc}',
onTap: (context, setState) async {
- final result = await showDialog(
+ final result = await showDialog(
context: context,
builder: (context) {
- return SelectDialog(
+ return SelectDialog(
title: '字幕选择偏好',
value: Pref.subtitlePreferenceV2,
- values: SubtitlePrefType.values
- .map((e) => (e.index, e.desc))
- .toList(),
+ values: SubtitlePrefType.values.map((e) => (e, e.desc)).toList(),
);
},
);
if (result != null) {
- await GStorage.setting.put(SettingBoxKey.subtitlePreferenceV2, result);
+ await GStorage.setting.put(
+ SettingBoxKey.subtitlePreferenceV2,
+ result.index,
+ );
setState();
}
},
@@ -266,23 +266,20 @@ List get playSettings => [
NormalModel(
title: '默认全屏方向',
leading: const Icon(Icons.open_with_outlined),
- getSubtitle: () =>
- '当前全屏方向:${FullScreenMode.values[Pref.fullScreenMode].desc}',
+ getSubtitle: () => '当前全屏方向:${Pref.fullScreenMode.desc}',
onTap: (context, setState) async {
- final result = await showDialog(
+ final result = await showDialog(
context: context,
builder: (context) {
- return SelectDialog(
+ return SelectDialog(
title: '默认全屏方向',
value: Pref.fullScreenMode,
- values: FullScreenMode.values
- .map((e) => (e.index, e.desc))
- .toList(),
+ values: FullScreenMode.values.map((e) => (e, e.desc)).toList(),
);
},
);
if (result != null) {
- await GStorage.setting.put(SettingBoxKey.fullScreenMode, result);
+ await GStorage.setting.put(SettingBoxKey.fullScreenMode, result.index);
setState();
}
},
@@ -290,23 +287,23 @@ List get playSettings => [
NormalModel(
title: '底部进度条展示',
leading: const Icon(Icons.border_bottom_outlined),
- getSubtitle: () =>
- '当前展示方式:${BtmProgressBehavior.values[Pref.btmProgressBehavior].desc}',
+ getSubtitle: () => '当前展示方式:${Pref.btmProgressBehavior.desc}',
onTap: (context, setState) async {
- final result = await showDialog(
+ final result = await showDialog(
context: context,
builder: (context) {
- return SelectDialog(
+ return SelectDialog(
title: '底部进度条展示',
value: Pref.btmProgressBehavior,
- values: BtmProgressBehavior.values
- .map((e) => (e.index, e.desc))
- .toList(),
+ values: BtmProgressBehavior.values.map((e) => (e, e.desc)).toList(),
);
},
);
if (result != null) {
- await GStorage.setting.put(SettingBoxKey.btmProgressBehavior, result);
+ await GStorage.setting.put(
+ SettingBoxKey.btmProgressBehavior,
+ result.index,
+ );
setState();
}
},
diff --git a/lib/pages/setting/models/recommend_settings.dart b/lib/pages/setting/models/recommend_settings.dart
index d60dd7089..db70d0220 100644
--- a/lib/pages/setting/models/recommend_settings.dart
+++ b/lib/pages/setting/models/recommend_settings.dart
@@ -21,7 +21,7 @@ List get recommendSettings => [
subtitle: '下拉刷新时保留上次内容',
leading: const Icon(Icons.refresh),
setKey: SettingBoxKey.enableSaveLastData,
- defaultVal: false,
+ defaultVal: true,
onChanged: (value) {
try {
Get.find()
diff --git a/lib/pages/setting/models/style_settings.dart b/lib/pages/setting/models/style_settings.dart
index 1c4b27e7b..1245f96fa 100644
--- a/lib/pages/setting/models/style_settings.dart
+++ b/lib/pages/setting/models/style_settings.dart
@@ -33,7 +33,6 @@ import 'package:PiliPlus/utils/storage.dart';
import 'package:PiliPlus/utils/storage_key.dart';
import 'package:PiliPlus/utils/storage_pref.dart';
import 'package:auto_orientation/auto_orientation.dart';
-import 'package:flex_seed_scheme/flex_seed_scheme.dart';
import 'package:flutter/material.dart' hide StatefulBuilder;
import 'package:flutter/services.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
@@ -593,10 +592,7 @@ List get styleSettings => [
dimension: 32,
child: ColorPalette(
colorScheme: colorThemeTypes[Pref.customColor].color
- .asColorSchemeSeed(
- FlexSchemeVariant.values[Pref.schemeVariant],
- Get.theme.brightness,
- ),
+ .asColorSchemeSeed(Pref.schemeVariant, Get.theme.brightness),
selected: false,
showBgColor: false,
),
@@ -604,28 +600,25 @@ List get styleSettings => [
),
NormalModel(
onTap: (context, setState) async {
- final result = await showDialog(
+ final result = await showDialog(
context: context,
builder: (context) {
- return SelectDialog(
+ return SelectDialog(
title: '首页启动页',
value: Pref.defaultHomePage,
- values: NavigationBarType.values
- .map((e) => (e.index, e.label))
- .toList(),
+ values: NavigationBarType.values.map((e) => (e, e.label)).toList(),
);
},
);
if (result != null) {
- await GStorage.setting.put(SettingBoxKey.defaultHomePage, result);
+ await GStorage.setting.put(SettingBoxKey.defaultHomePage, result.index);
SmartDialog.showToast('设置成功,重启生效');
setState();
}
},
leading: const Icon(Icons.home_outlined),
title: '默认启动页',
- getSubtitle: () =>
- '当前启动页:${NavigationBarType.values.firstWhere((e) => e.index == Pref.defaultHomePage).label}',
+ getSubtitle: () => '当前启动页:${Pref.defaultHomePage.label}',
),
NormalModel(
title: '滑动动画弹簧参数',
diff --git a/lib/pages/setting/pages/color_select.dart b/lib/pages/setting/pages/color_select.dart
index 31e43f085..5ef1f07ab 100644
--- a/lib/pages/setting/pages/color_select.dart
+++ b/lib/pages/setting/pages/color_select.dart
@@ -39,8 +39,7 @@ class Item {
class _ColorSelectPageState extends State {
final ctr = Get.put(ColorSelectController());
- FlexSchemeVariant _dynamicSchemeVariant =
- FlexSchemeVariant.values[Pref.schemeVariant];
+ FlexSchemeVariant _dynamicSchemeVariant = Pref.schemeVariant;
@override
Widget build(BuildContext context) {
diff --git a/lib/pages/video/controller.dart b/lib/pages/video/controller.dart
index 0b35370ff..69dd355f9 100644
--- a/lib/pages/video/controller.dart
+++ b/lib/pages/video/controller.dart
@@ -1592,8 +1592,7 @@ class VideoDetailController extends GetxController
if (response.subtitle?.subtitles?.isNotEmpty == true) {
subtitles.value = response.subtitle!.subtitles!;
- final idx = switch (SubtitlePrefType.values[Pref
- .subtitlePreferenceV2]) {
+ final idx = switch (Pref.subtitlePreferenceV2) {
SubtitlePrefType.off => 0,
SubtitlePrefType.on => 1,
SubtitlePrefType.withoutAi =>
diff --git a/lib/pages/video/introduction/ugc/view.dart b/lib/pages/video/introduction/ugc/view.dart
index 19a3fb513..773756c3b 100644
--- a/lib/pages/video/introduction/ugc/view.dart
+++ b/lib/pages/video/introduction/ugc/view.dart
@@ -773,6 +773,9 @@ class _UgcIntroPanelState extends State {
int? ownerMid,
Staff item,
) {
+ void onTap() => Get.toNamed(
+ '/member?mid=${item.mid}&from_view_aid=${videoDetailCtr.aid}',
+ );
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
@@ -781,11 +784,13 @@ class _UgcIntroPanelState extends State {
introController.horizontalMemberPage) {
widget.onShowMemberPage(ownerMid);
} else {
- Get.toNamed(
- '/member?mid=${item.mid}&from_view_aid=${videoDetailCtr.aid}',
- );
+ onTap();
}
},
+ onSecondaryTap:
+ PlatformUtils.isDesktop && introController.horizontalMemberPage
+ ? onTap
+ : null,
child: Row(
children: [
Stack(
@@ -893,6 +898,12 @@ class _UgcIntroPanelState extends State {
) => GestureDetector(
onTap: onPushMember,
behavior: HitTestBehavior.opaque,
+ onSecondaryTap:
+ PlatformUtils.isDesktop && introController.horizontalMemberPage
+ ? () => Get.toNamed(
+ '/member?mid=${introController.userStat.value.card?.mid}&from_view_aid=${videoDetailCtr.aid}',
+ )
+ : null,
child: Obx(
() {
final userStat = introController.userStat.value;
diff --git a/lib/pages/video/reply/widgets/reply_item_grpc.dart b/lib/pages/video/reply/widgets/reply_item_grpc.dart
index bd5eb6e27..8cdd098ec 100644
--- a/lib/pages/video/reply/widgets/reply_item_grpc.dart
+++ b/lib/pages/video/reply/widgets/reply_item_grpc.dart
@@ -99,14 +99,8 @@ class ReplyItemGrpc extends StatelessWidget {
return Material(
type: MaterialType.transparency,
child: InkWell(
- onTap: () {
- feedBack();
- replyReply?.call(replyItem, null);
- },
- onLongPress: () {
- feedBack();
- showMore();
- },
+ onTap: () => replyReply?.call(replyItem, null),
+ onLongPress: showMore,
onSecondaryTap: isMobile ? null : showMore,
child: _buildContent(context, theme),
),
@@ -468,10 +462,7 @@ class ReplyItemGrpc extends StatelessWidget {
return InkWell(
onTap: () =>
replyReply?.call(replyItem, childReply.id.toInt()),
- onLongPress: () {
- feedBack();
- showMore();
- },
+ onLongPress: showMore,
onSecondaryTap: PlatformUtils.isMobile ? null : showMore,
child: Padding(
padding: padding,
diff --git a/lib/pages/whisper_detail/widget/chat_item.dart b/lib/pages/whisper_detail/widget/chat_item.dart
index dc5012bdd..f8c72957f 100644
--- a/lib/pages/whisper_detail/widget/chat_item.dart
+++ b/lib/pages/whisper_detail/widget/chat_item.dart
@@ -587,7 +587,7 @@ class ChatItem extends StatelessWidget {
);
}
- Widget msgTypePic_2(content) {
+ Widget msgTypePic_2(Map content) {
final url = content['url'];
return GestureDetector(
onTap: () => PageUtils.imageView(imgList: [SourceModel(url: url)]),
diff --git a/lib/plugin/pl_player/controller.dart b/lib/plugin/pl_player/controller.dart
index ddfdc66cc..263167f4d 100644
--- a/lib/plugin/pl_player/controller.dart
+++ b/lib/plugin/pl_player/controller.dart
@@ -19,7 +19,6 @@ import 'package:PiliPlus/models/video/play/url.dart';
import 'package:PiliPlus/models_new/video/video_shot/data.dart';
import 'package:PiliPlus/pages/danmaku/danmaku_model.dart';
import 'package:PiliPlus/pages/mine/controller.dart';
-import 'package:PiliPlus/plugin/pl_player/models/bottom_progress_behavior.dart';
import 'package:PiliPlus/plugin/pl_player/models/data_source.dart';
import 'package:PiliPlus/plugin/pl_player/models/data_status.dart';
import 'package:PiliPlus/plugin/pl_player/models/double_tap_type.dart';
@@ -402,8 +401,7 @@ class PlPlayerController {
late final bool enableHA = Pref.enableHA;
late final String hwdec = Pref.hardwareDecoding;
- late final progressType =
- BtmProgressBehavior.values[Pref.btmProgressBehavior];
+ late final progressType = Pref.btmProgressBehavior;
late final enableQuickDouble = Pref.enableQuickDouble;
late final fullScreenGestureReverse = Pref.fullScreenGestureReverse;
@@ -416,7 +414,7 @@ class PlPlayerController {
isRelative ? duration.value.inMilliseconds * offset : offset;
// 播放顺序相关
- late PlayRepeat playRepeat = PlayRepeat.values[Pref.playRepeat];
+ late PlayRepeat playRepeat = Pref.playRepeat;
TextStyle get subTitleStyle => TextStyle(
height: 1.5,
@@ -1519,7 +1517,7 @@ class PlPlayerController {
}
late bool isManualFS = true;
- late final FullScreenMode mode = FullScreenMode.values[Pref.fullScreenMode];
+ late final FullScreenMode mode = Pref.fullScreenMode;
late final horizontalScreen = Pref.horizontalScreen;
// 全屏
diff --git a/lib/plugin/pl_player/view.dart b/lib/plugin/pl_player/view.dart
index 59f597252..c3b8214f5 100644
--- a/lib/plugin/pl_player/view.dart
+++ b/lib/plugin/pl_player/view.dart
@@ -1146,11 +1146,7 @@ class _PLVideoPlayerState extends State
}
void onDoubleTapDownMobile(TapDownDetails details) {
- if (plPlayerController.controlsLock.value) {
- return;
- }
- if (plPlayerController.isLive) {
- plPlayerController.doubleTapFuc(DoubleTapType.center);
+ if (plPlayerController.isLive || plPlayerController.controlsLock.value) {
return;
}
final double tapPosition = details.localPosition.dx;
@@ -1167,7 +1163,7 @@ class _PLVideoPlayerState extends State
}
void onTapDesktop() {
- if (plPlayerController.controlsLock.value) {
+ if (plPlayerController.isLive || plPlayerController.controlsLock.value) {
return;
}
plPlayerController.onDoubleTapCenter();
diff --git a/lib/utils/storage_key.dart b/lib/utils/storage_key.dart
index 07580d003..b42f2577b 100644
--- a/lib/utils/storage_key.dart
+++ b/lib/utils/storage_key.dart
@@ -144,7 +144,9 @@ abstract final class SettingBoxKey {
enableTapDm = 'enableTapDm',
setSystemBrightness = 'setSystemBrightness',
downloadPath = 'downloadPath',
- followOrderType = 'followOrderType';
+ followOrderType = 'followOrderType',
+ enableImgMenu = 'enableImgMenu',
+ showDynDispute = 'showDynDispute';
static const String minimizeOnExit = 'minimizeOnExit',
windowSize = 'windowSize',
diff --git a/lib/utils/storage_pref.dart b/lib/utils/storage_pref.dart
index 21c0882a1..e02c3c8e8 100644
--- a/lib/utils/storage_pref.dart
+++ b/lib/utils/storage_pref.dart
@@ -4,10 +4,13 @@ import 'dart:math' show pow, sqrt;
import 'package:PiliPlus/common/widgets/pair.dart';
import 'package:PiliPlus/http/constants.dart';
import 'package:PiliPlus/models/common/dynamic/dynamic_badge_mode.dart';
+import 'package:PiliPlus/models/common/dynamic/dynamics_type.dart';
import 'package:PiliPlus/models/common/dynamic/up_panel_position.dart';
import 'package:PiliPlus/models/common/follow_order_type.dart';
import 'package:PiliPlus/models/common/member/tab_type.dart';
import 'package:PiliPlus/models/common/msg/msg_unread_type.dart';
+import 'package:PiliPlus/models/common/nav_bar_config.dart';
+import 'package:PiliPlus/models/common/reply/reply_sort_type.dart';
import 'package:PiliPlus/models/common/sponsor_block/segment_type.dart';
import 'package:PiliPlus/models/common/sponsor_block/skip_type.dart';
import 'package:PiliPlus/models/common/super_chat_type.dart';
@@ -32,6 +35,7 @@ import 'package:PiliPlus/utils/login_utils.dart';
import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:PiliPlus/utils/storage.dart';
import 'package:PiliPlus/utils/storage_key.dart';
+import 'package:flex_seed_scheme/flex_seed_scheme.dart' show FlexSchemeVariant;
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hive/hive.dart';
@@ -55,25 +59,23 @@ abstract final class Pref {
static Set get blackMids =>
_localCache.get(LocalCacheKey.blackMids, defaultValue: {});
- static set blackMids(Set blackMidsSet) {
- _localCache.put(LocalCacheKey.blackMids, blackMidsSet);
- }
+ static set blackMids(Set blackMidsSet) =>
+ _localCache.put(LocalCacheKey.blackMids, blackMidsSet);
static RuleFilter get danmakuFilterRule => _localCache.get(
LocalCacheKey.danmakuFilterRules,
defaultValue: RuleFilter.empty(),
);
- static void setBlackMid(int mid) {
- _localCache.put(LocalCacheKey.blackMids, GlobalData().blackMids..add(mid));
- }
+ static void setBlackMid(int mid) => _localCache.put(
+ LocalCacheKey.blackMids,
+ GlobalData().blackMids..add(mid),
+ );
- static void removeBlackMid(int mid) {
- _localCache.put(
- LocalCacheKey.blackMids,
- GlobalData().blackMids..remove(mid),
- );
- }
+ static void removeBlackMid(int mid) => _localCache.put(
+ LocalCacheKey.blackMids,
+ GlobalData().blackMids..remove(mid),
+ );
static MemberTabType get memberTab =>
MemberTabType.values[_setting.get(
@@ -86,13 +88,13 @@ abstract final class Pref {
defaultValue: ThemeType.system.index,
);
- static ThemeMode get themeMode {
- return switch (_themeTypeInt) {
- 0 => ThemeMode.light,
- 1 => ThemeMode.dark,
- _ => ThemeMode.system,
- };
- }
+ static ThemeType get themeType => ThemeType.values[_themeTypeInt];
+
+ static ThemeMode get themeMode => switch (_themeTypeInt) {
+ 0 => ThemeMode.light,
+ 1 => ThemeMode.dark,
+ _ => ThemeMode.system,
+ };
static List get springDescription => List.from(
_setting.get(SettingBoxKey.springDescription) ??
@@ -143,8 +145,6 @@ abstract final class Pref {
static int get picQuality =>
_setting.get(SettingBoxKey.defaultPicQa, defaultValue: 10);
- static ThemeType get themeType => ThemeType.values[_themeTypeInt];
-
static DynamicBadgeMode get dynamicBadgeType =>
DynamicBadgeMode.values[_setting.get(
SettingBoxKey.dynamicBadgeMode,
@@ -163,8 +163,13 @@ abstract final class Pref {
.toSet() ??
MsgUnReadType.values.toSet();
- static int get defaultHomePage =>
- _setting.get(SettingBoxKey.defaultHomePage, defaultValue: 0);
+ static NavigationBarType get defaultHomePage =>
+ NavigationBarType.values[defaultHomePageIndex];
+
+ static int get defaultHomePageIndex => _setting.get(
+ SettingBoxKey.defaultHomePage,
+ defaultValue: NavigationBarType.home.index,
+ );
static int get previewQ =>
_setting.get(SettingBoxKey.previewQuality, defaultValue: 100);
@@ -181,20 +186,23 @@ abstract final class Pref {
defaultValue: UpPanelPosition.leftFixed.index,
)];
- static int get fullScreenMode => _setting.get(
- SettingBoxKey.fullScreenMode,
- defaultValue: FullScreenMode.auto.index,
- );
+ static FullScreenMode get fullScreenMode =>
+ FullScreenMode.values[_setting.get(
+ SettingBoxKey.fullScreenMode,
+ defaultValue: FullScreenMode.auto.index,
+ )];
- static int get btmProgressBehavior => _setting.get(
- SettingBoxKey.btmProgressBehavior,
- defaultValue: BtmProgressBehavior.alwaysShow.index,
- );
+ static BtmProgressBehavior get btmProgressBehavior =>
+ BtmProgressBehavior.values[_setting.get(
+ SettingBoxKey.btmProgressBehavior,
+ defaultValue: BtmProgressBehavior.alwaysShow.index,
+ )];
- static int get subtitlePreferenceV2 => _setting.get(
- SettingBoxKey.subtitlePreferenceV2,
- defaultValue: SubtitlePrefType.off.index,
- );
+ static SubtitlePrefType get subtitlePreferenceV2 =>
+ SubtitlePrefType.values[_setting.get(
+ SettingBoxKey.subtitlePreferenceV2,
+ defaultValue: SubtitlePrefType.off.index,
+ )];
static bool get useRelativeSlide =>
_setting.get(SettingBoxKey.useRelativeSlide, defaultValue: false);
@@ -267,8 +275,13 @@ abstract final class Pref {
static String get systemProxyPort =>
_setting.get(SettingBoxKey.systemProxyPort, defaultValue: '');
- static int get defaultDynamicType =>
- _setting.get(SettingBoxKey.defaultDynamicType, defaultValue: 0);
+ static DynamicsTabType get defaultDynamicType =>
+ DynamicsTabType.values[defaultDynamicTypeIndex];
+
+ static int get defaultDynamicTypeIndex => _setting.get(
+ SettingBoxKey.defaultDynamicType,
+ defaultValue: DynamicsTabType.all.index,
+ );
static bool get showDynInteraction =>
_setting.get(SettingBoxKey.showDynInteraction, defaultValue: true);
@@ -285,11 +298,8 @@ abstract final class Pref {
);
static String get blockUserID {
- String blockUserID = _setting.get(
- SettingBoxKey.blockUserID,
- defaultValue: '',
- );
- if (blockUserID.isEmpty) {
+ String? blockUserID = _setting.get(SettingBoxKey.blockUserID);
+ if (blockUserID == null || blockUserID.isEmpty) {
blockUserID = const Uuid().v4().replaceAll('-', '');
_setting.put(SettingBoxKey.blockUserID, blockUserID);
}
@@ -313,11 +323,16 @@ abstract final class Pref {
static int get dynamicPeriod =>
_setting.get(SettingBoxKey.dynamicPeriod, defaultValue: 5);
- static int get schemeVariant =>
- _setting.get(SettingBoxKey.schemeVariant, defaultValue: 10);
+ static FlexSchemeVariant get schemeVariant =>
+ FlexSchemeVariant.values[_setting.get(
+ SettingBoxKey.schemeVariant,
+ defaultValue: FlexSchemeVariant.material3Legacy.index,
+ )];
- static double get danmakuFontScaleFS =>
- _setting.get(SettingBoxKey.danmakuFontScaleFS, defaultValue: 1.2);
+ static double get danmakuFontScaleFS => _setting.get(
+ SettingBoxKey.danmakuFontScaleFS,
+ defaultValue: PlatformUtils.isMobile ? 1.2 : 1.7,
+ );
static bool get danmakuMassiveMode =>
_setting.get(SettingBoxKey.danmakuMassiveMode, defaultValue: false);
@@ -352,11 +367,15 @@ abstract final class Pref {
static bool get expandIntroPanelH =>
_setting.get(SettingBoxKey.expandIntroPanelH, defaultValue: false);
- static bool get horizontalSeasonPanel =>
- _setting.get(SettingBoxKey.horizontalSeasonPanel, defaultValue: false);
+ static bool get horizontalSeasonPanel => _setting.get(
+ SettingBoxKey.horizontalSeasonPanel,
+ defaultValue: PlatformUtils.isDesktop,
+ );
- static bool get horizontalMemberPage =>
- _setting.get(SettingBoxKey.horizontalMemberPage, defaultValue: false);
+ static bool get horizontalMemberPage => _setting.get(
+ SettingBoxKey.horizontalMemberPage,
+ defaultValue: PlatformUtils.isDesktop,
+ );
static int? get replyLengthLimit {
int length = _setting.get(SettingBoxKey.replyLengthLimit, defaultValue: 6);
@@ -435,8 +454,7 @@ abstract final class Pref {
if (index != null) {
superResolutionType = SuperResolutionType.values.getOrNull(index);
}
- superResolutionType ??= SuperResolutionType.disable;
- return superResolutionType;
+ return superResolutionType ?? SuperResolutionType.disable;
}
static bool get preInitPlayer =>
@@ -682,16 +700,20 @@ abstract final class Pref {
static bool get enableHttp2 =>
_setting.get(SettingBoxKey.enableHttp2, defaultValue: false);
- static int get replySortType =>
- _setting.get(SettingBoxKey.replySortType, defaultValue: 1);
+ static ReplySortType get replySortType =>
+ ReplySortType.values[_setting.get(
+ SettingBoxKey.replySortType,
+ defaultValue: ReplySortType.hot.index,
+ )];
static bool get hideTabBar =>
_setting.get(SettingBoxKey.hideTabBar, defaultValue: true);
- static int get dynamicBadgeMode => _setting.get(
- SettingBoxKey.dynamicBadgeMode,
- defaultValue: DynamicBadgeMode.number.index,
- );
+ static DynamicBadgeMode get dynamicBadgeMode =>
+ DynamicBadgeMode.values[_setting.get(
+ SettingBoxKey.dynamicBadgeMode,
+ defaultValue: DynamicBadgeMode.number.index,
+ )];
static bool get enableMYBar =>
_setting.get(SettingBoxKey.enableMYBar, defaultValue: true);
@@ -730,8 +752,10 @@ abstract final class Pref {
static double get danmakuOpacity =>
_setting.get(SettingBoxKey.danmakuOpacity, defaultValue: 1.0);
- static double get danmakuFontScale =>
- _setting.get(SettingBoxKey.danmakuFontScale, defaultValue: 1.0);
+ static double get danmakuFontScale => _setting.get(
+ SettingBoxKey.danmakuFontScale,
+ defaultValue: PlatformUtils.isMobile ? 1.0 : 1.4,
+ );
static double get danmakuDuration =>
_setting.get(SettingBoxKey.danmakuDuration, defaultValue: 7.0);
@@ -739,11 +763,15 @@ abstract final class Pref {
static double get danmakuStaticDuration =>
_setting.get(SettingBoxKey.danmakuStaticDuration, defaultValue: 4.0);
- static double get danmakuStrokeWidth =>
- _setting.get(SettingBoxKey.danmakuStrokeWidth, defaultValue: 1.5);
+ static double get danmakuStrokeWidth => _setting.get(
+ SettingBoxKey.danmakuStrokeWidth,
+ defaultValue: PlatformUtils.isMobile ? 1.5 : 2.5,
+ );
- static int get danmakuFontWeight =>
- _setting.get(SettingBoxKey.danmakuFontWeight, defaultValue: 5);
+ static int get danmakuFontWeight => _setting.get(
+ SettingBoxKey.danmakuFontWeight,
+ defaultValue: PlatformUtils.isMobile ? 5 : 6,
+ );
static bool get enableLongShowControl =>
_setting.get(SettingBoxKey.enableLongShowControl, defaultValue: false);
@@ -782,14 +810,16 @@ abstract final class Pref {
_setting.get(SettingBoxKey.enableSearchRcmd, defaultValue: true);
static bool get enableSaveLastData =>
- _setting.get(SettingBoxKey.enableSaveLastData, defaultValue: false);
+ _setting.get(SettingBoxKey.enableSaveLastData, defaultValue: true);
static double get defaultToastOp =>
_setting.get(SettingBoxKey.defaultToastOp, defaultValue: 1.0);
- static int get playRepeat =>
- (_video.get(VideoBoxKey.playRepeat) as num?)?.toInt() ??
- PlayRepeat.pause.index;
+ static PlayRepeat get playRepeat =>
+ PlayRepeat.values[_video.get(
+ VideoBoxKey.playRepeat,
+ defaultValue: PlayRepeat.pause.index,
+ )];
static int get cacheVideoFit =>
_video.get(VideoBoxKey.cacheVideoFit, defaultValue: 1);
@@ -904,4 +934,10 @@ abstract final class Pref {
SettingBoxKey.followOrderType,
defaultValue: FollowOrderType.def.index,
)];
+
+ static bool get enableImgMenu =>
+ _setting.get(SettingBoxKey.enableImgMenu, defaultValue: false);
+
+ static bool get showDynDispute =>
+ _setting.get(SettingBoxKey.showDynDispute, defaultValue: false);
}
diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart
index 3fb15d4c5..70f20a2af 100644
--- a/lib/utils/utils.dart
+++ b/lib/utils/utils.dart
@@ -145,7 +145,7 @@ abstract final class Utils {
return Clipboard.setData(ClipboardData(text: text));
}
- static String makeHeroTag(v) {
+ static String makeHeroTag(dynamic v) {
return v.toString() + random.nextInt(9999).toString();
}