Browse Source

修改聊天音乐卡片

weicu
tanlongsheng 2 years ago
parent
commit
f651fdf0f8
  1. 9
      lib/modules/chat/bindings/chat_binding.dart
  2. 35
      lib/modules/chat/controllers/chat_controller.dart
  3. 90
      lib/modules/chat/views/chat_music_card.dart
  4. 50
      lib/modules/chat/views/chat_view.dart

9
lib/modules/chat/bindings/chat_binding.dart

@ -1,17 +1,10 @@
import 'package:get/get.dart'; import 'package:get/get.dart';
import '../controllers/chat_controller.dart'; import '../controllers/chat_controller.dart';
import '../../../data/services/speech_impl/azure_asr_service.dart';
import '../../../data/services/speech_impl/azure_tts_service.dart';
import '../../../data/services/asr_service.dart';
import '../../../data/services/tts_service.dart';
import '../../../data/services/volcano_ai_service.dart';
import '../../../data/services/chat_history_service.dart';
class ChatBinding extends Bindings { class ChatBinding extends Bindings {
@override @override
void dependencies() { void dependencies() {
// 注册控制器 // 注册控制器
Get.lazyPut<ChatController>(() => ChatController()); Get.lazyPut<ChatController>(() => ChatController());
} }
} }

35
lib/modules/chat/controllers/chat_controller.dart

@ -2,6 +2,7 @@ import 'dart:async';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:get_storage/get_storage.dart'; import 'package:get_storage/get_storage.dart';
import 'package:just_audio/just_audio.dart';
import '../../../data/services/ai_service.dart'; import '../../../data/services/ai_service.dart';
import '../../../data/services/deapsound_ai_service.dart'; import '../../../data/services/deapsound_ai_service.dart';
import '../../../data/services/kouzi_ai_service.dart'; import '../../../data/services/kouzi_ai_service.dart';
@ -72,6 +73,10 @@ class ChatController extends GetxController {
// 记录最后一次活动时间 // 记录最后一次活动时间
DateTime _lastActivityTime = DateTime.now(); DateTime _lastActivityTime = DateTime.now();
final _player = AudioPlayer();
final RxString audiourl = ''.obs;
final RxBool isPlay = false.obs;
@override @override
Future<void> onInit() async { Future<void> onInit() async {
super.onInit(); super.onInit();
@ -248,6 +253,8 @@ class ChatController extends GetxController {
_historyService.saveHistory(agent.id!, messages.toList()); _historyService.saveHistory(agent.id!, messages.toList());
} }
_player.dispose();
super.onClose(); super.onClose();
} }
@ -345,6 +352,9 @@ class ChatController extends GetxController {
if (chunk is Map) { if (chunk is Map) {
_updateLoadingMessage(data: chunk); _updateLoadingMessage(data: chunk);
if (chunk['musicaudio'] != null) {
play(chunk['musicaudio']);
}
} else { } else {
fullResponse += chunk; fullResponse += chunk;
@ -427,6 +437,31 @@ class ChatController extends GetxController {
} }
} }
// 播放音乐
void play(Map musicaudio) async {
try {
isPlay.value = false;
if (audiourl.value != musicaudio['audiourl']) {
audiourl.value = musicaudio['audiourl'];
await _player.setUrl(musicaudio['audiourl']);
_player.play();
} else {
_player.play();
}
isPlay.value = true;
} catch (e) {
isPlay.value = false;
audiourl.value = '';
Logger.error('加载异常: $e');
}
}
// 暂停播放音乐
void pause() async {
await _player.pause();
isPlay.value = false;
}
// 完成响应 // 完成响应
void _finalizeResponse(String content) { void _finalizeResponse(String content) {
final index = messages.indexWhere((m) => m.isLoading); final index = messages.indexWhere((m) => m.isLoading);

90
lib/modules/chat/views/chat_music_card.dart

@ -0,0 +1,90 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import '../controllers/chat_controller.dart';
class ChatMusicCard extends GetView<ChatController> {
final Map? data;
final bool isDarkMode;
const ChatMusicCard(this.data, this.isDarkMode, {super.key});
@override
Widget build(BuildContext context) {
final Map musiccards = data?['musiccards'].first;
final Map musicaudio = data?['musicaudio'];
return Row(
children: [
Container(
width: 60.w,
height: 60.w,
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6.r),
),
child: Image.network(
musiccards['image'],
fit: BoxFit.cover,
),
),
10.horizontalSpace,
Expanded(
child: Text(
musiccards['name'],
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: isDarkMode ? Colors.white : Colors.black,
fontSize: 16.sp,
height: 1.5,
),
),
),
10.horizontalSpace,
Obx(
() => controller.audiourl == musicaudio['audiourl'] &&
controller.isPlay.value
? GestureDetector(
onTap: () {
controller.pause();
},
child: Container(
width: 38.w,
height: 38.w,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color:
isDarkMode ? Colors.grey[700]! : Colors.grey[300]!,
width: 2,
),
),
child: Icon(
Icons.pause_rounded,
color: isDarkMode ? Colors.white : Colors.black,
),
),
)
: GestureDetector(
onTap: () {
controller.play(musicaudio);
},
child: Container(
width: 38.w,
height: 38.w,
decoration: BoxDecoration(
color: isDarkMode ? Colors.white : Colors.black,
shape: BoxShape.circle,
),
child: Icon(
Icons.play_arrow_rounded,
color: isDarkMode ? Colors.black : Colors.white,
),
),
),
),
],
);
}
}

