Skip to content

Commit 1214176

Browse files
committed
refactor(settings): 重构设置页面布局,添加分组标题组件
- 提取公共的_buildSectionHeader方法用于构建分组标题 - 统一AI标签和翻译设置页面的布局结构 - 添加页面描述文本提升用户体验
1 parent 44d2755 commit 1214176

File tree

2 files changed

+151
-193
lines changed

2 files changed

+151
-193
lines changed

lib/ui/settings/widgets/ai_tag_settings_screen.dart

Lines changed: 62 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,20 @@ class _AiTagSettingsScreenState extends State<AiTagSettingsScreen> {
103103
);
104104
}
105105

106+
/// 构建分组标题
107+
Widget _buildSectionHeader(BuildContext context, String title) {
108+
return Padding(
109+
padding: const EdgeInsets.fromLTRB(16, 24, 16, 8),
110+
child: Text(
111+
title,
112+
style: Theme.of(context).textTheme.labelLarge?.copyWith(
113+
color: Theme.of(context).colorScheme.primary,
114+
fontWeight: FontWeight.w500,
115+
),
116+
),
117+
);
118+
}
119+
106120
@override
107121
Widget build(BuildContext context) {
108122
return Scaffold(
@@ -111,117 +125,61 @@ class _AiTagSettingsScreenState extends State<AiTagSettingsScreen> {
111125
),
112126
body: ListenableBuilder(
113127
listenable: widget.viewModel,
114-
builder: (context, _) => ListView(
115-
children: [
116-
const SizedBox(height: 16),
117-
118-
// AI标签目标语言设置卡片
119-
Padding(
120-
padding: const EdgeInsets.symmetric(horizontal: 16.0),
121-
child: Card(
122-
child: Padding(
123-
padding: const EdgeInsets.all(16.0),
124-
child: Column(
125-
crossAxisAlignment: CrossAxisAlignment.start,
126-
children: [
127-
Row(
128-
children: [
129-
Icon(
130-
Icons.language,
131-
color: Theme.of(context).colorScheme.primary,
128+
builder: (context, _) {
129+
return ListView(
130+
children: [
131+
// 页面描述
132+
Padding(
133+
padding: const EdgeInsets.all(16.0),
134+
child: Column(
135+
crossAxisAlignment: CrossAxisAlignment.start,
136+
children: [
137+
Text(
138+
'配置 AI 标签功能',
139+
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
140+
color:
141+
Theme.of(context).colorScheme.onSurfaceVariant,
142+
fontWeight: FontWeight.w500,
132143
),
133-
const SizedBox(width: 8),
134-
Text(
135-
'标签目标语言',
136-
style: Theme.of(context)
137-
.textTheme
138-
.titleMedium
139-
?.copyWith(
140-
color: Theme.of(context).colorScheme.primary,
141-
),
144+
),
145+
const SizedBox(height: 4),
146+
Text(
147+
'设置 AI 标签推荐的目标语言和专用模型',
148+
style: Theme.of(context).textTheme.bodySmall?.copyWith(
149+
color:
150+
Theme.of(context).colorScheme.onSurfaceVariant,
142151
),
143-
],
144-
),
145-
const SizedBox(height: 16),
146-
ListTile(
147-
contentPadding: EdgeInsets.zero,
148-
leading: const Icon(Icons.translate),
149-
title: const Text('AI标签推荐语言'),
150-
subtitle: Text(widget.viewModel.aiTagTargetLanguage),
151-
trailing: const Icon(Icons.chevron_right),
152-
onTap: _showLanguageSelectionDialog,
153-
),
154-
const Divider(),
155-
ListTile(
156-
contentPadding: EdgeInsets.zero,
157-
leading: const Icon(Icons.smart_toy),
158-
title: const Text('专用模型'),
159-
subtitle: Text(
160-
widget.viewModel.aiTagModelName.isNotEmpty
161-
? widget.viewModel.aiTagModelName
162-
: '使用全局模型'),
163-
trailing: const Icon(Icons.chevron_right),
164-
onTap: () {
165-
context
166-
.push('${Routes.modelSelection}?scenario=ai_tag');
167-
},
168-
),
169-
],
170-
),
152+
),
153+
],
171154
),
172155
),
173-
),
174156

175-
const SizedBox(height: 16),
157+
// 基础设置分组
158+
_buildSectionHeader(context, '基础设置'),
159+
ListTile(
160+
leading: const Icon(Icons.translate),
161+
title: const Text('标签推荐语言'),
162+
subtitle: Text(widget.viewModel.aiTagTargetLanguage),
163+
trailing: const Icon(Icons.chevron_right),
164+
onTap: _showLanguageSelectionDialog,
165+
),
176166

177-
// 说明信息卡片
178-
Padding(
179-
padding: const EdgeInsets.symmetric(horizontal: 16.0),
180-
child: Card(
181-
child: Padding(
182-
padding: const EdgeInsets.all(16.0),
183-
child: Column(
184-
crossAxisAlignment: CrossAxisAlignment.start,
185-
children: [
186-
Row(
187-
children: [
188-
Icon(
189-
Icons.info_outline,
190-
color: Theme.of(context).colorScheme.primary,
191-
),
192-
const SizedBox(width: 8),
193-
Text(
194-
'关于 AI 标签功能',
195-
style: Theme.of(context)
196-
.textTheme
197-
.titleMedium
198-
?.copyWith(
199-
color: Theme.of(context).colorScheme.primary,
200-
),
201-
),
202-
],
203-
),
204-
const SizedBox(height: 12),
205-
Text(
206-
'AI 标签功能会根据网页内容智能推荐合适的标签,帮助您更好地组织和管理书签。',
207-
style: Theme.of(context).textTheme.bodyMedium,
208-
),
209-
const SizedBox(height: 8),
210-
Text(
211-
'• 支持多种语言的标签推荐\n• 基于网页内容智能分析\n• 优先使用已有标签保持一致性\n• 需要配置 OpenRouter API 才能使用',
212-
style: Theme.of(context).textTheme.bodySmall?.copyWith(
213-
color: Theme.of(context)
214-
.colorScheme
215-
.onSurfaceVariant,
216-
),
217-
),
218-
],
219-
),
220-
),
167+
// 模型配置分组
168+
_buildSectionHeader(context, '模型配置'),
169+
ListTile(
170+
leading: const Icon(Icons.smart_toy),
171+
title: const Text('专用模型'),
172+
subtitle: Text(widget.viewModel.aiTagModelName.isNotEmpty
173+
? widget.viewModel.aiTagModelName
174+
: '使用全局模型'),
175+
trailing: const Icon(Icons.chevron_right),
176+
onTap: () {
177+
context.push('${Routes.modelSelection}?scenario=ai_tag');
178+
},
221179
),
222-
),
223-
],
224-
),
180+
],
181+
);
182+
},
225183
),
226184
);
227185
}

lib/ui/settings/widgets/translation_settings_screen.dart

Lines changed: 89 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,20 @@ class _TranslationSettingsScreenState extends State<TranslationSettingsScreen> {
162162
);
163163
}
164164

165+
/// 构建分组标题
166+
Widget _buildSectionHeader(BuildContext context, String title) {
167+
return Padding(
168+
padding: const EdgeInsets.fromLTRB(16, 24, 16, 8),
169+
child: Text(
170+
title,
171+
style: Theme.of(context).textTheme.labelLarge?.copyWith(
172+
color: Theme.of(context).colorScheme.primary,
173+
fontWeight: FontWeight.w500,
174+
),
175+
),
176+
);
177+
}
178+
165179
@override
166180
Widget build(BuildContext context) {
167181
return Scaffold(
@@ -170,99 +184,85 @@ class _TranslationSettingsScreenState extends State<TranslationSettingsScreen> {
170184
),
171185
body: ListenableBuilder(
172186
listenable: widget.viewModel,
173-
builder: (context, _) => ListView(
174-
children: [
175-
ListTile(
176-
leading: const Icon(Icons.translate),
177-
title: const Text('翻译服务提供方'),
178-
subtitle: Text(widget.viewModel.translationProvider),
179-
trailing: const Icon(Icons.chevron_right),
180-
onTap: () {
181-
// 目前只支持AI,所以暂时不提供选择
182-
SnackBarHelper.showInfo(
183-
context,
184-
'目前只支持 AI 翻译服务',
185-
);
186-
},
187-
),
188-
const Divider(),
189-
ListTile(
190-
leading: const Icon(Icons.language),
191-
title: const Text('翻译目标语种'),
192-
subtitle: Text(widget.viewModel.translationTargetLanguage),
193-
trailing: const Icon(Icons.chevron_right),
194-
onTap: _showLanguageSelectionDialog,
195-
),
196-
const Divider(),
197-
ListTile(
198-
leading: const Icon(Icons.smart_toy),
199-
title: const Text('专用模型'),
200-
subtitle: Text(widget.viewModel.translationModelName.isNotEmpty
201-
? widget.viewModel.translationModelName
202-
: '使用全局模型'),
203-
trailing: const Icon(Icons.chevron_right),
204-
onTap: () {
205-
context.push('${Routes.modelSelection}?scenario=translation');
206-
},
207-
),
208-
const Divider(),
209-
SwitchListTile(
210-
secondary: const Icon(Icons.cached),
211-
title: const Text('启用翻译缓存'),
212-
subtitle: const Text('缓存翻译结果以提高性能'),
213-
value: widget.viewModel.translationCacheEnabled,
214-
onChanged: (bool value) {
215-
widget.viewModel.saveTranslationCacheEnabled.execute(value);
216-
},
217-
),
218-
const Divider(),
219-
Padding(
220-
padding: const EdgeInsets.all(16.0),
221-
child: Card(
222-
child: Padding(
223-
padding: const EdgeInsets.all(16.0),
224-
child: Column(
225-
crossAxisAlignment: CrossAxisAlignment.start,
226-
children: [
227-
Row(
228-
children: [
229-
Icon(
230-
Icons.info_outline,
231-
color: Theme.of(context).colorScheme.primary,
187+
builder: (context, _) {
188+
return ListView(
189+
children: [
190+
// 页面描述
191+
Padding(
192+
padding: const EdgeInsets.all(16.0),
193+
child: Column(
194+
crossAxisAlignment: CrossAxisAlignment.start,
195+
children: [
196+
Text(
197+
'配置翻译功能',
198+
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
199+
color:
200+
Theme.of(context).colorScheme.onSurfaceVariant,
201+
fontWeight: FontWeight.w500,
232202
),
233-
const SizedBox(width: 8),
234-
Text(
235-
'关于翻译功能',
236-
style: Theme.of(context)
237-
.textTheme
238-
.titleMedium
239-
?.copyWith(
240-
color: Theme.of(context).colorScheme.primary,
241-
),
203+
),
204+
const SizedBox(height: 4),
205+
Text(
206+
'设置翻译服务提供方、目标语种和专用模型',
207+
style: Theme.of(context).textTheme.bodySmall?.copyWith(
208+
color:
209+
Theme.of(context).colorScheme.onSurfaceVariant,
242210
),
243-
],
244-
),
245-
const SizedBox(height: 12),
246-
Text(
247-
'翻译功能使用 AI 服务将文章内容翻译为您选择的目标语言。请确保已在 AI 设置中配置了 OpenRouter API 密钥。',
248-
style: Theme.of(context).textTheme.bodyMedium,
249-
),
250-
const SizedBox(height: 8),
251-
Text(
252-
'• 支持多种主流语言\n• 启用缓存可以提高翻译速度\n• 翻译质量取决于所选的 AI 模型',
253-
style: Theme.of(context).textTheme.bodySmall?.copyWith(
254-
color: Theme.of(context)
255-
.colorScheme
256-
.onSurfaceVariant,
257-
),
258-
),
259-
],
260-
),
211+
),
212+
],
261213
),
262214
),
263-
),
264-
],
265-
),
215+
216+
// 基础设置分组
217+
_buildSectionHeader(context, '基础设置'),
218+
ListTile(
219+
leading: const Icon(Icons.translate),
220+
title: const Text('翻译服务提供方'),
221+
subtitle: Text(widget.viewModel.translationProvider),
222+
trailing: const Icon(Icons.chevron_right),
223+
onTap: () {
224+
SnackBarHelper.showInfo(
225+
context,
226+
'目前只支持 AI 翻译服务',
227+
);
228+
},
229+
),
230+
ListTile(
231+
leading: const Icon(Icons.language),
232+
title: const Text('翻译目标语种'),
233+
subtitle: Text(widget.viewModel.translationTargetLanguage),
234+
trailing: const Icon(Icons.chevron_right),
235+
onTap: _showLanguageSelectionDialog,
236+
),
237+
238+
// 模型配置分组
239+
_buildSectionHeader(context, '模型配置'),
240+
ListTile(
241+
leading: const Icon(Icons.smart_toy),
242+
title: const Text('专用模型'),
243+
subtitle: Text(widget.viewModel.translationModelName.isNotEmpty
244+
? widget.viewModel.translationModelName
245+
: '使用全局模型'),
246+
trailing: const Icon(Icons.chevron_right),
247+
onTap: () {
248+
context.push('${Routes.modelSelection}?scenario=translation');
249+
},
250+
),
251+
252+
// 性能优化分组
253+
_buildSectionHeader(context, '性能优化'),
254+
SwitchListTile(
255+
secondary: const Icon(Icons.cached),
256+
title: const Text('启用翻译缓存'),
257+
subtitle: const Text('缓存翻译结果以提高性能'),
258+
value: widget.viewModel.translationCacheEnabled,
259+
onChanged: (bool value) {
260+
widget.viewModel.saveTranslationCacheEnabled.execute(value);
261+
},
262+
),
263+
],
264+
);
265+
},
266266
),
267267
);
268268
}

0 commit comments

Comments
 (0)