77 lines
2.2 KiB
Dart
77 lines
2.2 KiB
Dart
// 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 [];
|
|
}
|
|
}
|