500 lines
16 KiB
Dart
500 lines
16 KiB
Dart
/// ============================================================
|
|
/// 闲言APP — 通用设置分组定义
|
|
/// 创建时间: 2026-05-19
|
|
/// 更新时间: 2026-06-05
|
|
/// 作用: 构建通用设置页面的所有分组和设置项数据
|
|
/// 上次更新: 添加无障碍分组(语义调试/高对比度/减少动画/粗体文本指示)
|
|
|
|
import 'package:flutter/cupertino.dart';
|
|
|
|
import '../../../../../../l10n/app_locale.dart';
|
|
import '../../../../../../l10n/translations.dart';
|
|
import '../../../../../../core/theme/app_colors.dart';
|
|
import '../../../../../../core/providers/split_view_provider.dart';
|
|
import '../../providers/general_settings_provider.dart';
|
|
import '../../providers/plugin_provider.dart';
|
|
import 'setting_models.dart';
|
|
|
|
/// 构建通用设置的所有分组
|
|
List<SettingSection> buildGeneralSettingSections({
|
|
required GeneralSettingsState settings,
|
|
required bool notificationEnabled,
|
|
required bool preloadEnabled,
|
|
required String appLockMethodLabel,
|
|
required PluginState pluginState,
|
|
required T t,
|
|
required int navBarPositionIndex,
|
|
required double splitRatio,
|
|
required bool splitViewEnabled,
|
|
}) {
|
|
return [
|
|
// ── 交互设置 ──
|
|
SettingSection(
|
|
title: t.interaction,
|
|
icon: CupertinoIcons.hand_draw_fill,
|
|
color: AppColors.iosBlue,
|
|
items: [
|
|
SettingItem(
|
|
id: 'sound',
|
|
icon: CupertinoIcons.speaker_2_fill,
|
|
iconColor: AppColors.iosBlue,
|
|
title: t.sound,
|
|
subtitle: t.soundSubtitle,
|
|
type: SettingType.toggle,
|
|
value: settings.soundEnabled,
|
|
),
|
|
SettingItem(
|
|
id: 'vibration',
|
|
icon: CupertinoIcons.device_phone_portrait,
|
|
iconColor: AppColors.iosPurple,
|
|
title: t.vibration,
|
|
subtitle: t.vibrationSubtitle,
|
|
type: SettingType.selection,
|
|
displayValue: settings.vibrationLevel.label,
|
|
),
|
|
if (settings.vibrationEnabled)
|
|
SettingItem(
|
|
id: 'sound_effect',
|
|
icon: CupertinoIcons.music_note_2,
|
|
iconColor: AppColors.iosLightPurple,
|
|
title: t.soundEffect,
|
|
subtitle: t.soundEffectSubtitle,
|
|
type: SettingType.selection,
|
|
displayValue: settings.soundEffectType.label,
|
|
),
|
|
SettingItem(
|
|
id: 'sfx',
|
|
icon: CupertinoIcons.waveform_path,
|
|
iconColor: AppColors.iosGreen,
|
|
title: '音效反馈',
|
|
subtitle: '操作时播放音效',
|
|
type: SettingType.toggle,
|
|
value: settings.sfxEnabled,
|
|
),
|
|
if (settings.sfxEnabled)
|
|
SettingItem(
|
|
id: 'sfx_style',
|
|
icon: CupertinoIcons.music_note_2,
|
|
iconColor: AppColors.iosLightPurple,
|
|
title: '🎵 音效类型',
|
|
subtitle: '选择音效风格',
|
|
type: SettingType.selection,
|
|
displayValue: settings.sfxStyle.label,
|
|
),
|
|
SettingItem(
|
|
id: 'page_transition_mode',
|
|
icon: CupertinoIcons.chevron_left_2,
|
|
iconColor: AppColors.iosBlue,
|
|
title: t.pageTransitionMode,
|
|
subtitle: settings.pageTransitionModeId == 'navigate'
|
|
? t.pageTransitionModeNavigate
|
|
: t.pageTransitionModeSheet,
|
|
type: SettingType.selection,
|
|
displayValue: settings.pageTransitionMode.label,
|
|
),
|
|
if (settings.pageTransitionModeId == 'navigate')
|
|
SettingItem(
|
|
id: 'predictive_back',
|
|
icon: CupertinoIcons.arrow_turn_down_left,
|
|
iconColor: AppColors.iosLightBlue,
|
|
title: t.predictiveBack,
|
|
subtitle: t.predictiveBackSubtitle,
|
|
type: SettingType.toggle,
|
|
value: settings.predictiveBackEnabled,
|
|
isLocked: true,
|
|
),
|
|
SettingItem(
|
|
id: 'long_press_preview',
|
|
icon: CupertinoIcons.hand_point_right_fill,
|
|
iconColor: AppColors.iosOrange,
|
|
title: t.longPressPreview,
|
|
subtitle: t.longPressPreviewSubtitle,
|
|
type: SettingType.toggle,
|
|
value: settings.longPressPreviewEnabled,
|
|
isLocked: true,
|
|
),
|
|
SettingItem(
|
|
id: 'shake_to_switch',
|
|
icon: CupertinoIcons.arrow_counterclockwise,
|
|
iconColor: AppColors.iosPurple,
|
|
title: '摇一摇换句',
|
|
subtitle: '摇晃手机切换每日推荐',
|
|
type: SettingType.toggle,
|
|
value: settings.shakeToSwitch,
|
|
),
|
|
],
|
|
),
|
|
|
|
// ── 功能扩展 ──
|
|
SettingSection(
|
|
title: '功能扩展',
|
|
icon: CupertinoIcons.square_grid_2x2_fill,
|
|
color: AppColors.iosPurple,
|
|
items: [
|
|
SettingItem(
|
|
id: 'plugin',
|
|
icon: CupertinoIcons.square_grid_2x2_fill,
|
|
iconColor: AppColors.iosPurple,
|
|
title: '插件',
|
|
subtitle: '翻译守护、文本朗读等增强功能',
|
|
type: SettingType.navigation,
|
|
displayValue: '${_countAvailablePlugins(pluginState)}个可用',
|
|
),
|
|
],
|
|
),
|
|
|
|
// ── 通知设置 ──
|
|
SettingSection(
|
|
title: t.notification,
|
|
icon: CupertinoIcons.bell_fill,
|
|
color: AppColors.iosRed,
|
|
items: [
|
|
SettingItem(
|
|
id: 'notification',
|
|
icon: CupertinoIcons.bell_fill,
|
|
iconColor: AppColors.iosRed,
|
|
title: t.pushNotification,
|
|
subtitle: t.pushNotificationSubtitle,
|
|
type: SettingType.navigation,
|
|
displayValue: notificationEnabled ? t.enabled : t.disabled,
|
|
),
|
|
SettingItem(
|
|
id: 'daily_notification',
|
|
icon: CupertinoIcons.bell_circle_fill,
|
|
iconColor: AppColors.iosOrange,
|
|
title: '每日提醒',
|
|
subtitle: '每天定时推送一句好句',
|
|
type: SettingType.toggle,
|
|
value: settings.dailyNotification,
|
|
),
|
|
if (settings.dailyNotification)
|
|
SettingItem(
|
|
id: 'notify_time',
|
|
icon: CupertinoIcons.clock_fill,
|
|
iconColor: AppColors.iosPurple,
|
|
title: '提醒时间',
|
|
subtitle: '选择每日提醒的时间',
|
|
type: SettingType.selection,
|
|
displayValue:
|
|
'${settings.notifyTimeHour.toString().padLeft(2, '0')}:${settings.notifyTimeMinute.toString().padLeft(2, '0')}',
|
|
),
|
|
],
|
|
),
|
|
|
|
// ── 显示设置 ──
|
|
SettingSection(
|
|
title: t.display,
|
|
icon: CupertinoIcons.brightness_solid,
|
|
color: AppColors.iosPurple,
|
|
items: [
|
|
SettingItem(
|
|
id: 'screen_timeout',
|
|
icon: CupertinoIcons.timer,
|
|
iconColor: AppColors.iosPurple,
|
|
title: t.screenTimeout,
|
|
subtitle: t.screenTimeoutSubtitle,
|
|
type: SettingType.selection,
|
|
displayValue: settings.screenTimeout.label,
|
|
),
|
|
SettingItem(
|
|
id: 'screen_always_on',
|
|
icon: CupertinoIcons.sun_max_fill,
|
|
iconColor: AppColors.iosYellow,
|
|
title: '屏幕常亮',
|
|
subtitle: '控制屏幕是否保持常亮',
|
|
type: SettingType.selection,
|
|
displayValue: [
|
|
'关闭',
|
|
'阅读时',
|
|
'始终',
|
|
][settings.screenAlwaysOn.clamp(0, 2)],
|
|
),
|
|
SettingItem(
|
|
id: 'font_scale',
|
|
icon: CupertinoIcons.textformat_size,
|
|
iconColor: AppColors.iosLightPurple,
|
|
title: t.fontSize,
|
|
subtitle: t.fontSizeSubtitle,
|
|
type: SettingType.navigation,
|
|
),
|
|
SettingItem(
|
|
id: 'startup_page',
|
|
icon: CupertinoIcons.house_fill,
|
|
iconColor: AppColors.iosGreen,
|
|
title: t.startupPage,
|
|
subtitle: t.startupPageSubtitle,
|
|
type: SettingType.selection,
|
|
displayValue: settings.startupPage.label,
|
|
),
|
|
const SettingItem(
|
|
id: 'reopen_onboarding',
|
|
icon: CupertinoIcons.book,
|
|
iconColor: AppColors.toolPurple,
|
|
title: '重新打开引导页',
|
|
subtitle: '查看功能介绍和个性化设置向导',
|
|
type: SettingType.action,
|
|
),
|
|
SettingItem(
|
|
id: 'immersive_status',
|
|
icon: CupertinoIcons.fullscreen,
|
|
iconColor: AppColors.iosLightBlue,
|
|
title: t.immersiveStatus,
|
|
subtitle: t.immersiveStatusSubtitle,
|
|
type: SettingType.toggle,
|
|
value: settings.immersiveStatusBar,
|
|
),
|
|
SettingItem(
|
|
id: 'nav_bar_position',
|
|
icon: CupertinoIcons.sidebar_left,
|
|
iconColor: AppColors.iosBlue,
|
|
title: '导航栏位置',
|
|
subtitle: '宽屏时导航栏的停靠位置',
|
|
type: SettingType.selection,
|
|
displayValue:
|
|
(navBarPositionIndex >= 0 &&
|
|
navBarPositionIndex < NavBarPosition.values.length)
|
|
? NavBarPosition.values[navBarPositionIndex].label
|
|
: '左侧',
|
|
),
|
|
SettingItem(
|
|
id: 'split_view_ratio',
|
|
icon: CupertinoIcons.rectangle_split_3x1,
|
|
iconColor: AppColors.iosPurple,
|
|
title: '分屏比例',
|
|
subtitle: '宽屏分屏时左右面板的比例',
|
|
type: SettingType.selection,
|
|
displayValue:
|
|
'${(splitRatio * 100).toInt()}:${(100 - splitRatio * 100).toInt()}',
|
|
),
|
|
SettingItem(
|
|
id: 'split_view_enabled',
|
|
icon: CupertinoIcons.rectangle_split_3x1,
|
|
iconColor: AppColors.iosGreen,
|
|
title: '分屏功能',
|
|
subtitle: '宽屏时启用左右分屏布局',
|
|
type: SettingType.toggle,
|
|
value: splitViewEnabled,
|
|
),
|
|
SettingItem(
|
|
id: 'content_density',
|
|
icon: CupertinoIcons.rectangle_3_offgrid,
|
|
iconColor: AppColors.iosLightGreen,
|
|
title: t.contentDensity,
|
|
subtitle: t.contentDensitySubtitle,
|
|
type: SettingType.selection,
|
|
displayValue: settings.contentDensity.label,
|
|
),
|
|
SettingItem(
|
|
id: 'reduce_animations',
|
|
icon: CupertinoIcons.paintbrush_fill,
|
|
iconColor: AppColors.iosGray,
|
|
title: t.reduceAnimations,
|
|
subtitle: t.reduceAnimationsSubtitle,
|
|
type: SettingType.toggle,
|
|
value: settings.reduceAnimations,
|
|
),
|
|
SettingItem(
|
|
id: 'shader_background',
|
|
icon: CupertinoIcons.sparkles,
|
|
iconColor: AppColors.iosLightPurple,
|
|
title: '特效背景',
|
|
subtitle: '句子卡片流体渐变特效',
|
|
type: SettingType.toggle,
|
|
value: settings.shaderBackground,
|
|
),
|
|
SettingItem(
|
|
id: 'language',
|
|
icon: CupertinoIcons.globe,
|
|
iconColor: AppColors.iosSkyBlue,
|
|
title: t.language,
|
|
subtitle: t.languageSubtitle,
|
|
type: SettingType.selection,
|
|
displayValue: AppLocale.fromId(settings.languageId).nativeName,
|
|
),
|
|
],
|
|
),
|
|
|
|
// ── 性能设置 ──
|
|
SettingSection(
|
|
title: t.performance,
|
|
icon: CupertinoIcons.bolt_fill,
|
|
color: AppColors.iosGreen,
|
|
items: [
|
|
SettingItem(
|
|
id: 'smart_mode',
|
|
icon: CupertinoIcons.wand_stars,
|
|
iconColor: AppColors.iosBlue,
|
|
title: t.smartMode,
|
|
subtitle: t.smartModeSubtitle,
|
|
type: SettingType.navigation,
|
|
),
|
|
SettingItem(
|
|
id: 'preload',
|
|
icon: CupertinoIcons.bolt_fill,
|
|
iconColor: AppColors.iosGreen,
|
|
title: t.preload,
|
|
subtitle: t.preloadSubtitle,
|
|
type: SettingType.toggle,
|
|
value: preloadEnabled,
|
|
),
|
|
SettingItem(
|
|
id: 'cache_strategy',
|
|
icon: CupertinoIcons.arrow_down_circle_fill,
|
|
iconColor: AppColors.iosBlue,
|
|
title: t.cacheStrategy,
|
|
subtitle: t.cacheStrategySubtitle,
|
|
type: SettingType.selection,
|
|
displayValue: settings.cacheStrategy.label,
|
|
),
|
|
SettingItem(
|
|
id: 'image_quality',
|
|
icon: CupertinoIcons.photo_fill,
|
|
iconColor: AppColors.iosLightPurple,
|
|
title: t.imageQuality,
|
|
subtitle: settings.imageQualityId == 'original'
|
|
? t.imageQualityOriginal
|
|
: settings.imageQualityId == 'saver'
|
|
? t.imageQualitySaver
|
|
: t.imageQualityBalanced,
|
|
type: SettingType.selection,
|
|
displayValue: settings.imageQuality.label,
|
|
),
|
|
SettingItem(
|
|
id: 'data_saver',
|
|
icon: CupertinoIcons.wifi,
|
|
iconColor: AppColors.iosLightGreen,
|
|
title: t.dataSaver,
|
|
subtitle: t.dataSaverSubtitle,
|
|
type: SettingType.toggle,
|
|
value: settings.dataSaverMode,
|
|
),
|
|
],
|
|
),
|
|
|
|
// ── 隐私与权限 ──
|
|
SettingSection(
|
|
title: t.privacyAndPermissions,
|
|
icon: CupertinoIcons.lock_shield_fill,
|
|
color: AppColors.iosBlue,
|
|
items: [
|
|
SettingItem(
|
|
id: 'app_lock',
|
|
icon: CupertinoIcons.lock_fill,
|
|
iconColor: AppColors.iosBlue,
|
|
title: t.appLock,
|
|
subtitle: t.appLockSubtitle,
|
|
type: SettingType.navigation,
|
|
displayValue: settings.appLockEnabled
|
|
? appLockMethodLabel
|
|
: t.disabled,
|
|
),
|
|
SettingItem(
|
|
id: 'clipboard_read',
|
|
icon: CupertinoIcons.doc_on_clipboard_fill,
|
|
iconColor: AppColors.iosLightBlue,
|
|
title: t.clipboardRead,
|
|
subtitle: t.clipboardReadSubtitle,
|
|
type: SettingType.toggle,
|
|
value: settings.clipboardReadEnabled,
|
|
),
|
|
SettingItem(
|
|
id: 'nearby_discovery',
|
|
icon: CupertinoIcons.antenna_radiowaves_left_right,
|
|
iconColor: AppColors.iosGreen,
|
|
title: '近场发现',
|
|
subtitle: '允许被附近用户发现',
|
|
type: SettingType.toggle,
|
|
value: settings.nearbyDiscovery,
|
|
),
|
|
SettingItem(
|
|
id: 'permission',
|
|
icon: CupertinoIcons.lock_shield_fill,
|
|
iconColor: AppColors.iosBlue,
|
|
title: t.permissionManagement,
|
|
subtitle: t.permissionManagementSubtitle,
|
|
type: SettingType.navigation,
|
|
displayValue: t.view,
|
|
),
|
|
],
|
|
),
|
|
|
|
// ── 其他设置入口 ──
|
|
SettingSection(
|
|
title: t.advanced,
|
|
icon: CupertinoIcons.gear_solid,
|
|
color: AppColors.iosGray,
|
|
items: [
|
|
const SettingItem(
|
|
id: 'other_settings',
|
|
icon: CupertinoIcons.chevron_left_2,
|
|
iconColor: AppColors.iosGray,
|
|
title: '其他设置',
|
|
subtitle: '高级设置、辅助功能、电池与存储',
|
|
type: SettingType.navigation,
|
|
displayValue: '',
|
|
),
|
|
],
|
|
),
|
|
|
|
// ── 开发者 ──
|
|
const SettingSection(
|
|
title: '开发者',
|
|
icon: CupertinoIcons.hammer_fill,
|
|
color: AppColors.iosOrange,
|
|
items: [
|
|
SettingItem(
|
|
id: 'log_level',
|
|
icon: CupertinoIcons.text_justify,
|
|
iconColor: AppColors.iosOrange,
|
|
title: '日志级别',
|
|
subtitle: '按模块控制日志输出级别',
|
|
type: SettingType.navigation,
|
|
displayValue: '',
|
|
),
|
|
],
|
|
),
|
|
];
|
|
}
|
|
|
|
/// 根据搜索关键词过滤设置分组(支持拼音匹配)
|
|
List<SettingSection> filterSettingSections(
|
|
List<SettingSection> sections,
|
|
String query, {
|
|
bool Function(String query, String text)? pinyinMatcher,
|
|
}) {
|
|
if (query.isEmpty) return sections;
|
|
final q = query.toLowerCase();
|
|
return sections
|
|
.map((section) {
|
|
final filteredItems = section.items.where((item) {
|
|
if (item.title.toLowerCase().contains(q)) return true;
|
|
if (item.subtitle.toLowerCase().contains(q)) return true;
|
|
if (item.id.toLowerCase().contains(q)) return true;
|
|
if (pinyinMatcher != null) {
|
|
if (pinyinMatcher(query, item.title)) return true;
|
|
if (pinyinMatcher(query, item.subtitle)) return true;
|
|
}
|
|
return false;
|
|
}).toList();
|
|
if (filteredItems.isEmpty) return null;
|
|
return SettingSection(
|
|
title: section.title,
|
|
icon: section.icon,
|
|
color: section.color,
|
|
items: filteredItems,
|
|
);
|
|
})
|
|
.whereType<SettingSection>()
|
|
.toList();
|
|
}
|
|
|
|
/// 从PluginState动态计算已启用插件数量
|
|
/// 过滤启用状态的插件再计数,未来新增插件时在此添加
|
|
int _countAvailablePlugins(PluginState pluginState) {
|
|
return [
|
|
pluginState.translateEnabled,
|
|
pluginState.ttsEnabled,
|
|
pluginState.pinyinEnabled,
|
|
].where((enabled) => enabled).length;
|
|
}
|