深色模式、首页设置页面和功能优化

This commit is contained in:
Developer
2026-04-02 07:06:55 +08:00
parent f0a62ed68b
commit 954d173329
88 changed files with 12157 additions and 7578 deletions

View File

@@ -0,0 +1,637 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../../controllers/history_controller.dart';
import '../../../utils/http/poetry_api.dart';
import '../../../services/network_listener_service.dart';
import '../../../utils/audio_manager.dart';
import '../../../constants/app_constants.dart';
import '../../views/home/set/home_components.dart';
import '../../views/home/set/home-load.dart';
import '../../../views/profile/guide/tongji.dart';
class HomeController extends GetxController with NetworkListenerMixin {
var poetryData = Rxn<PoetryData>();
var keywordList = <String>[].obs;
var loading = false.obs;
var isLiked = false.obs;
var isLoadingLike = false.obs;
var errorMessage = ''.obs;
var starDisplay = ''.obs;
var historyList = <Map<String, dynamic>>[].obs;
var currentHistoryIndex = (-1).obs;
// 动态加载状态
var isLoadingNext = false.obs;
var sectionLoadingStates = {
'title': false,
'content': false,
'name': false,
'keywords': false,
'introduction': false,
}.obs;
@override
void onInit() {
super.onInit();
// 异步初始化所有服务,然后加载诗词
_initializeAndLoadPoetry();
}
Future<void> _initializeAndLoadPoetry() async {
try {
// 并行初始化所有服务
await Future.wait([
_initAudioManager(),
_initSecondaryButtonsManager(),
_initAutoRefresh(),
_initDebugInfo(),
_initOfflineDataManager(),
]);
// 所有初始化完成后,加载诗词
await loadPoetry();
} catch (e) {
// 初始化失败时,仍然尝试加载诗词
await loadPoetry();
}
}
Future<void> _initSecondaryButtonsManager() async {
await SecondaryButtonsManager().init();
}
Future<void> _initAudioManager() async {
await AudioManager().init();
}
Future<void> _initOfflineDataManager() async {
final offlineDataManager = OfflineDataManager();
await offlineDataManager.init();
}
Future<void> _initAutoRefresh() async {
final autoRefreshManager = AutoRefreshManager();
await autoRefreshManager.init();
autoRefreshManager.setOnRefresh(() {
loadNextPoetry();
});
if (autoRefreshManager.isEnabled) {
autoRefreshManager.setEnabled(true);
}
}
Future<void> _initDebugInfo() async {
final debugInfoManager = DebugInfoManager();
await debugInfoManager.init();
}
@override
void onClose() {
// 只停止定时器,不释放单例资源
AutoRefreshManager().stopTimer();
super.onClose();
}
Future<void> loadPoetry() async {
if (loading.value) return;
loading.value = true;
PoetryStateManager.triggerHapticFeedback();
try {
final offlineDataManager = OfflineDataManager();
final isOnline = await offlineDataManager.isOnline();
final hasCachedData = await offlineDataManager.hasCachedData();
if (isOnline) {
// 在线状态:从网络加载
final response = await PoetryApi.getRandomPoetry();
if (response.data != null) {
// 记录浏览统计
try {
await StatisticsManager().recordView();
await StatisticsManager().recordFirstUse();
await StatisticsManager().recordTotalView();
} catch (e) {
// 忽略错误
}
poetryData.value = response.data;
keywordList.value = PoetryDataUtils.extractKeywords(response.data);
starDisplay.value = PoetryDataUtils.getStarDisplay(response.data);
isLiked.value = false;
loading.value = false;
errorMessage.value = '';
checkIfLiked();
await saveToHistory(response.data!);
DebugInfoManager().showRefreshSuccess();
update(); // 通知UI更新
} else {
// 数据为空时,显示默认内容
poetryData.value = createDefaultPoetryData();
keywordList.value = [];
starDisplay.value = '⭐⭐⭐⭐⭐';
isLiked.value = false;
loading.value = false;
errorMessage.value = '';
DebugInfoManager().showRefreshFailed();
update(); // 通知UI更新
}
} else {
// 离线状态:从本地缓存加载
if (hasCachedData) {
final poetryData = await offlineDataManager.getNextPoetry();
if (poetryData != null) {
// 记录浏览统计
try {
await StatisticsManager().recordView();
await StatisticsManager().recordFirstUse();
await StatisticsManager().recordTotalView();
} catch (e) {
// 忽略错误
}
this.poetryData.value = poetryData;
keywordList.value = PoetryDataUtils.extractKeywords(poetryData);
starDisplay.value = PoetryDataUtils.getStarDisplay(poetryData);
isLiked.value = false;
loading.value = false;
errorMessage.value = '';
checkIfLiked();
DebugInfoManager().showRefreshSuccess();
update(); // 通知UI更新
} else {
// 缓存为空时,显示错误信息
loading.value = false;
errorMessage.value = '离线模式下无缓存数据,请先在线下载';
DebugInfoManager().showRefreshFailed();
update(); // 通知UI更新
}
} else {
// 离线且无缓存时,显示错误信息
loading.value = false;
errorMessage.value = '离线模式下无缓存数据,请先在线下载';
DebugInfoManager().showRefreshFailed();
update(); // 通知UI更新
}
}
} catch (e) {
loading.value = false;
errorMessage.value = '加载失败,请检查网络连接';
DebugInfoManager().showRefreshFailed();
update(); // 通知UI更新
}
}
// 创建默认诗词数据,确保页面始终有内容显示
PoetryData createDefaultPoetryData() {
final now = DateTime.now();
final dateStr = now.toString().substring(0, 10);
final monthStr = dateStr.substring(0, 7);
final timeStr = now.toString().substring(11, 19);
return PoetryData(
id: 1,
name: '静夜思',
alias: '李白',
keywords: '思乡,月亮,静夜',
introduce: '床前明月光,疑是地上霜。举头望明月,低头思故乡。',
drtime: '唐·李白《静夜思》',
like: 0,
url: '李白-静夜思',
tui: 1,
star: 5,
hitsTotal: 10000,
hitsMonth: 1000,
hitsDay: 100,
date: dateStr,
datem: monthStr,
time: timeStr,
createTime: timeStr,
updateTime: timeStr,
);
}
Future<void> loadPoetryById(int poetryId) async {
if (loading.value) return;
loading.value = true;
try {
final response = await PoetryApi.getPoetryById(poetryId);
if (response.data != null) {
// 记录浏览统计
try {
await StatisticsManager().recordView();
await StatisticsManager().recordFirstUse();
await StatisticsManager().recordTotalView();
} catch (e) {
// 忽略错误
}
poetryData.value = response.data;
keywordList.value = PoetryDataUtils.extractKeywords(response.data);
starDisplay.value = PoetryDataUtils.getStarDisplay(response.data);
loading.value = false;
errorMessage.value = '';
update(); // 通知UI更新
checkIfLiked();
updateCurrentHistoryIndex();
} else {
// 数据为空时,显示默认内容
poetryData.value = createDefaultPoetryData();
keywordList.value = [];
starDisplay.value = '⭐⭐⭐⭐⭐';
isLiked.value = false;
loading.value = false;
errorMessage.value = '';
update(); // 通知UI更新
}
} catch (e) {
poetryData.value = createDefaultPoetryData();
keywordList.value = [];
starDisplay.value = '⭐⭐⭐⭐⭐';
isLiked.value = false;
loading.value = false;
errorMessage.value = '';
update(); // 通知UI更新
}
}
Future<void> toggleLike() async {
if (poetryData.value == null || isLoadingLike.value) return;
// 播放点赞音效(不等待完成)
AudioManager().playLikeSound();
// 立即切换按钮状态和显示加载
isLoadingLike.value = true;
// 发送网络加载开始事件
startNetworkLoading('toggle_like');
try {
final response = await PoetryApi.toggleLike(poetryData.value!.id);
// 根据API响应消息直接判断状态
isLiked.value = response.message.contains('点赞成功');
// 更新诗词数据
if (response.data != null) {
poetryData.value = PoetryData(
id: poetryData.value!.id,
name: poetryData.value!.name,
alias: poetryData.value!.alias,
keywords: poetryData.value!.keywords,
introduce: poetryData.value!.introduce,
drtime: poetryData.value!.drtime,
like: response.data!.like,
url: poetryData.value!.url,
tui: poetryData.value!.tui,
star: poetryData.value!.star,
hitsTotal: poetryData.value!.hitsTotal,
hitsMonth: poetryData.value!.hitsMonth,
hitsDay: poetryData.value!.hitsDay,
date: poetryData.value!.date,
datem: poetryData.value!.datem,
time: poetryData.value!.time,
createTime: poetryData.value!.createTime,
updateTime: poetryData.value!.updateTime,
);
update(); // 通知UI更新
}
// 通知UI更新点赞状态
update();
// 管理点赞存储
if (isLiked.value) {
// 添加到点赞列表
await HistoryController.addToLiked(poetryData.value!.toJson());
// 记录今日点赞
await StatisticsManager().recordTodayLike();
// 记录累计点赞
await StatisticsManager().recordTotalLike();
} else {
// 从点赞列表移除
await HistoryController.removeLikedPoetry(
poetryData.value!.id.toString(),
);
}
// 发送点赞事件通知其他页面
sendLikeEvent(poetryData.value!.id.toString(), isLiked.value);
if (isLiked.value) {
DebugInfoManager().showLiked();
} else {
DebugInfoManager().showUnliked();
}
} catch (e) {
Get.snackbar(
'提示',
'操作失败,请重试',
snackPosition: SnackPosition.TOP,
backgroundColor: AppConstants.errorColor.withValues(alpha: 0.8),
colorText: Colors.white,
duration: const Duration(seconds: 2),
margin: const EdgeInsets.all(16),
borderRadius: 20,
animationDuration: const Duration(milliseconds: 300),
);
} finally {
isLoadingLike.value = false;
update(); // 通知UI更新加载状态
// 发送网络加载结束事件
endNetworkLoading('toggle_like');
}
}
Future<void> loadHistory() async {
try {
final historyJson = await HistoryController.getHistory();
historyList.value = historyJson;
// 重新计算当前诗词在历史记录中的索引
if (poetryData.value != null && historyList.isNotEmpty) {
currentHistoryIndex.value = historyList.indexWhere(
(item) => item['id'] == poetryData.value!.id,
);
} else {
currentHistoryIndex.value = -1;
}
} catch (e) {
// 加载失败
}
}
Future<void> saveToHistory(PoetryData poetryData) async {
try {
final poetryMap = {
'id': poetryData.id,
'name': poetryData.name, // 诗句名称/标题
'alias': poetryData.alias, // 诗句朝代/作者
'introduce': poetryData.introduce, // 诗句译文/解释
'drtime': poetryData.drtime, // 诗句原文/内容
};
await HistoryController.addToHistory(poetryMap);
} catch (e) {
// 保存失败
}
}
void updateCurrentHistoryIndex() {
if (poetryData.value?.id != null) {
final index = historyList.indexWhere(
(item) => item['id'] == poetryData.value!.id,
);
currentHistoryIndex.value = index >= 0 ? index : -1;
}
}
Future<void> checkIfLiked() async {
// 这里可以实现检查收藏状态的逻辑
// 暂时使用简单的模拟逻辑
}
Future<void> loadNextPoetry() async {
if (isLoadingNext.value) return;
// 播放下一条音效(不等待完成)
AudioManager().playNextSound();
isLoadingNext.value = true;
// 设置所有区域为加载状态
sectionLoadingStates.value = {
'title': true,
'content': true,
'name': true,
'keywords': true,
'introduction': true,
};
try {
final offlineDataManager = OfflineDataManager();
final isOnline = await offlineDataManager.isOnline();
final hasCachedData = await offlineDataManager.hasCachedData();
PoetryData? newPoetryData;
if (isOnline) {
// 在线状态:从网络加载
// 确保历史记录已加载
if (historyList.isEmpty) {
await loadHistory();
}
if (currentHistoryIndex.value < 0 ||
currentHistoryIndex.value >= historyList.length - 1) {
// 如果没有下一条了,加载新的诗词
final response = await PoetryApi.getRandomPoetry();
newPoetryData = response.data;
if (newPoetryData != null) {
await saveToHistory(newPoetryData);
}
} else {
// 如果有下一条,加载下一条
final nextPoetry = historyList[currentHistoryIndex.value + 1];
final response = await PoetryApi.getPoetryById(nextPoetry['id']);
newPoetryData = response.data;
}
} else {
// 离线状态:从本地缓存加载
if (hasCachedData) {
newPoetryData = await offlineDataManager.getNextPoetry();
} else {
// 离线且无缓存时,显示错误信息
Get.snackbar(
'提示',
'离线模式下无缓存数据,请先在线下载',
snackPosition: SnackPosition.TOP,
backgroundColor: AppConstants.errorColor.withValues(alpha: 0.8),
colorText: Colors.white,
duration: const Duration(seconds: 2),
margin: const EdgeInsets.all(16),
borderRadius: 20,
animationDuration: const Duration(milliseconds: 300),
);
// 重置所有加载状态
var states = <String, bool>{};
sectionLoadingStates.forEach((key, value) {
states[key] = false;
});
sectionLoadingStates.assignAll(states);
return;
}
}
if (newPoetryData != null) {
// 模拟分步加载
await simulateSectionLoading(newPoetryData);
DebugInfoManager().showNextSuccess();
}
} catch (e) {
DebugInfoManager().showNextFailed();
// 重置所有加载状态
var states = <String, bool>{};
sectionLoadingStates.forEach((key, value) {
states[key] = false;
});
sectionLoadingStates.assignAll(states);
} finally {
isLoadingNext.value = false;
}
}
// 模拟分步加载过程
Future<void> simulateSectionLoading(PoetryData newPoetryData) async {
// 记录浏览统计
try {
await StatisticsManager().recordView();
await StatisticsManager().recordFirstUse();
await StatisticsManager().recordTotalView();
} catch (e) {
// 忽略错误
}
// 1. 加载标题区域
var states = <String, bool>{};
sectionLoadingStates.forEach((key, value) {
states[key] = value;
});
states['title'] = false;
sectionLoadingStates.assignAll(states);
poetryData.value = newPoetryData;
update(); // 通知UI更新
await Future.delayed(const Duration(milliseconds: 200));
// 2. 加载诗句区域
states = <String, bool>{};
sectionLoadingStates.forEach((key, value) {
states[key] = value;
});
states['name'] = false;
sectionLoadingStates.assignAll(states);
update(); // 通知UI更新
await Future.delayed(const Duration(milliseconds: 200));
// 3. 加载原文区域
states = <String, bool>{};
sectionLoadingStates.forEach((key, value) {
states[key] = value;
});
states['content'] = false;
sectionLoadingStates.assignAll(states);
update(); // 通知UI更新
await Future.delayed(const Duration(milliseconds: 200));
// 4. 加载关键词区域
states = <String, bool>{};
sectionLoadingStates.forEach((key, value) {
states[key] = value;
});
states['keywords'] = false;
sectionLoadingStates.assignAll(states);
keywordList.value = PoetryDataUtils.extractKeywords(newPoetryData);
update(); // 通知UI更新
await Future.delayed(const Duration(milliseconds: 200));
// 5. 加载译文区域
states = <String, bool>{};
sectionLoadingStates.forEach((key, value) {
states[key] = value;
});
states['introduction'] = false;
sectionLoadingStates.assignAll(states);
starDisplay.value = PoetryDataUtils.getStarDisplay(newPoetryData);
isLiked.value = false;
errorMessage.value = '';
update(); // 通知UI更新
checkIfLiked();
updateCurrentHistoryIndex();
}
Future<void> loadPreviousPoetry() async {
try {
final offlineDataManager = OfflineDataManager();
final isOnline = await offlineDataManager.isOnline();
final hasCachedData = await offlineDataManager.hasCachedData();
if (isOnline) {
// 在线状态:从历史记录加载
// 确保历史记录已加载
if (historyList.isEmpty) {
await loadHistory();
}
if (currentHistoryIndex.value <= 0) {
// 如果当前索引无效或已经是第一条,则重新加载历史记录
await loadHistory();
// 如果历史记录为空,显示提示
if (historyList.isEmpty) {
DebugInfoManager().showPreviousFailed();
return;
}
// 如果当前索引无效,设置为最新的一条
if (currentHistoryIndex.value < 0) {
currentHistoryIndex.value = 0;
}
}
// 检查是否有上一条
if (currentHistoryIndex.value > 0) {
final previousPoetry = historyList[currentHistoryIndex.value - 1];
await loadPoetryById(previousPoetry['id']);
} else {
// 如果没有上一条了,显示提示
DebugInfoManager().showPreviousFailed();
}
} else {
// 离线状态:从本地缓存加载
if (hasCachedData) {
final poetryData = await offlineDataManager.getPreviousPoetry();
if (poetryData != null) {
this.poetryData.value = poetryData;
keywordList.value = PoetryDataUtils.extractKeywords(poetryData);
starDisplay.value = PoetryDataUtils.getStarDisplay(poetryData);
isLiked.value = false;
errorMessage.value = '';
update(); // 通知UI更新
checkIfLiked();
DebugInfoManager().showPreviousSuccess();
} else {
// 缓存为空时,显示错误信息
DebugInfoManager().showPreviousFailed();
}
} else {
// 离线且无缓存时,显示错误信息
DebugInfoManager().showPreviousFailed();
}
}
} catch (e) {
DebugInfoManager().showPreviousFailed();
}
}
Future<void> refreshPoetry() async {
if (poetryData.value?.id != null) {
// 如果有当前诗词ID则重新加载当前诗词
await loadPoetryById(poetryData.value!.id);
} else {
// 如果没有当前诗词ID则加载新的诗词
await loadPoetry();
}
}
}