diff --git a/lib/pages/setting/models/extra_settings.dart b/lib/pages/setting/models/extra_settings.dart index 4e8753aba..51ffd6e3d 100644 --- a/lib/pages/setting/models/extra_settings.dart +++ b/lib/pages/setting/models/extra_settings.dart @@ -70,19 +70,23 @@ List get extraSettings => [ onTap: _showDownPathDialog, ), ], - SwitchModel( - title: '空降助手', - subtitle: '点击配置', - setKey: SettingBoxKey.enableSponsorBlock, - defaultVal: false, - onTap: (context) => Get.toNamed('/sponsorBlock'), - leading: const Stack( - clipBehavior: Clip.none, - alignment: Alignment.center, - children: [ - Icon(Icons.shield_outlined), - Icon(Icons.play_arrow_rounded, size: 15), - ], + SplitModel( + normalModel: const NormalModel.split( + title: '空降助手', + subtitle: '点击配置', + leading: Stack( + clipBehavior: Clip.none, + alignment: Alignment.center, + children: [ + Icon(Icons.shield_outlined), + Icon(Icons.play_arrow_rounded, size: 15), + ], + ), + ), + switchModel: SwitchModel.split( + defaultVal: false, + setKey: SettingBoxKey.enableSponsorBlock, + onTap: (context) => Get.toNamed('/sponsorBlock'), ), ), PopupModel( @@ -94,14 +98,18 @@ List get extraSettings => [ .put(SettingBoxKey.pgcSkipType, value.index) .whenComplete(setState), ), - SwitchModel( - title: '检查未读动态', - subtitle: '点击设置检查周期(min)', - leading: const Icon(Icons.notifications_none), - setKey: SettingBoxKey.checkDynamic, - defaultVal: true, - onChanged: (value) => Get.find().checkDynamic = value, - onTap: _showDynDialog, + SplitModel( + normalModel: const NormalModel.split( + title: '检查未读动态', + subtitle: '点击设置检查周期(min)', + leading: Icon(Icons.notifications_none), + ), + switchModel: SwitchModel.split( + defaultVal: true, + setKey: SettingBoxKey.checkDynamic, + onChanged: (value) => Get.find().checkDynamic = value, + onTap: _showDynDialog, + ), ), SwitchModel( title: '显示视频分段信息', @@ -615,12 +623,17 @@ List get extraSettings => [ defaultVal: false, onChanged: (value) => MemberTabType.showMemberShop = value, ), - const SwitchModel( - leading: Icon(Icons.airplane_ticket_outlined), - title: '设置代理', - subtitle: '设置代理 host:port', - setKey: SettingBoxKey.enableSystemProxy, - onTap: _showProxyDialog, + const SplitModel( + normalModel: NormalModel.split( + title: '设置代理', + subtitle: '设置代理 host:port', + leading: Icon(Icons.airplane_ticket_outlined), + ), + switchModel: SwitchModel.split( + defaultVal: false, + setKey: SettingBoxKey.enableSystemProxy, + onTap: _showProxyDialog, + ), ), const SwitchModel( title: '自动清除缓存', diff --git a/lib/pages/setting/models/model.dart b/lib/pages/setting/models/model.dart index 3cc4ab771..8402e64b1 100644 --- a/lib/pages/setting/models/model.dart +++ b/lib/pages/setting/models/model.dart @@ -30,6 +30,43 @@ sealed class SettingsModel { }); } +class SplitModel extends SettingsModel { + const SplitModel({ + super.contentPadding, + super.titleStyle, + required this.normalModel, + required this.switchModel, + }); + + @override + String? get effectiveSubtitle => normalModel.effectiveSubtitle; + + @override + String get effectiveTitle => normalModel.effectiveTitle; + + @override + String? get title => normalModel.title; + + final NormalModel normalModel; + + final SwitchModel switchModel; + + @override + Widget get widget => SetSwitchItem( + title: effectiveTitle, + subtitle: effectiveSubtitle, + setKey: switchModel.setKey, + defaultVal: switchModel.defaultVal, + onChanged: switchModel.onChanged, + needReboot: switchModel.needReboot, + leading: normalModel.leading, + onTap: switchModel.onTap, + contentPadding: contentPadding, + titleStyle: titleStyle, + isSplit: true, + ); +} + class PopupModel extends SettingsModel { const PopupModel({ required this.title, @@ -88,6 +125,18 @@ class NormalModel extends SettingsModel { this.onTap, }) : assert(title != null || getTitle != null); + const NormalModel.split({ + super.subtitle, + super.leading, + super.contentPadding, + super.titleStyle, + this.title, + this.getTitle, + this.getSubtitle, + this.getTrailing, + }) : onTap = null, + assert(title != null || getTitle != null); + @override String get effectiveTitle => title ?? getTitle!(); @override @@ -109,7 +158,7 @@ class NormalModel extends SettingsModel { class SwitchModel extends SettingsModel { @override - final String title; + final String? title; final String setKey; final bool defaultVal; final ValueChanged? onChanged; @@ -121,7 +170,7 @@ class SwitchModel extends SettingsModel { super.leading, super.contentPadding, super.titleStyle, - required this.title, + required String this.title, required this.setKey, this.defaultVal = false, this.onChanged, @@ -129,14 +178,22 @@ class SwitchModel extends SettingsModel { this.onTap, }); + const SwitchModel.split({ + required this.setKey, + this.defaultVal = false, + this.needReboot = false, + this.onChanged, + this.onTap, + }) : title = null; + @override - String get effectiveTitle => title; + String get effectiveTitle => title!; @override String? get effectiveSubtitle => subtitle; @override Widget get widget => SetSwitchItem( - title: title, + title: title!, subtitle: subtitle, setKey: setKey, defaultVal: defaultVal, diff --git a/lib/pages/setting/models/style_settings.dart b/lib/pages/setting/models/style_settings.dart index 69406d8b9..a95d6399d 100644 --- a/lib/pages/setting/models/style_settings.dart +++ b/lib/pages/setting/models/style_settings.dart @@ -82,14 +82,18 @@ List get styleSettings => [ defaultVal: false, needReboot: true, ), - SwitchModel( - title: 'App字体字重', - subtitle: '点击设置', - setKey: SettingBoxKey.appFontWeight, - defaultVal: false, - leading: const Icon(Icons.text_fields), - onChanged: (_) => Get.updateMyAppTheme(), - onTap: _showFontWeightDialog, + SplitModel( + normalModel: const NormalModel.split( + title: 'App字体字重', + subtitle: '点击设置', + leading: Icon(Icons.text_fields), + ), + switchModel: SwitchModel.split( + defaultVal: false, + setKey: SettingBoxKey.appFontWeight, + onChanged: (_) => Get.updateMyAppTheme(), + onTap: _showFontWeightDialog, + ), ), NormalModel( title: '界面缩放', diff --git a/lib/pages/setting/widgets/switch_item.dart b/lib/pages/setting/widgets/switch_item.dart index 25d2fc0ba..5f5c87718 100644 --- a/lib/pages/setting/widgets/switch_item.dart +++ b/lib/pages/setting/widgets/switch_item.dart @@ -17,8 +17,10 @@ class SetSwitchItem extends StatefulWidget { final void Function(BuildContext context)? onTap; final EdgeInsetsGeometry? contentPadding; final TextStyle? titleStyle; + final bool isSplit; const SetSwitchItem({ + super.key, required this.title, this.subtitle, required this.setKey, @@ -29,7 +31,7 @@ class SetSwitchItem extends StatefulWidget { this.onTap, this.contentPadding, this.titleStyle, - super.key, + this.isSplit = false, }); @override @@ -103,7 +105,17 @@ class _SetSwitchItemState extends State { final subTitleStyle = theme.textTheme.labelMedium!.copyWith( color: theme.colorScheme.outline, ); - return ListTile( + + final switchBtn = Transform.scale( + scale: 0.8, + alignment: .centerRight, + child: Switch( + value: val, + onChanged: switchChange, + ), + ); + + Widget child(Widget? trailing) => ListTile( contentPadding: widget.contentPadding, enabled: widget.onTap == null ? true : val, onTap: widget.onTap == null ? switchChange : () => widget.onTap!(context), @@ -112,14 +124,28 @@ class _SetSwitchItemState extends State { ? Text(widget.subtitle!, style: subTitleStyle) : null, leading: widget.leading, - trailing: Transform.scale( - scale: 0.8, - alignment: .centerRight, - child: Switch( - value: val, - onChanged: switchChange, - ), - ), + trailing: trailing, ); + + if (widget.isSplit) { + return Row( + children: [ + Expanded(child: child(null)), + SizedBox( + height: 25, + child: VerticalDivider( + width: 1, + color: theme.colorScheme.outline.withValues(alpha: .3), + ), + ), + Padding( + padding: const .only(left: 4, right: 24), + child: switchBtn, + ), + ], + ); + } + + return child(switchBtn); } }