141 lines
4.6 KiB
Dart
141 lines
4.6 KiB
Dart
// Author: fruit.com.cn
|
|
|
|
part of 'player_view.dart';
|
|
|
|
extension _PlayerViewActions on _PlayerPageState {
|
|
Future<void> _openSpeedSheet(BuildContext context) async {
|
|
final selected = await showModalBottomSheet<double>(
|
|
context: context,
|
|
backgroundColor: AppColors.transparent,
|
|
showDragHandle: false,
|
|
builder: (_) => PlayerSpeedSheet(selected: _playbackSpeed),
|
|
);
|
|
if (selected == null || !mounted) return;
|
|
_updatePlaybackSpeed(selected);
|
|
await logic.setPlaybackSpeed(selected);
|
|
}
|
|
|
|
Future<void> _openMore(BuildContext context, Episode episode) async {
|
|
final l10n = AppLocalizations.of(context)!;
|
|
await showModalBottomSheet<void>(
|
|
context: context,
|
|
backgroundColor: AppColors.transparent,
|
|
showDragHandle: false,
|
|
isScrollControlled: true,
|
|
builder: (_) => PlayerMoreSheet(
|
|
l10n: l10n,
|
|
state: PlayerMoreState(
|
|
speed: _playbackSpeed,
|
|
qualities: logic.qualities,
|
|
selectedQuality: logic.selectedQuality,
|
|
),
|
|
actions: PlayerMoreActions(
|
|
onSpeedChanged: (value) {
|
|
_updatePlaybackSpeed(value);
|
|
unawaited(logic.setPlaybackSpeed(value));
|
|
},
|
|
onQualityChanged: (quality) => _switchQuality(context, l10n, quality),
|
|
onClear: _hideChrome,
|
|
onDownload: () => requestEpisodeDownload(context, episode.id),
|
|
onPip: logic.pictureInPicture.isPlatformSupported
|
|
? () => unawaited(logic.enterPip(context))
|
|
: null,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<bool> _switchQuality(
|
|
BuildContext context,
|
|
AppLocalizations l10n,
|
|
String quality,
|
|
) async {
|
|
Navigator.of(context).pop();
|
|
final switched = await logic.selectQuality(quality);
|
|
if (!context.mounted || !switched) return false;
|
|
final label = quality.toUpperCase() == 'AUTO' ? l10n.qualityAuto : quality;
|
|
showCenteredToast(context, l10n.qualitySwitched(label));
|
|
return true;
|
|
}
|
|
|
|
Future<void> _openUnlockSheet(
|
|
BuildContext context,
|
|
int index,
|
|
Episode episode,
|
|
) async {
|
|
final wallet = logic.wallet;
|
|
if (wallet == null) return;
|
|
await showModalBottomSheet<bool>(
|
|
context: context,
|
|
backgroundColor: AppColors.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<bool> _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<void> _toggleLike(
|
|
BuildContext context,
|
|
InteractionController interactions,
|
|
Episode episode, {
|
|
bool likeOnly = false,
|
|
}) async {
|
|
unawaited(context.read<Haptics>().lightImpact());
|
|
if (interactions.isEpisodeBusy(episode.id) ||
|
|
(likeOnly && interactions.isEpisodeLiked(episode.id))) {
|
|
return;
|
|
}
|
|
if (!await ensureSignedIn(context) || !context.mounted) return;
|
|
if (interactions.isEpisodeBusy(episode.id) ||
|
|
(likeOnly && interactions.isEpisodeLiked(episode.id))) {
|
|
return;
|
|
}
|
|
final result = await interactions.toggleEpisodeLike(episode.id);
|
|
if (result.isSuccess || !context.mounted) return;
|
|
showCenteredToast(
|
|
context,
|
|
result.errorMessage ?? AppLocalizations.of(context)!.likeFailed,
|
|
);
|
|
}
|
|
|
|
Future<void> _toggleSave(BuildContext context, Drama drama) async {
|
|
final favorites = context.read<FavoriteController>();
|
|
if (!await ensureSignedIn(context) || !context.mounted) return;
|
|
unawaited(context.read<Haptics>().lightImpact());
|
|
final wasSaved = favorites.isSaved(drama.id);
|
|
final ok = await favorites.toggle(drama.id, card: drama);
|
|
if (!context.mounted) return;
|
|
if (ok) {
|
|
final nowSaved = favorites.isSaved(drama.id);
|
|
if (nowSaved != wasSaved) {
|
|
_applyFavoriteDelta(drama.id, nowSaved: nowSaved);
|
|
}
|
|
return;
|
|
}
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(
|
|
content: Text(AppLocalizations.of(context)!.favoriteToggleFailed),
|
|
),
|
|
);
|
|
}
|
|
}
|