// Author: fruit.com.cn import 'package:fruitshorts/core/data/repositories/watch_history_repository.dart'; import 'package:fruitshorts/core/data/models/page_result.dart'; import 'package:fruitshorts/core/data/models/watch_progress.dart'; /// 记录每次进度读取/上报,方便断言"读了哪部剧、上报了哪一集"。 /// /// 服务端模型:每部剧一条续看记录(不再是 profile+剧+集),所以 `reads` 里是 dramaId。 class FakeWatchHistory implements WatchHistoryRepository { final List reads = []; final List writes = []; /// 便捷写法:只关心"有续看位置"时直接给这个值(默认落在第 1 集)。 Duration? saved; /// 便捷写法:续看记录落在哪一集(配合 [saved] 使用)。 String? lastEpisode; /// 精确控制:按剧返回不同记录。 final Map records = {}; /// [recent] 的返回值。 List recentRecords = const []; bool failReads = false; bool failWrites = false; @override Future progressFor(String dramaId) async { reads.add(dramaId); if (failReads) throw StateError('history unavailable'); final record = records[dramaId]; if (record != null) return record; if (saved == null) return null; return WatchProgress( dramaId: dramaId, episodeId: lastEpisode ?? '$dramaId-1', position: saved!, duration: const Duration(minutes: 5), ); } @override Future save({ required String episodeId, required Duration position, Duration? duration, bool finished = false, }) async { if (failWrites) throw StateError('history unavailable'); writes.add('$episodeId|${position.inMilliseconds}|$finished'); return WatchProgress( dramaId: '', episodeId: episodeId, position: position, duration: duration ?? Duration.zero, finished: finished, ); } @override Future> recent({ int pageIndex = 1, int pageSize = 20, }) async { if (failReads) throw StateError('history unavailable'); final offset = (pageIndex - 1) * pageSize; if (offset >= recentRecords.length) { return PageResult(total: recentRecords.length); } return PageResult( total: recentRecords.length, list: recentRecords.skip(offset).take(pageSize).toList(), ); } @override Future remove(String dramaId) async => records.remove(dramaId); @override Future clear() async { records.clear(); recentRecords = const []; } }