feat: 增加AI配置文件与TTS自动朗读,修复二级页面返回按钮与音频播放
This commit is contained in:
@@ -199,8 +199,10 @@ class _AbilityRow extends StatelessWidget {
|
||||
}
|
||||
|
||||
class SettingsPage extends StatefulWidget {
|
||||
const SettingsPage({super.key, required this.state});
|
||||
const SettingsPage({super.key, required this.state, this.onBack});
|
||||
final AppState state;
|
||||
final VoidCallback? onBack;
|
||||
|
||||
@override
|
||||
State<SettingsPage> createState() => _SettingsPageState();
|
||||
}
|
||||
@@ -209,6 +211,8 @@ class _SettingsPageState extends State<SettingsPage> {
|
||||
late final TextEditingController endpoint;
|
||||
late final TextEditingController model;
|
||||
final apiKey = TextEditingController();
|
||||
bool _testingConnection = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@@ -226,7 +230,20 @@ class _SettingsPageState extends State<SettingsPage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => AppPage(
|
||||
appBar: AppBar(title: const Text('学习设置')),
|
||||
appBar: AppBar(
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
tooltip: "返回",
|
||||
onPressed: () {
|
||||
if (widget.onBack != null) {
|
||||
widget.onBack!();
|
||||
} else if (Navigator.canPop(context)) {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
},
|
||||
),
|
||||
title: const Text('学习设置'),
|
||||
),
|
||||
child: SpacedColumn(
|
||||
spacing: 4,
|
||||
children: [
|
||||
@@ -350,17 +367,49 @@ class _SettingsPageState extends State<SettingsPage> {
|
||||
},
|
||||
),
|
||||
SecondaryButton(
|
||||
label: '测试连接',
|
||||
label: _testingConnection ? '正在测试连接...' : '测试连接',
|
||||
onPressed: _testingConnection
|
||||
? null
|
||||
: () async {
|
||||
setState(() => _testingConnection = true);
|
||||
final result = await AiService.instance.testConnection(
|
||||
provider: widget.state.aiProvider,
|
||||
endpoint: endpoint.text,
|
||||
model: model.text,
|
||||
explicitApiKey: apiKey.text,
|
||||
);
|
||||
if (!mounted) return;
|
||||
setState(() => _testingConnection = false);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(result.message),
|
||||
backgroundColor:
|
||||
result.ok ? AppColors.green : Colors.redAccent,
|
||||
duration: const Duration(seconds: 4),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
SecondaryButton(
|
||||
label: '从配置文件重载 (ai_config.json)',
|
||||
onPressed: () async {
|
||||
final result = await AiService.instance.testConnection(
|
||||
provider: widget.state.aiProvider,
|
||||
endpoint: endpoint.text,
|
||||
model: model.text,
|
||||
);
|
||||
if (!context.mounted) return;
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text(result.message)));
|
||||
final ok = await widget.state.reloadAiConfigFromAsset();
|
||||
if (!mounted) return;
|
||||
if (ok) {
|
||||
setState(() {
|
||||
endpoint.text = widget.state.aiEndpoint;
|
||||
model.text = widget.state.aiModel;
|
||||
});
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('已从 assets/config/ai_config.json 载入配置。'),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('未找到配置文件或解析失败。')),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
const Divider(height: 28),
|
||||
|
||||
Reference in New Issue
Block a user