data.dart 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import 'package:flutter/material.dart';
  2. import 'package:puzzleweave/models/api_helper.dart';
  3. import 'package:puzzleweave/models/cached_request.dart';
  4. import 'package:puzzleweave/models/items.dart';
  5. import 'package:puzzleweave/persistence/persistence.dart';
  6. import 'package:logging/logging.dart';
  7. import 'package:puzzleweave/utils/utils.dart';
  8. final Logger _log = Logger('data.dart');
  9. class Data {
  10. final Persistence _persistence;
  11. ValueNotifier<List<Work>> completedWorks = ValueNotifier([]); // 已完成的图
  12. ValueNotifier<List<Work>> completedCollections = ValueNotifier([]); // 已完成的收藏图
  13. Data({required Persistence persistence}) : _persistence = persistence;
  14. Future<void> loadDataFromPersistence() async {
  15. // for test 为了测试合集完成动画
  16. // var works = _persistence.completedWorks;
  17. // works = works.sublist(0, works.length - 1);
  18. // _persistence.completedWorks = works;
  19. // _persistence.completedCollections = [];
  20. completedWorks.value = _persistence.completedWorks;
  21. completedCollections.value = _persistence.completedCollections;
  22. }
  23. // 完成某个作品调用此接口记录到存储中
  24. // !!! 改造点:接受 ListItem 和可选的耗时
  25. void workDone(ListItem item, {Duration? timeSpent}) {
  26. final newWork = Work.fromListItem(item, timeSpent: timeSpent);
  27. // 1. 记录作品完成
  28. final updatedWorks = [...completedWorks.value, newWork];
  29. completedWorks.value = updatedWorks;
  30. _persistence.completedWorks = updatedWorks; // 存储更新后的列表
  31. // 2. 核心新增:清除已完成作品的缓存
  32. _clearCompletedItemCache(item);
  33. }
  34. /// 清除已完成作品的缓存文件。
  35. void _clearCompletedItemCache(ListItem item) async {
  36. // 删除进度状态json
  37. try {
  38. final file = await localFile(item.jsonPath);
  39. if (await file.exists()) {
  40. await file.delete();
  41. _log.info('Successfully cleared json cache file for ${item.id}');
  42. } else {
  43. _log.warning('json cache file not found for ${item.id} at path: ${item.jsonPath}');
  44. }
  45. } catch (e) {
  46. _log.severe('Failed to clear json cache for item ${item.id}, error: $e');
  47. }
  48. // 只有 RemoteItem 才会有需要清理的下载缓存
  49. if (item is RemoteItem) {
  50. _log.info('Work done for remote item ${item.id}. Attempting to clear cache at path: ${item.cachePath}');
  51. try {
  52. final file = await localFile(item.cachePath);
  53. if (await file.exists()) {
  54. await file.delete();
  55. _log.info('Successfully cleared cache file for ${item.id}');
  56. } else {
  57. _log.warning('Cache file not found for ${item.id} at path: ${item.cachePath}');
  58. }
  59. } catch (e) {
  60. _log.severe('Failed to clear cache for item ${item.id}, error: $e');
  61. }
  62. } else {
  63. _log.info('Work done for asset item ${item.id}. No network cache to clear.');
  64. }
  65. }
  66. // 获取当前的关卡index (基于已完成作品的数量)
  67. int get currentLevel => completedWorks.value.length;
  68. // 完成某个collection
  69. void collectionDone(ListItem item) {
  70. final newCollection = Work.fromListItem(item);
  71. final updatedCollections = [...completedCollections.value, newCollection];
  72. completedCollections.value = updatedCollections;
  73. _persistence.completedCollections = updatedCollections; // 存储更新后的列表
  74. }
  75. // 获取当前的合集index (基于已完成收藏的数量)
  76. int get currentCollectionIndex => completedCollections.value.length;
  77. CachedRequest? _latest;
  78. CachedRequest get latest {
  79. _latest ??= CachedRequest.fromUrl(
  80. ApiHelper.latestUri,
  81. transformFunction: (json) async {
  82. late List<ListItem> list;
  83. if (json['asset'] != null) {
  84. // from asset
  85. list = List<AssetItem>.from((json['data'] as Iterable).map((e) => AssetItem.fromJSON(e)));
  86. } else {
  87. // from remote
  88. list = List<RemoteItem>.from((json['data'] as Iterable).map((e) => RemoteItem.fromJSON(e)));
  89. }
  90. return list;
  91. },
  92. );
  93. return _latest!;
  94. }
  95. CachedRequest? _collection;
  96. CachedRequest get collection {
  97. _collection ??= CachedRequest.fromUrl(
  98. ApiHelper.collectionUri,
  99. transformFunction: (json) async {
  100. late List<ListItem> list;
  101. if (json['asset'] != null) {
  102. // from asset
  103. list = List<AssetItem>.from((json['data'] as Iterable).map((e) => AssetItem.fromJSON(e)));
  104. } else {
  105. // from remote
  106. list = List<RemoteItem>.from((json['data'] as Iterable).map((e) => RemoteItem.fromJSON(e)));
  107. }
  108. return list;
  109. },
  110. );
  111. return _collection!;
  112. }
  113. }