Files

123 lines
3.3 KiB
Dart

import 'package:fruitshorts/core/data/models/drama.dart';
import 'package:fruitshorts/core/data/models/feed_page.dart';
import 'package:fruitshorts/core/data/models/home_feed.dart';
import 'package:fruitshorts/core/data/models/search_result.dart';
import 'package:fruitshorts/core/data/repositories/catalog_repository.dart';
import 'package:fruitshorts/core/data/repositories/search_repository.dart';
/// 测试用目录数据:三部分区里的短剧,标题与后端演示数据保持一致。
class FakeCatalogRepository implements CatalogRepository, SearchRepository {
FakeCatalogRepository({List<Drama>? dramas, this.banners = const []})
: dramas = dramas ?? demoDramas;
final List<Drama> dramas;
final List<FeedBanner> banners;
@override
Future<HomeFeed> fetchHomeFeed() async => _feed();
@override
Future<HomeFeed> fetchDiscoverFeed() async => _feed();
@override
Future<FeedPage> fetchFeed({
List<String> types = const [],
String? categoryId,
String? cursor,
int size = 10,
}) async {
final filtered = types.isEmpty
? dramas
: dramas.where((drama) => _matchesFeedTypes(drama, types)).toList();
return FeedPage(dramas: filtered.take(size).toList());
}
bool _matchesFeedTypes(Drama drama, List<String> types) {
final dramaType = drama.id == 'the-signal-demo' ? 'ANIME' : 'LIVE';
return types.contains(dramaType);
}
@override
Future<Drama> fetchDrama(String dramaId) async {
return dramas.firstWhere((drama) => drama.id == dramaId);
}
@override
Future<SearchResult> search(
String keyword, {
int pageIndex = 1,
int pageSize = 20,
}) async {
final query = keyword.trim().toLowerCase();
final hits = dramas.where((drama) {
final haystack = [drama.title, drama.synopsis, drama.genre].join(' ');
return haystack.toLowerCase().contains(query);
}).toList();
return SearchResult(total: hits.length, list: hits);
}
HomeFeed _feed() => HomeFeed(
banners: banners,
sections: [FeedSection(code: 'hot', title: '热门推荐', dramas: dramas)],
);
}
final List<Drama> demoDramas = [
_drama(
'the-signal-demo',
'The Signal',
'Suspense · Mystery',
format: 1,
viewCount: 419000,
likeCount: 419000,
favoriteCount: 1006,
commentCount: 32000,
),
_drama(
'city-lights-demo',
'City Lights & Velvet Nights',
'Urban Romance',
format: 8,
likeCount: 12400,
favoriteCount: 3200,
commentCount: 96,
),
_drama('vengeance-demo', 'Vengeance Rising', 'Action · Thriller', format: 15),
];
Drama _drama(
String id,
String title,
String genre, {
required int format,
int? likeCount,
int? favoriteCount,
int? commentCount,
int viewCount = 0,
}) => Drama(
id: id,
title: title,
synopsis: '$title synopsis',
posterUrl: '/files/$id.png',
genre: genre,
language: 'id',
detailLoaded: true,
viewCount: viewCount,
likeCount: likeCount,
favoriteCount: favoriteCount,
commentCount: commentCount,
episodes: [
for (var index = 0; index < 7; index++)
Episode(
id: '$id-${index + 1}',
number: index + 1,
title: 'Episode ${index + 1}',
isFree: true,
durationSec: 60,
videoUrl: 'https://example.test/$format-$index.mp4',
likeCount: likeCount,
commentCount: commentCount,
),
],
);