50
lib/modules/chat/views/chat_view.dart

@ -5,6 +5,7 @@ import 'dart:math';
import '../controllers/chat_controller.dart'; import '../controllers/chat_controller.dart';
import '../models/message_model.dart'; import '../models/message_model.dart';
import '../../../core/theme/app_colors.dart'; import '../../../core/theme/app_colors.dart';
import 'chat_music_card.dart';
class ChatView extends GetView<ChatController> { class ChatView extends GetView<ChatController> {
const ChatView({Key? key}) : super(key: key); const ChatView({Key? key}) : super(key: key);
@ -297,19 +298,7 @@ class ChatView extends GetView<ChatController> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// 消息内容 // 消息内容
if (message.content.isNotEmpty) _buildMessageContent(message, isDarkMode, isUser),
SelectableText(
'${message.content}'.tr,
style: TextStyle(
color: isUser
? Colors.white
: isDarkMode
? Colors.white
: Colors.black,
fontSize: 16.sp,
height: 1.5,
),
),
// 加载中动画 // 加载中动画
if (message.isLoading) if (message.isLoading)
@ -348,6 +337,30 @@ class ChatView extends GetView<ChatController> {
); );
} }
Widget _buildMessageContent(Message message, bool isDarkMode, bool isUser) {
Widget box = const SizedBox();
if (message.content.isNotEmpty) {
box = SelectableText(
message.content.tr,
style: TextStyle(
color: isUser
? Colors.white
: isDarkMode
? Colors.white
: Colors.black,
fontSize: 16.sp,
height: 1.5,
),
);
}
if (message.data != null) {
if (message.data?['musicaudio'] != null) {
box = ChatMusicCard(message.data, isDarkMode);
}
}
return box;
}
// 构建输入区域 // 构建输入区域
Widget _buildInputArea(bool isDarkMode) { Widget _buildInputArea(bool isDarkMode) {
final textController = final textController =
@ -715,21 +728,22 @@ class ChatView extends GetView<ChatController> {
); );
} }
// 格式化时间 // 格式化时间
String _formatTime(DateTime time) { String _formatTime(DateTime time) {
final now = DateTime.now(); final now = DateTime.now();
final today = DateTime(now.year, now.month, now.day); final today = DateTime(now.year, now.month, now.day);
//final yesterday = today.subtract(const Duration(days: 1)); //final yesterday = today.subtract(const Duration(days: 1));
final messageDate = DateTime(time.year, time.month, time.day); final messageDate = DateTime(time.year, time.month, time.day);
String timeStr = '${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}'; String timeStr =
'${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}';
if (messageDate == today) { if (messageDate == today) {
return timeStr; // 只显示时间,如 "14:30" return timeStr; // 只显示时间,如 "14:30"
} }
// else if (messageDate == yesterday) { // else if (messageDate == yesterday) {
// return 'Yesterday $timeStr'; // 如 "Yesterday 14:30" // return 'Yesterday $timeStr'; // 如 "Yesterday 14:30"
// } // }
else { else {
// 国际通用日期格式 "MM-dd HH:mm" // 国际通用日期格式 "MM-dd HH:mm"
return '${time.month.toString().padLeft(2, '0')}-${time.day.toString().padLeft(2, '0')} $timeStr'; return '${time.month.toString().padLeft(2, '0')}-${time.day.toString().padLeft(2, '0')} $timeStr';

Loading…
Cancel
Save