|
|
|
@ -1,9 +1,12 @@ |
|
|
|
import 'package:flutter/material.dart'; |
|
|
|
import 'package:get/get.dart'; |
|
|
|
import 'package:intl/intl.dart'; |
|
|
|
import 'dart:io'; |
|
|
|
|
|
|
|
import '../controllers/agent_controller.dart'; |
|
|
|
|
|
|
|
/// 消息气泡组件 |
|
|
|
class MessageBubble extends StatelessWidget { |
|
|
|
class MessageBubble extends GetView<AgentController> { |
|
|
|
final bool isUser; |
|
|
|
final String message; |
|
|
|
final DateTime timestamp; |
|
|
|
@ -199,8 +202,14 @@ class MessageBubble extends StatelessWidget { |
|
|
|
//音乐卡片 |
|
|
|
return _buildMusicItem(context, musicName, musicUrl, musicSinger); |
|
|
|
} else if (mate!.keys.contains('card_musiclist')) { |
|
|
|
final rawList = mate!['card_musiclist']['musics'] as List; |
|
|
|
final playlist = |
|
|
|
rawList.map((e) => Map<String, dynamic>.from(e)).toList(); |
|
|
|
// final playlist = |
|
|
|
// mate!['card_musiclist']['musics'] as List<Map<String, String>>; |
|
|
|
|
|
|
|
//音乐播放列表 |
|
|
|
return _buildMusicContent(context); |
|
|
|
return _buildMusicContent(context, playlist); |
|
|
|
} else if (mate!.keys.contains('card_weather')) { |
|
|
|
//天气 |
|
|
|
return _buildWeatherContent(context); |
|
|
|
@ -250,11 +259,12 @@ class MessageBubble extends StatelessWidget { |
|
|
|
} |
|
|
|
|
|
|
|
/// 构建音乐内容卡片 |
|
|
|
Widget _buildMusicContent(BuildContext context) { |
|
|
|
Widget _buildMusicContent( |
|
|
|
BuildContext context, List<Map<String, dynamic>> playlist) { |
|
|
|
return Column( |
|
|
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
|
|
children: [ |
|
|
|
Text( |
|
|
|
const Text( |
|
|
|
'以下是一些推荐的音乐:', |
|
|
|
style: TextStyle( |
|
|
|
color: Colors.black87, |
|
|
|
@ -301,18 +311,22 @@ class MessageBubble extends StatelessWidget { |
|
|
|
), |
|
|
|
const SizedBox(height: 10), |
|
|
|
|
|
|
|
// 歌曲示例 |
|
|
|
_buildMusicItem( |
|
|
|
context, |
|
|
|
'雨声与钢琴曲', |
|
|
|
"", |
|
|
|
'纯音乐', |
|
|
|
), |
|
|
|
Divider(height: 1, thickness: 1, color: Colors.grey[100]), |
|
|
|
_buildMusicItem(context, 'Rainy Day', "", 'Coldplay'), |
|
|
|
Divider(height: 1, thickness: 1, color: Colors.grey[100]), |
|
|
|
_buildMusicItem(context, '雨天的爵士咖啡馆', "", '爵士合集'), |
|
|
|
// 动态生成音乐条目 |
|
|
|
...playlist.asMap().entries.map((entry) { |
|
|
|
final index = entry.key; |
|
|
|
final item = entry.value; |
|
|
|
final name = item["name"] ?? "未知歌曲"; |
|
|
|
final url = item["url"] ?? ""; |
|
|
|
final singer = item["sgener"] ?? "未知歌手"; |
|
|
|
|
|
|
|
return Column( |
|
|
|
children: [ |
|
|
|
_buildMusicItem(context, name, url, singer), |
|
|
|
if (index != playlist.length - 1) |
|
|
|
Divider(height: 1, thickness: 1, color: Colors.grey[100]), |
|
|
|
], |
|
|
|
); |
|
|
|
}).toList(), |
|
|
|
const SizedBox(height: 8), |
|
|
|
Center( |
|
|
|
child: TextButton( |
|
|
|
@ -507,6 +521,8 @@ class MessageBubble extends StatelessWidget { |
|
|
|
/// 构建音乐项目 |
|
|
|
Widget _buildMusicItem( |
|
|
|
BuildContext context, String name, String url, String singer) { |
|
|
|
final controller = Get.find<AgentController>(); // 获取控制器 |
|
|
|
controller.musicStatus(); //刷新状态 |
|
|
|
return Padding( |
|
|
|
padding: const EdgeInsets.symmetric(vertical: 8), |
|
|
|
child: Row( |
|
|
|
@ -550,14 +566,35 @@ class MessageBubble extends StatelessWidget { |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
IconButton( |
|
|
|
onPressed: () {}, |
|
|
|
icon: |
|
|
|
Icon(Icons.play_circle, color: Theme.of(context).primaryColor), |
|
|
|
padding: EdgeInsets.zero, |
|
|
|
constraints: BoxConstraints(), |
|
|
|
iconSize: 24, |
|
|
|
), |
|
|
|
Obx(() { |
|
|
|
final isThisPlaying = controller.isPlaying.value && |
|
|
|
controller.currentUrl.value == url; |
|
|
|
|
|
|
|
return IconButton( |
|
|
|
onPressed: () { |
|
|
|
if (controller.isPlaying.value) { |
|
|
|
if (controller.currentUrl.value == url) { |
|
|
|
controller.musicPause(); |
|
|
|
} else { |
|
|
|
controller.musicPlay(url); |
|
|
|
} |
|
|
|
} else { |
|
|
|
if (controller.currentUrl.value == url) { |
|
|
|
controller.musicResume(); |
|
|
|
} else { |
|
|
|
controller.musicPlay(url); |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
icon: Icon( |
|
|
|
isThisPlaying ? Icons.pause_circle : Icons.play_circle, |
|
|
|
color: Theme.of(context).primaryColor, |
|
|
|
), |
|
|
|
padding: EdgeInsets.zero, |
|
|
|
constraints: BoxConstraints(), |
|
|
|
iconSize: 24, |
|
|
|
); |
|
|
|
}), |
|
|
|
], |
|
|
|
), |
|
|
|
); |
|
|
|
|