feat(app): 剧场页九宫格与极简我的页
This commit is contained in:
1 parent
dc8ca7b743
commit
35338cbfc8
46 files changed
+2353
-4358
No files matched your search
@@ -0,0 +1,76 @@
|
||||
// Author: fruit.com.cn
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import '../../core/data/models/drama.dart';
|
||||
import '../../core/data/models/home_feed.dart';
|
||||
|
||||
/// Ranking boards backed by the feed sections the server already returns.
|
||||
enum RankingBoard { hot, newReleases }
|
||||
|
||||
/// One ranked title; rank is one-based and mirrors server section order.
|
||||
class RankingEntry {
|
||||
const RankingEntry({required this.rank, required this.drama});
|
||||
|
||||
final int rank;
|
||||
final Drama drama;
|
||||
}
|
||||
|
||||
/// Keeps the active board and turns real feed sections into ranked entries.
|
||||
///
|
||||
/// The backend does not expose a dedicated ranking endpoint, so this class
|
||||
/// never invents scores: it preserves the order of the `hot` and `new`
|
||||
/// sections and only falls back to the catalog when a section is absent.
|
||||
class RankingLogic extends ChangeNotifier {
|
||||
RankingLogic({required this.sections, required this.fallback});
|
||||
|
||||
static const hotSectionCode = 'hot';
|
||||
static const newSectionCode = 'new';
|
||||
|
||||
List<FeedSection> sections;
|
||||
List<Drama> fallback;
|
||||
RankingBoard _board = RankingBoard.hot;
|
||||
|
||||
RankingBoard get board => _board;
|
||||
|
||||
List<RankingEntry> get entries {
|
||||
final sectionCode = _board == RankingBoard.hot
|
||||
? hotSectionCode
|
||||
: newSectionCode;
|
||||
final source = _sectionDramas(sectionCode);
|
||||
final dramas = source.isEmpty ? fallback : source;
|
||||
final seen = <String>{};
|
||||
final unique = [
|
||||
for (final drama in dramas)
|
||||
if (seen.add(drama.id)) drama,
|
||||
];
|
||||
return [
|
||||
for (var index = 0; index < unique.length; index++)
|
||||
RankingEntry(rank: index + 1, drama: unique[index]),
|
||||
];
|
||||
}
|
||||
|
||||
/// Switches boards and notifies only when the visible source changes.
|
||||
void select(RankingBoard next) {
|
||||
if (_board == next) return;
|
||||
_board = next;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Applies refreshed feed data without rebuilding the page state.
|
||||
void updateSources({
|
||||
required List<FeedSection> sections,
|
||||
required List<Drama> fallback,
|
||||
}) {
|
||||
this.sections = sections;
|
||||
this.fallback = fallback;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
List<Drama> _sectionDramas(String code) {
|
||||
for (final section in sections) {
|
||||
if (section.code == code) return section.dramas;
|
||||
}
|
||||
return const [];
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user