merge commit
This commit is contained in:
@@ -68,7 +68,7 @@ public class MainActivity extends FlutterActivity implements INativeNuiCallback
|
||||
.setMethodCallHandler((call, result) -> {
|
||||
Map<String, Object> args = (Map<String, Object>) call.arguments;
|
||||
switch (call.method) {
|
||||
case "start":
|
||||
case "startTts":
|
||||
Object isChinese = args.get("isChinese");
|
||||
if (isChinese == null || isChinese.toString().isBlank()) {
|
||||
return;
|
||||
@@ -76,17 +76,17 @@ public class MainActivity extends FlutterActivity implements INativeNuiCallback
|
||||
boolean isSuccess = startTts(Boolean.parseBoolean(isChinese.toString()));
|
||||
result.success(isSuccess);
|
||||
break;
|
||||
case "send":
|
||||
case "sendTts":
|
||||
Object textArg = args.get("text");
|
||||
if (textArg == null || textArg.toString().isBlank()) {
|
||||
return;
|
||||
}
|
||||
sendTts(textArg.toString());
|
||||
break;
|
||||
case "complete":
|
||||
case "completeTts":
|
||||
completeTts();
|
||||
break;
|
||||
case "stop":
|
||||
case "stopTts":
|
||||
stopTts();
|
||||
break;
|
||||
default:
|
||||
@@ -97,10 +97,10 @@ public class MainActivity extends FlutterActivity implements INativeNuiCallback
|
||||
asrMethodChannel = new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), ASR_CHANNEL);
|
||||
asrMethodChannel.setMethodCallHandler((call, result) -> {
|
||||
switch (call.method) {
|
||||
case "start":
|
||||
case "startAsr":
|
||||
startAsr();
|
||||
break;
|
||||
case "stop":
|
||||
case "stopAsr":
|
||||
stopAsr();
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -18,6 +18,7 @@ class PartScreen extends StatefulWidget {
|
||||
class _PartScreenState extends State<PartScreen> {
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
bool _isInitialized = false;
|
||||
int _lastMessageCount = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -97,9 +98,13 @@ class _PartScreenState extends State<PartScreen> {
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: Consumer<MessageService>(
|
||||
builder: (context, messageService, child) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_scrollToBottom();
|
||||
});
|
||||
final messageCount = messageService.messages.length;
|
||||
if (messageCount > _lastMessageCount) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_scrollToBottom();
|
||||
});
|
||||
}
|
||||
_lastMessageCount = messageCount;
|
||||
return Container(
|
||||
width: chatWidth,
|
||||
constraints: BoxConstraints(
|
||||
|
||||
@@ -9,8 +9,7 @@ class VehicleCommandService {
|
||||
|
||||
Future<VehicleCommandResponse?> getCommandFromText(String text) async {
|
||||
try {
|
||||
final uri = Uri.parse(
|
||||
'http://143.64.185.20:18606/control');
|
||||
final uri = Uri.parse('http://143.64.185.20:18606/control');
|
||||
|
||||
final response = await http.post(
|
||||
uri,
|
||||
@@ -24,9 +23,9 @@ class VehicleCommandService {
|
||||
final commandList = decoded['commands'];
|
||||
List<VehicleCommand> vehicleCommandList = (commandList as List)
|
||||
.map<VehicleCommand>((item) => VehicleCommand.fromString(
|
||||
item['command'] as String,
|
||||
item['params'] as Map<String, dynamic>?,
|
||||
item['error'] ?? ''))
|
||||
item['command'] as String,
|
||||
item['params'] as Map<String, dynamic>?,
|
||||
item['error'] ?? ''))
|
||||
.toList();
|
||||
return VehicleCommandResponse(tips: tips, commands: vehicleCommandList);
|
||||
} else {
|
||||
@@ -40,30 +39,23 @@ class VehicleCommandService {
|
||||
}
|
||||
}
|
||||
|
||||
// 执行车辆控制命令的方法
|
||||
Future<bool> executeCommand(VehicleCommand command) async {
|
||||
Future<String> getControlResponse(List<String> successCommandList) async {
|
||||
String reply = "";
|
||||
try {
|
||||
final uri = Uri.parse('http://143.64.185.20:18607/executeCommand');
|
||||
|
||||
final uri = Uri.parse('http://143.64.185.20:18606/control_resp');
|
||||
final response = await http.post(
|
||||
uri,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: json.encode({
|
||||
'command': command.commandString, // 使用getter转换为字符串
|
||||
'params': command.params,
|
||||
}),
|
||||
body: json.encode(successCommandList),
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
print('命令执行成功: ${command.commandString}');
|
||||
return true;
|
||||
return response.body;
|
||||
} else {
|
||||
print('命令执行失败: ${response.statusCode}, ${response.body}');
|
||||
return false;
|
||||
print("请求控制回复失败: ${response.statusCode}");
|
||||
}
|
||||
} catch (e) {
|
||||
print('命令执行出错: $e');
|
||||
return false;
|
||||
print('请求控制回复异常: $e');
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,10 @@ class MessageService extends ChangeNotifier {
|
||||
_asrChannel.setMethodCallHandler((call) async {
|
||||
switch (call.method) {
|
||||
case "onAsrResult":
|
||||
replaceMessage(id: _latestUserMessageId!, text: call.arguments);
|
||||
replaceMessage(
|
||||
id: _latestUserMessageId!,
|
||||
text: call.arguments,
|
||||
status: MessageStatus.normal);
|
||||
break;
|
||||
case "onAsrStop":
|
||||
int index = findMessageIndexById(_latestUserMessageId!);
|
||||
@@ -45,8 +48,6 @@ class MessageService extends ChangeNotifier {
|
||||
removeMessageById(_latestUserMessageId!);
|
||||
return;
|
||||
}
|
||||
replaceMessage(
|
||||
id: _latestUserMessageId!, status: MessageStatus.normal);
|
||||
if (_asrCompleter != null && !_asrCompleter!.isCompleted) {
|
||||
_asrCompleter!.complete(messages.last.text);
|
||||
}
|
||||
@@ -60,7 +61,7 @@ class MessageService extends ChangeNotifier {
|
||||
// final AudioRecorderService _audioService = AudioRecorderService();
|
||||
// final VoiceRecognitionService _recognitionService = VoiceRecognitionService();
|
||||
final TextClassificationService _classificationService =
|
||||
TextClassificationService();
|
||||
TextClassificationService();
|
||||
final VehicleCommandService _vehicleCommandService = VehicleCommandService();
|
||||
|
||||
final List<ChatMessage> _messages = [];
|
||||
@@ -107,9 +108,8 @@ class MessageService extends ChangeNotifier {
|
||||
_latestAssistantMessageId = null;
|
||||
_isReplyAborted = false;
|
||||
changeState(MessageServiceState.recording);
|
||||
addMessage("", true, MessageStatus.listening);
|
||||
_latestUserMessageId = messages.last.id;
|
||||
_asrChannel.invokeMethod("start");
|
||||
_latestUserMessageId = addMessage("", true, MessageStatus.listening);
|
||||
_asrChannel.invokeMethod("startAsr");
|
||||
} catch (e) {
|
||||
print('录音开始出错: $e');
|
||||
}
|
||||
@@ -120,14 +120,16 @@ class MessageService extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void addMessage(String text, bool isUser, MessageStatus status) {
|
||||
String addMessage(String text, bool isUser, MessageStatus status) {
|
||||
String uuid = Uuid().v1();
|
||||
_messages.add(ChatMessage(
|
||||
id: Uuid().v1(),
|
||||
id: uuid,
|
||||
text: text,
|
||||
isUser: isUser,
|
||||
timestamp: DateTime.now(),
|
||||
status: status));
|
||||
notifyListeners();
|
||||
return uuid;
|
||||
}
|
||||
|
||||
Future<void> stopAndProcessVoiceInput() async {
|
||||
@@ -137,7 +139,7 @@ class MessageService extends ChangeNotifier {
|
||||
}
|
||||
try {
|
||||
changeState(MessageServiceState.recognizing);
|
||||
_asrChannel.invokeMethod("stop");
|
||||
_asrChannel.invokeMethod("stopAsr");
|
||||
_asrCompleter = Completer<String>();
|
||||
final recognizedText = await _asrCompleter!.future;
|
||||
// final audioData = await _audioService.stopRecording();
|
||||
@@ -194,8 +196,7 @@ class MessageService extends ChangeNotifier {
|
||||
}
|
||||
|
||||
Future<void> reply(String text) async {
|
||||
addMessage("", false, MessageStatus.thinking);
|
||||
_latestAssistantMessageId = messages.last.id;
|
||||
_latestAssistantMessageId = addMessage("", false, MessageStatus.thinking);
|
||||
bool isChinese = CommonUtil.containChinese(text);
|
||||
try {
|
||||
if (_isReplyAborted) {
|
||||
@@ -226,7 +227,7 @@ class MessageService extends ChangeNotifier {
|
||||
return;
|
||||
}
|
||||
final vehicleCommandResponse =
|
||||
await _vehicleCommandService.getCommandFromText(text);
|
||||
await _vehicleCommandService.getCommandFromText(text);
|
||||
if (vehicleCommandResponse == null) {
|
||||
if (_isReplyAborted) {
|
||||
return;
|
||||
@@ -249,9 +250,11 @@ class MessageService extends ChangeNotifier {
|
||||
if (!_isReplyAborted) {
|
||||
if (await TtsUtil.start(isChinese) == true) {
|
||||
TtsUtil.send(vehicleCommandResponse.tips!);
|
||||
Future.delayed(const Duration(milliseconds: 300), () => TtsUtil.complete());
|
||||
}
|
||||
}
|
||||
bool containOpenAC = false;
|
||||
List<String> successCommandList = [];
|
||||
for (var command in vehicleCommandResponse.commands) {
|
||||
if (_isReplyAborted) {
|
||||
return;
|
||||
@@ -263,11 +266,15 @@ class MessageService extends ChangeNotifier {
|
||||
if (command.type == VehicleCommandType.openAC) {
|
||||
containOpenAC = true;
|
||||
}
|
||||
bool isSuccess;
|
||||
if (containOpenAC && command.type == VehicleCommandType.changeACTemp) {
|
||||
await Future.delayed(const Duration(milliseconds: 2000),
|
||||
() => processCommand(command, isChinese));
|
||||
isSuccess = await Future.delayed(const Duration(milliseconds: 2000),
|
||||
() => processCommand(command, isChinese));
|
||||
} else {
|
||||
await processCommand(command, isChinese);
|
||||
isSuccess = await processCommand(command, isChinese);
|
||||
}
|
||||
if (isSuccess) {
|
||||
successCommandList.add(command.type.name);
|
||||
}
|
||||
}
|
||||
replaceMessage(
|
||||
@@ -275,12 +282,21 @@ class MessageService extends ChangeNotifier {
|
||||
text: vehicleCommandResponse.tips!,
|
||||
status: MessageStatus.normal);
|
||||
notifyListeners();
|
||||
if (_isReplyAborted || successCommandList.isEmpty) {
|
||||
return;
|
||||
}
|
||||
String controlResponse =
|
||||
await _vehicleCommandService.getControlResponse(successCommandList);
|
||||
if (_isReplyAborted || controlResponse.isEmpty) {
|
||||
return;
|
||||
}
|
||||
addMessage(controlResponse, false, MessageStatus.normal);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> processCommand(VehicleCommand command, bool isChinese) async {
|
||||
String msg;
|
||||
MessageStatus status;
|
||||
Future<bool> processCommand(VehicleCommand command, bool isChinese) async {
|
||||
String msg = "";
|
||||
MessageStatus status = MessageStatus.normal;
|
||||
final (isSuccess, result) = await CommandService.executeCommand(
|
||||
command.type,
|
||||
params: command.params);
|
||||
@@ -299,19 +315,17 @@ class MessageService extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isSuccess) {
|
||||
msg = isChinese
|
||||
? "为您执行\"${command.type.chinese}\"成功"
|
||||
: "Execute \"${command.type.english}\" successful";
|
||||
status = MessageStatus.success;
|
||||
} else {
|
||||
if (!isSuccess) {
|
||||
msg = isChinese
|
||||
? "很抱歉,\"${command.type.chinese}\"失败"
|
||||
: "Sorry, execute \"${command.type.english}\" unsuccessfully";
|
||||
status = MessageStatus.failure;
|
||||
}
|
||||
}
|
||||
addMessage(msg, false, status);
|
||||
if (msg.isNotEmpty) {
|
||||
addMessage(msg, false, status);
|
||||
}
|
||||
return isSuccess;
|
||||
}
|
||||
|
||||
Future<void> answerWrongQuestion(bool isChinese) async {
|
||||
|
||||
@@ -10,18 +10,18 @@ class TtsUtil {
|
||||
}
|
||||
|
||||
static Future<bool> start(bool isChinese) async {
|
||||
return await execute('start', {'isChinese': isChinese});
|
||||
return await execute('startTts', {'isChinese': isChinese});
|
||||
}
|
||||
|
||||
static Future<void> send(String text) async {
|
||||
await execute('send', {'text': text});
|
||||
await execute('sendTts', {'text': text});
|
||||
}
|
||||
|
||||
static Future<void> complete() async {
|
||||
await execute('complete');
|
||||
await execute('completeTts');
|
||||
}
|
||||
|
||||
static Future<void> stop() async {
|
||||
await execute('stop');
|
||||
await execute('stopTts');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ class _FloatingIconState extends State<FloatingIcon>
|
||||
}
|
||||
|
||||
void _showFullScreen() async {
|
||||
_hidePartScreen();
|
||||
await Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const FullScreen(),
|
||||
|
||||
Reference in New Issue
Block a user