feat: M2.1 客户端骨架、BLE 修复、仓库整理与现状板
- BLE: 修复 BlueZ LocalName 与 Includes 冲突,串行注册与退避 - HTTP: 语音对话补 Live2D talking 标志与 session;Web 补 X-Session-Id - Flutter: 角色/对话/模型页 + API,Gradle/依赖升级,麦克风权限 - 文档: 新增 docs/STATUS.md,校准 CLAUDE/PROGRESS/README - 清理: 移除根目录截图与临时模型,运维脚本迁入 scripts/device
This commit is contained in:
@@ -2,6 +2,7 @@ import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../models/video_item.dart';
|
||||
@@ -80,6 +81,34 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
padding: const EdgeInsets.all(AppSpacing.md),
|
||||
children: [
|
||||
Card(
|
||||
child: Column(
|
||||
children: [
|
||||
ListTile(
|
||||
leading: const Icon(Icons.memory_rounded),
|
||||
title: const Text('模型管理'),
|
||||
subtitle: const Text('下载 / 切换 / 删除 AI 模型'),
|
||||
trailing: const Icon(Icons.chevron_right_rounded),
|
||||
onTap: () => context.push('/settings/models'),
|
||||
),
|
||||
const Divider(height: 1),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.bolt_rounded),
|
||||
title: const Text('状态机触发'),
|
||||
trailing: const Icon(Icons.chevron_right_rounded),
|
||||
onTap: () => context.push('/settings/trigger'),
|
||||
),
|
||||
const Divider(height: 1),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.bug_report_rounded),
|
||||
title: const Text('调试日志'),
|
||||
trailing: const Icon(Icons.chevron_right_rounded),
|
||||
onTap: () => context.push('/settings/debug'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppSpacing.lg),
|
||||
Card(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(AppSpacing.md),
|
||||
@@ -464,9 +493,17 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||
Map<String, dynamic>.from(results[0] as Map<String, dynamic>);
|
||||
final available =
|
||||
Map<String, dynamic>.from(results[1] as Map<String, dynamic>);
|
||||
// M2.1: configs 为 {filename, character} 对象列表;兼容旧版纯字符串列表
|
||||
_availableConfigs =
|
||||
(available['configs'] as List<dynamic>? ?? const <dynamic>[])
|
||||
.map((item) => item.toString())
|
||||
.map((item) {
|
||||
if (item is String) return item;
|
||||
if (item is Map) {
|
||||
return item['filename']?.toString() ?? item.toString();
|
||||
}
|
||||
return item.toString();
|
||||
})
|
||||
.where((name) => name.isNotEmpty)
|
||||
.toList(growable: false);
|
||||
_activeConfig = available['active']?.toString();
|
||||
_applyDisplayConfig(Map<String, dynamic>.from(
|
||||
|
||||
Reference in New Issue
Block a user