mirror of
https://github.com/gabehf/Fladder.git
synced 2026-03-07 13:38:13 -08:00
207 lines
9.7 KiB
Dart
207 lines
9.7 KiB
Dart
import 'dart:io' show Platform;
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:auto_route/auto_route.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
import 'package:fladder/models/settings/video_player_settings.dart';
|
|
import 'package:fladder/providers/settings/video_player_settings_provider.dart';
|
|
import 'package:fladder/screens/settings/settings_list_tile.dart';
|
|
import 'package:fladder/screens/settings/settings_scaffold.dart';
|
|
import 'package:fladder/screens/settings/widgets/settings_label_divider.dart';
|
|
import 'package:fladder/screens/settings/widgets/settings_message_box.dart';
|
|
import 'package:fladder/screens/settings/widgets/subtitle_editor.dart';
|
|
import 'package:fladder/screens/shared/animated_fade_size.dart';
|
|
import 'package:fladder/screens/video_player/components/video_player_options_sheet.dart';
|
|
import 'package:fladder/util/adaptive_layout.dart';
|
|
import 'package:fladder/util/box_fit_extension.dart';
|
|
import 'package:fladder/util/localization_helper.dart';
|
|
import 'package:fladder/util/option_dialogue.dart';
|
|
import 'package:fladder/widgets/shared/enum_selection.dart';
|
|
|
|
@RoutePage()
|
|
class PlayerSettingsPage extends ConsumerStatefulWidget {
|
|
const PlayerSettingsPage({super.key});
|
|
|
|
@override
|
|
ConsumerState<ConsumerStatefulWidget> createState() => _PlayerSettingsPageState();
|
|
}
|
|
|
|
class _PlayerSettingsPageState extends ConsumerState<PlayerSettingsPage> {
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final videoSettings = ref.watch(videoPlayerSettingsProvider);
|
|
final provider = ref.read(videoPlayerSettingsProvider.notifier);
|
|
final showBackground = AdaptiveLayout.of(context).layout != LayoutState.phone &&
|
|
AdaptiveLayout.of(context).size != ScreenLayout.single;
|
|
return Card(
|
|
elevation: showBackground ? 2 : 0,
|
|
child: SettingsScaffold(
|
|
label: context.localized.settingsPlayerTitle,
|
|
items: [
|
|
SettingsLabelDivider(label: context.localized.video),
|
|
if (!AdaptiveLayout.of(context).isDesktop && !kIsWeb)
|
|
SettingsListTile(
|
|
label: Text(context.localized.videoScalingFillScreenTitle),
|
|
subLabel: Text(context.localized.videoScalingFillScreenDesc),
|
|
onTap: () => provider.setFillScreen(!videoSettings.fillScreen),
|
|
trailing: Switch(
|
|
value: videoSettings.fillScreen,
|
|
onChanged: (value) => provider.setFillScreen(value),
|
|
),
|
|
),
|
|
AnimatedFadeSize(
|
|
child: videoSettings.fillScreen
|
|
? SettingsMessageBox(
|
|
context.localized.videoScalingFillScreenNotif,
|
|
messageType: MessageType.warning,
|
|
)
|
|
: Container(),
|
|
),
|
|
SettingsListTile(
|
|
label: Text(context.localized.videoScalingFillScreenTitle),
|
|
subLabel: Text(videoSettings.videoFit.label(context)),
|
|
onTap: () => openOptionDialogue(
|
|
context,
|
|
label: context.localized.videoScalingFillScreenTitle,
|
|
items: BoxFit.values,
|
|
itemBuilder: (type) => RadioListTile.adaptive(
|
|
title: Text(type?.label(context) ?? ""),
|
|
value: type,
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
|
contentPadding: EdgeInsets.zero,
|
|
groupValue: ref.read(videoPlayerSettingsProvider.select((value) => value.videoFit)),
|
|
onChanged: (value) {
|
|
provider.setFitType(value);
|
|
Navigator.pop(context);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
const Divider(),
|
|
SettingsLabelDivider(label: context.localized.advanced),
|
|
if (PlayerOptions.available.length != 1)
|
|
SettingsListTile(
|
|
label: Text(context.localized.playerSettingsBackendTitle),
|
|
subLabel: Text(context.localized.playerSettingsBackendDesc),
|
|
trailing: Builder(builder: (context) {
|
|
final wantedPlayer = ref.watch(videoPlayerSettingsProvider.select((value) => value.wantedPlayer));
|
|
final currentPlayer = ref.watch(videoPlayerSettingsProvider.select((value) => value.playerOptions));
|
|
return EnumBox(
|
|
current: currentPlayer == null
|
|
? "${context.localized.defaultLabel} (${PlayerOptions.platformDefaults.label(context)})"
|
|
: wantedPlayer.label(context),
|
|
itemBuilder: (context) => [
|
|
PopupMenuItem(
|
|
value: null,
|
|
child:
|
|
Text("${context.localized.defaultLabel} (${PlayerOptions.platformDefaults.label(context)})"),
|
|
onTap: () => ref.read(videoPlayerSettingsProvider.notifier).state =
|
|
ref.read(videoPlayerSettingsProvider).copyWith(playerOptions: null),
|
|
),
|
|
...PlayerOptions.available.map(
|
|
(entry) => PopupMenuItem(
|
|
value: entry,
|
|
child: Text(entry.label(context)),
|
|
onTap: () => ref.read(videoPlayerSettingsProvider.notifier).state =
|
|
ref.read(videoPlayerSettingsProvider).copyWith(playerOptions: entry),
|
|
),
|
|
)
|
|
],
|
|
);
|
|
}),
|
|
),
|
|
AnimatedFadeSize(
|
|
child: switch (ref.read(videoPlayerSettingsProvider.select((value) => value.wantedPlayer))) {
|
|
PlayerOptions.libMPV => Column(
|
|
children: [
|
|
SettingsListTile(
|
|
label: Text(context.localized.settingsPlayerVideoHWAccelTitle),
|
|
subLabel: Text(context.localized.settingsPlayerVideoHWAccelDesc),
|
|
onTap: () => provider.setHardwareAccel(!videoSettings.hardwareAccel),
|
|
trailing: Switch(
|
|
value: videoSettings.hardwareAccel,
|
|
onChanged: (value) => provider.setHardwareAccel(value),
|
|
),
|
|
),
|
|
if (!kIsWeb) ...[
|
|
SettingsListTile(
|
|
label: Text(context.localized.settingsPlayerNativeLibassAccelTitle),
|
|
subLabel: Text(context.localized.settingsPlayerNativeLibassAccelDesc),
|
|
onTap: () => provider.setUseLibass(!videoSettings.useLibass),
|
|
trailing: Switch(
|
|
value: videoSettings.useLibass,
|
|
onChanged: (value) => provider.setUseLibass(value),
|
|
),
|
|
),
|
|
AnimatedFadeSize(
|
|
child: videoSettings.useLibass && videoSettings.hardwareAccel && Platform.isAndroid
|
|
? SettingsMessageBox(
|
|
context.localized.settingsPlayerMobileWarning,
|
|
messageType: MessageType.warning,
|
|
)
|
|
: Container(),
|
|
),
|
|
],
|
|
SettingsListTile(
|
|
label: Text(context.localized.settingsPlayerCustomSubtitlesTitle),
|
|
subLabel: Text(context.localized.settingsPlayerCustomSubtitlesDesc),
|
|
onTap: videoSettings.useLibass
|
|
? null
|
|
: () {
|
|
showDialog(
|
|
context: context,
|
|
barrierDismissible: false,
|
|
useSafeArea: false,
|
|
builder: (context) => const SubtitleEditor(),
|
|
);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
_ => SettingsMessageBox(
|
|
messageType: MessageType.info,
|
|
"${context.localized.noVideoPlayerOptions}\n${context.localized.mdkExperimental}")
|
|
},
|
|
),
|
|
SettingsListTile(
|
|
label: Text(context.localized.settingsAutoNextTitle),
|
|
subLabel: Text(context.localized.settingsAutoNextDesc),
|
|
trailing: EnumBox(
|
|
current: ref.watch(
|
|
videoPlayerSettingsProvider.select(
|
|
(value) => value.nextVideoType.label(context),
|
|
),
|
|
),
|
|
itemBuilder: (context) => AutoNextType.values
|
|
.map(
|
|
(entry) => PopupMenuItem(
|
|
value: entry,
|
|
child: Text(entry.label(context)),
|
|
onTap: () => ref.read(videoPlayerSettingsProvider.notifier).state =
|
|
ref.read(videoPlayerSettingsProvider).copyWith(nextVideoType: entry),
|
|
),
|
|
)
|
|
.toList(),
|
|
),
|
|
),
|
|
AnimatedFadeSize(
|
|
child: switch (ref.watch(videoPlayerSettingsProvider.select((value) => value.nextVideoType))) {
|
|
AutoNextType.smart => SettingsMessageBox(AutoNextType.smart.desc(context)),
|
|
AutoNextType.static => SettingsMessageBox(AutoNextType.static.desc(context)),
|
|
_ => const SizedBox.shrink(),
|
|
},
|
|
),
|
|
if (!AdaptiveLayout.of(context).isDesktop && !kIsWeb)
|
|
SettingsListTile(
|
|
label: Text(context.localized.playerSettingsOrientationTitle),
|
|
subLabel: Text(context.localized.playerSettingsOrientationDesc),
|
|
onTap: () => showOrientationOptions(context, ref),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|