// Author: fruit.com.cn import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../../core/config/locale_controller.dart'; import '../../core/data/models/drama.dart'; import '../../core/data/models/watch_progress.dart'; import '../../core/data/repositories/watch_history_repository.dart'; import '../../l10n/app_localizations.dart'; enum MyPageAction { home, discover, resume } class MineLogic extends ChangeNotifier { MineLogic({ required this.history, required this.drama, required int initialSection, }) : section = initialSection { refreshPosition(); } final WatchHistoryRepository history; Drama drama; late Future position; List recent = const []; bool recentLoading = false; String? recentError; /// 续看位置读取失败:与"没有记录"区分开,失败要能重试(不能假装成从 0 开始) bool positionFailed = false; int section; int filter = 0; bool _disposed = false; void notify() { if (!_disposed) notifyListeners(); } void refreshPosition() { position = history .resumePointFor(drama.id) .then((point) { positionFailed = false; return point?.position; }) .catchError((Object _) { positionFailed = true; notify(); return null; }); refreshRecent(); } /// 最近观看:服务端只给 dramaId/位置,剧名封面用已加载的目录卡片按 id 映射。 Future refreshRecent() async { recentLoading = true; recentError = null; notify(); try { recent = await history.recent(limit: 20); } catch (_) { recentError = 'progressError'; } finally { recentLoading = false; notify(); } } void selectSection(int index) { section = index; notify(); } void selectFilter(int index) { filter = index; notify(); } void syncPage({ required bool active, required bool wasActive, required Drama nextDrama, required bool dramaChanged, required int sectionRequest, required int previousSectionRequest, required int initialSection, }) { if (active && (!wasActive || dramaChanged)) { drama = nextDrama; refreshPosition(); notify(); } if (sectionRequest != previousSectionRequest) { section = initialSection; notify(); } } void act( BuildContext context, MyPageAction action, { required bool embedded, ValueChanged? onAction, }) { if (embedded) { onAction?.call(action); } else { Navigator.pop(context, action); } } Future showLanguage(BuildContext context) async { final l10n = AppLocalizations.of(context)!; await showModalBottomSheet( context: context, backgroundColor: const Color(0xFF1C1D22), showDragHandle: true, builder: (sheetContext) => SafeArea( child: Column( mainAxisSize: MainAxisSize.min, children: [ ListTile(title: Text(l10n.language)), for (final (code, label) in [ ('en', l10n.english), ('zh', l10n.simplifiedChinese), ]) ListTile( title: Text(label), onTap: () { context.read().select(code); Navigator.pop(sheetContext); }, ), const SizedBox(height: 8), ], ), ), ); } @override void dispose() { _disposed = true; super.dispose(); } }