Files
ShowenV2/clients/flutter/lib/models/character_pack.dart
XiuchengWu 6f7e24db63 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
2026-07-09 12:41:34 +08:00

93 lines
2.4 KiB
Dart

class CharacterPack {
const CharacterPack({
required this.filename,
required this.name,
required this.characterType,
required this.renderType,
this.live2dModel,
});
final String filename;
final String name;
final String characterType;
final String renderType;
final String? live2dModel;
bool get isLive2d => renderType.toLowerCase() == 'live2d';
String get typeLabel {
switch (characterType.toLowerCase()) {
case 'human':
return '数字人';
case 'singer':
return '歌姬';
case 'live2d':
return 'Live2D';
case 'pet':
default:
return '宠物';
}
}
IconDataLike get iconHint {
switch (characterType.toLowerCase()) {
case 'human':
return IconDataLike.person;
case 'singer':
return IconDataLike.mic;
case 'live2d':
return IconDataLike.sparkle;
default:
return IconDataLike.pets;
}
}
factory CharacterPack.fromJson(Map<String, dynamic> json) {
final character = json['character'];
final Map<String, dynamic> charMap = character is Map
? Map<String, dynamic>.from(character)
: const <String, dynamic>{};
final filename = json['filename']?.toString() ?? '';
return CharacterPack(
filename: filename,
name: charMap['name']?.toString().isNotEmpty == true
? charMap['name'].toString()
: filename,
characterType: charMap['character_type']?.toString() ?? 'pet',
renderType: charMap['render_type']?.toString() ?? 'video',
live2dModel: charMap['live2d_model']?.toString(),
);
}
}
/// Avoid importing Flutter material in pure model unit tests.
enum IconDataLike { pets, person, mic, sparkle }
class AvailableConfigs {
const AvailableConfigs({
required this.configs,
required this.active,
});
final List<CharacterPack> configs;
final String active;
factory AvailableConfigs.fromJson(Map<String, dynamic> json) {
final raw = json['configs'];
final list = <CharacterPack>[];
if (raw is List) {
for (final item in raw) {
if (item is Map<String, dynamic>) {
list.add(CharacterPack.fromJson(item));
} else if (item is Map) {
list.add(CharacterPack.fromJson(Map<String, dynamic>.from(item)));
}
}
}
return AvailableConfigs(
configs: list,
active: json['active']?.toString() ?? '',
);
}
}