feat(category): 分类频道接入榜单快照

This commit is contained in:
Zhou Weidong committed 2026-11-02 14:44:38 +08:00
1 parent 8c1662475a
commit 59fbd33059
8 files changed
+234 -11

No files matched your search

@@ -4,6 +4,7 @@ import 'package:flutter/foundation.dart';
import '../../config/app_config.dart';
import '../models/content_category.dart';
import '../models/category_ranking.dart';
import '../models/drama.dart';
import '../models/home_feed.dart';
import '../models/page_result.dart';
@@ -21,10 +22,15 @@ class CategoryController extends ChangeNotifier {
String categoryId, {
int pageIndex,
int pageSize,
})? dramaPageLoader;
})?
dramaPageLoader;
/// 生产环境推荐榜加载器,测试与本地数据模式可不注入。
Future<CategoryRanking> Function(String categoryId)? rankingLoader;
List<ContentCategory> categories = const [];
final Map<String, CategoryDramaSlot> _slots = {};
final Map<String, CategoryRankingSlot> _rankingSlots = {};
HomeFeed feed = const HomeFeed();
bool loading = false;
String? error;
@@ -36,6 +42,29 @@ class CategoryController extends ChangeNotifier {
return _slots.putIfAbsent(categoryId, CategoryDramaSlot.new);
}
CategoryRankingSlot rankingSlotOf(String categoryId) {
return _rankingSlots.putIfAbsent(categoryId, CategoryRankingSlot.new);
}
/// 打开推荐榜并获取当前服务端快照。
Future<void> openRanking(String categoryId) async {
final loader = rankingLoader;
if (loader == null) return;
final slot = rankingSlotOf(categoryId);
slot.loading = true;
slot.error = null;
_notify();
try {
slot.ranking = await loader(categoryId);
} catch (exception) {
slot.error = exception;
if (kDebugMode) debugPrint('[category-ranking] $exception');
} finally {
slot.loading = false;
_notify();
}
}
/// 打开分类并加载第一页短剧。
Future<void> openCategory(String categoryId) async {
final loader = dramaPageLoader;
@@ -126,8 +155,14 @@ class CategoryController extends ChangeNotifier {
loading = false;
_notify();
}
if (error == null && dramaPageLoader != null && categories.isNotEmpty) {
await openCategory(categories.first.id);
final hasRemoteLoader = dramaPageLoader != null || rankingLoader != null;
if (error == null && hasRemoteLoader && categories.isNotEmpty) {
final first = categories.first;
if (first.isRanking) {
await openRanking(first.id);
} else {
await openCategory(first.id);
}
}
}
@@ -152,3 +187,10 @@ class CategoryDramaSlot {
bool get hasMore => dramas.length < total;
}
/// 单个推荐榜的快照状态。
class CategoryRankingSlot {
CategoryRanking? ranking;
Object? error;
bool loading = false;
}