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.

179 lines
5.3 KiB

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import '../controllers/translation_controller.dart';
import 'dart:async';
import '../models/translation_models.dart'; // 添加异步支持
class TranslationAudioHistoryController extends GetxController {
// 引用主翻译控制器,以访问历史记录数据
final TranslationController translationController =
Get.find<TranslationController>();
// 按日期分组的历史记录
final Rx<Map<String, List<TranslationItem>>> groupedHistory =
Rx<Map<String, List<TranslationItem>>>({});
// 排序后的日期列表
final RxList<String> sortedDates = <String>[].obs;
// 会话映射表,用于存储每个会话的所有项目
final Rx<Map<String, List<TranslationItem>>> sessionMap =
Rx<Map<String, List<TranslationItem>>>({});
// 加载状态
final isLoading = true.obs;
@override
void onInit() {
super.onInit();
// 确保所有翻译操作都已停止
translationController.stopAll();
// 异步加载数据,避免阻塞主线程
loadHistoryData();
}
// 异步加载历史数据
Future<void> loadHistoryData() async {
isLoading.value = true;
// 使用 compute 或 Future.microtask 在后台处理数据
await Future.microtask(() {
_groupHistoryByDate();
_groupHistoryBySession();
});
isLoading.value = false;
}
// 按日期对历史记录进行分组
void _groupHistoryByDate() {
final Map<String, List<TranslationItem>> newGroupedHistory = {};
// 获取完整的历史记录,而不仅仅是当前显示的记录
final List<TranslationItem> allHistory =
translationController.getAllHistory();
// 筛选出每个会话的第一条记录
final List<TranslationItem> firstItemsOfSessions =
allHistory.where((item) => item.isFirstInSession).toList();
for (var item in firstItemsOfSessions) {
final DateTime date = item.timestamp;
String key;
final now = DateTime.now();
final today = DateTime(now.year, now.month, now.day);
final itemDate = DateTime(date.year, date.month, date.day);
if (itemDate == today) {
key = 'TODAY';
} else {
key = DateFormat('yyyy-MM-dd').format(date);
}
if (!newGroupedHistory.containsKey(key)) {
newGroupedHistory[key] = [];
}
newGroupedHistory[key]!.add(item);
}
// 对每个日期组内的项目按时间倒序排序
newGroupedHistory.forEach((key, items) {
items.sort((a, b) => b.timestamp.compareTo(a.timestamp));
});
// 更新分组后的历史记录
groupedHistory.value = newGroupedHistory;
// 按日期排序
final List<String> dates = newGroupedHistory.keys.toList()
..sort((a, b) {
if (a == 'TODAY') return -1;
if (b == 'TODAY') return 1;
if (a == '1 DAY AGO') return -1;
if (b == '1 DAY AGO') return 1;
if (a == '2 DAYS AGO') return -1;
if (b == '2 DAYS AGO') return 1;
return b.compareTo(a); // 降序排列其他日期
});
sortedDates.value = dates;
}
// 按会话ID对历史记录进行分组
void _groupHistoryBySession() {
final Map<String, List<TranslationItem>> newSessionMap = {};
// 获取完整的历史记录进行会话分组
final List<TranslationItem> allHistory =
translationController.getAllHistory();
for (var item in allHistory) {
if (!newSessionMap.containsKey(item.sessionId)) {
newSessionMap[item.sessionId] = [];
}
newSessionMap[item.sessionId]!.add(item);
}
// 对每个会话内的项目按时间升序排序
newSessionMap.forEach((key, items) {
items.sort((a, b) => a.timestamp.compareTo(b.timestamp));
});
// 更新会话映射表
sessionMap.value = newSessionMap;
}
// 获取指定会话的所有翻译项
List<TranslationItem> getSessionItems(String sessionId) {
return sessionMap.value[sessionId] ?? [];
}
// 播放翻译项
void playTranslationItem(TranslationItem item) {
translationController.playTranslationItem(item);
}
// 播放指定文本
void playText(String text) {
translationController.playTranslatedText(text);
}
// 检查是否有历史记录
bool get hasHistory => translationController.translationHistory.isNotEmpty;
// 删除指定会话的历史记录
Future<void> deleteSessionHistory(String sessionId) async {
try {
// 调用主控制器的删除方法
translationController.deleteSessionHistory(sessionId);
// 重新加载和分组历史数据
await loadHistoryData();
// 显示删除成功提示
Get.snackbar(
'删除成功',
'已删除该会话的所有翻译记录',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Get.isDarkMode ? Colors.grey[800] : Colors.grey[200],
colorText: Get.isDarkMode ? Colors.white : Colors.black,
duration: const Duration(seconds: 2),
);
} catch (e) {
// 显示删除失败提示
Get.snackbar(
'删除失败',
'删除会话记录时发生错误: ${e.toString()}',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Colors.red[400],
colorText: Colors.white,
duration: const Duration(seconds: 3),
);
}
}
}