// Author: fruit.com.cn part of 'player_view.dart'; extension _PlayerViewActions on _PlayerPageState { Future _openSpeedSheet(BuildContext context) async { final selected = await showModalBottomSheet( context: context, backgroundColor: Colors.transparent, showDragHandle: false, builder: (_) => PlayerSpeedSheet(selected: _playbackSpeed), ); if (selected == null || !mounted) return; _updatePlaybackSpeed(selected); await logic.setPlaybackSpeed(selected); } Future _openMore( BuildContext context, Drama drama, Episode episode, ) async { final l10n = AppLocalizations.of(context)!; await showModalBottomSheet( context: context, backgroundColor: Colors.transparent, showDragHandle: false, isScrollControlled: true, builder: (_) => PlayerMoreSheet( l10n: l10n, state: PlayerMoreState( speed: _playbackSpeed, qualities: logic.qualities, textScale: _textScale, ), actions: PlayerMoreActions( onSpeedChanged: (value) { _updatePlaybackSpeed(value); unawaited(logic.setPlaybackSpeed(value)); }, onTextScaleChanged: _updateTextScale, onClear: _hideChrome, onDownload: () => requestEpisodeDownload(context, episode.id), onReport: () => unawaited(_reportDrama(context, drama, l10n)), ), ), ); } Future _openUnlockSheet( BuildContext context, int index, Episode episode, ) async { final wallet = logic.wallet; if (wallet == null) return; await showModalBottomSheet( context: context, backgroundColor: Colors.transparent, showDragHandle: false, isScrollControlled: true, builder: (_) => PlayerUnlockSheet( l10n: AppLocalizations.of(context)!, episodeNumber: episode.number, coinCost: logic.blockedTicket?.unlockCoin ?? 0, balance: wallet.snapshot == null ? null : wallet.balance, onUnlock: () => _unlockEpisode(context, index), ), ); } Future _unlockEpisode(BuildContext context, int index) async { if (!await ensureSignedIn(context) || !context.mounted) return false; final ok = await logic.unlockEpisode(index); if (ok || !context.mounted) return ok; final l10n = AppLocalizations.of(context)!; ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(errorText(l10n, logic.unlockError, l10n.unlockFailed)), ), ); return false; } Future _reportDrama( BuildContext context, Drama drama, AppLocalizations l10n, ) async { if (!await ensureSignedIn(context) || !context.mounted) return; final draft = await showReportDialog(context, title: l10n.reportDrama); if (draft == null || !context.mounted) return; unawaited(context.read().lightImpact()); final result = await context.read().reportDrama( drama.id, reason: draft.reason, description: draft.description, ); if (!context.mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( result.isSuccess ? l10n.reportSubmitted : result.errorMessage ?? l10n.reportFailed, ), ), ); } Future _toggleLike( BuildContext context, InteractionController interactions, Drama drama, ) async { if (!await ensureSignedIn(context) || !context.mounted) return; unawaited(context.read().lightImpact()); final result = await interactions.toggleDramaLike(drama.id); if (result.isSuccess || !context.mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( result.errorMessage ?? AppLocalizations.of(context)!.likeFailed, ), ), ); } Future _toggleSave(BuildContext context, Drama drama) async { final favorites = context.read(); if (!await ensureSignedIn(context) || !context.mounted) return; unawaited(context.read().lightImpact()); final ok = await favorites.toggle(drama.id, card: drama); if (ok || !context.mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(AppLocalizations.of(context)!.favoriteToggleFailed), ), ); } }