You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

208 lines
6.7 KiB

import 'package:flutter/material.dart';
import 'device_category.dart';
/// 功能模块(agent)定义。
///
/// AI 页与广场页共用同一份注册表:广场展示全部,AI 页只展示用户启用的那些,
/// 顺序由 [AgentModuleService] 持久化。新增 agent 只需往 [AgentModules.all]
/// 里加一条,两个页面自动生效。
class AgentModule {
const AgentModule({
required this.id,
required this.title,
required this.icon,
required this.gradient,
this.subtitle,
this.requiresDevice = false,
this.comingSoon = false,
});
/// 唯一标识,持久化时存的就是它,改名会导致用户已有配置失效
final String id;
/// i18n key,展示时 `.tr`(不是中文文案本身)
final String title;
/// i18n key,展示时 `.tr`
final String? subtitle;
final IconData icon;
/// 卡片图标底色渐变(两个色值)
final List<Color> gradient;
/// 是否依赖设备连接:未连接时卡片置灰,点击提示连接设备
final bool requiresDevice;
/// 尚未实现的占位模块:可以加到 AI 页排版,但点击只提示"敬请期待"
final bool comingSoon;
}
/// 全部可用模块的注册表
class AgentModules {
AgentModules._();
// ---------- 已实现(对应现有路由) ----------
static const String meeting = 'meeting';
static const String simultaneous = 'simultaneous';
static const String faceToFace = 'faceToFace';
static const String call = 'call';
static const String audioVideo = 'audioVideo';
static const String callRecording = 'callRecording';
static const String fieldRecording = 'fieldRecording';
/// EMAI 助手:原来 AI 页底部那颗悬浮球,改成广场里的一个正式 agent
static const String emaiAssistant = 'emaiAssistant';
static const String textTranslation = 'textTranslation';
static const String pictureTranslation = 'pictureTranslation';
// ---------- 规划中(占位,方便测试增删) ----------
static const String englishChat = 'englishChat';
static const String englishStudy = 'englishStudy';
static const String kidsStory = 'kidsStory';
static const List<AgentModule> all = [
AgentModule(
id: meeting,
title: 'agentMeeting',
subtitle: 'agentMeetingDesc',
icon: Icons.groups_2,
gradient: [Color(0xFFAB47BC), Color(0xFFEC407A)],
),
AgentModule(
id: emaiAssistant,
title: 'agentEmai',
subtitle: 'agentEmaiDesc',
icon: Icons.auto_awesome,
gradient: [Color(0xFF5B8DEF), Color(0xFF7E57C2)],
),
AgentModule(
id: simultaneous,
title: 'agentSimultaneous',
subtitle: 'agentSimultaneousDesc',
icon: Icons.record_voice_over,
gradient: [Color(0xFF4CAF50), Color(0xFF009688)],
),
AgentModule(
id: faceToFace,
title: 'agentFaceToFace',
subtitle: 'agentFaceToFaceDesc',
icon: Icons.forum,
gradient: [Color(0xFF42A5F5), Color(0xFF1E88E5)],
),
AgentModule(
id: callRecording,
title: 'agentCallRecording',
subtitle: 'agentCallRecordingDesc',
icon: Icons.fiber_manual_record,
gradient: [Color(0xFFEF5350), Color(0xFFE53935)],
requiresDevice: true,
),
AgentModule(
id: fieldRecording,
title: 'agentFieldRecording',
// 有设备走设备录音通路,没设备退回手机麦克风,两种情况都能用
subtitle: 'agentFieldRecordingDesc',
icon: Icons.mic,
gradient: [Color(0xFF26C6DA), Color(0xFF00838F)],
),
AgentModule(
id: call,
title: 'agentCall',
subtitle: 'agentCallDesc',
icon: Icons.phone_in_talk,
gradient: [Color(0xFFFFA726), Color(0xFFFB8C00)],
requiresDevice: true,
),
AgentModule(
id: audioVideo,
title: 'agentAudioVideo',
subtitle: 'agentAudioVideoDesc',
// 放映机图标:这个功能是音视频内容翻译,用投影/放映的意象更贴切
icon: Icons.slideshow,
gradient: [Color(0xFF5C6BC0), Color(0xFF3949AB)],
),
AgentModule(
id: textTranslation,
title: 'agentTextTranslation',
subtitle: 'agentTextTranslationDesc',
icon: Icons.translate,
gradient: [Color(0xFF26A69A), Color(0xFF00796B)],
),
AgentModule(
id: pictureTranslation,
title: 'agentPictureTranslation',
subtitle: 'agentPictureTranslationDesc',
icon: Icons.image_search,
gradient: [Color(0xFFEC407A), Color(0xFFAD1457)],
),
AgentModule(
id: englishChat,
title: 'agentEnglishChat',
subtitle: 'agentEnglishChatDesc',
icon: Icons.chat_bubble_outline,
gradient: [Color(0xFF7E57C2), Color(0xFF5E35B1)],
comingSoon: true,
),
AgentModule(
id: englishStudy,
title: 'agentEnglishStudy',
subtitle: 'agentEnglishStudyDesc',
icon: Icons.menu_book,
gradient: [Color(0xFF29B6F6), Color(0xFF0288D1)],
comingSoon: true,
),
AgentModule(
id: kidsStory,
title: 'agentKidsStory',
subtitle: 'agentKidsStoryDesc',
icon: Icons.auto_stories,
gradient: [Color(0xFFFF7043), Color(0xFFF4511E)],
comingSoon: true,
),
];
/// AI 页首次进入时的默认模块。
///
/// 没连过设备也能用的三个(都只依赖手机本身):语音记录助手、EMAI助手、现场录音。
/// 依赖设备的功能等连上对应设备后由 [defaultsForCategory] 自动补进来。
static const List<String> defaultEnabled = [
// 网格区(左大 + 右上下两小)
call,
simultaneous,
faceToFace,
// 并排方块
meeting,
audioVideo,
// 往下是整行横条,现场录音是第一行
fieldRecording,
callRecording,
textTranslation,
pictureTranslation,
emaiAssistant,
];
/// 各设备品类**第一次连接成功**时要铺到 AI 页的默认功能与顺序。
///
/// key 用的是 [DeviceCategories] 的品类 id。只在该品类首次连接时生效一次
/// (由 AgentModuleService 记录已应用过的品类),之后用户怎么增删排序都不再覆盖。
static const Map<String, List<String>> defaultsByCategory = {
// AI手机支架 / AI录音卡片:只有录音相关能力,AI 页就只留这三个
DeviceCategories.phoneHolder: [meeting, fieldRecording, callRecording],
DeviceCategories.noteCard: [meeting, fieldRecording, callRecording],
// AI耳机(恒玄):通话 + 翻译整套都能跑,铺开全量默认编排
DeviceCategories.earphone: defaultEnabled,
};
static List<String> defaultsForCategory(String? categoryId) {
if (categoryId == null) return const [];
return defaultsByCategory[categoryId] ?? const [];
}
static AgentModule? byId(String id) {
for (final m in all) {
if (m.id == id) return m;
}
return null;
}
}