video: custom playback buttons
This commit is contained in:
parent
9e64da8940
commit
e0b3f92b65
12 changed files with 76 additions and 56 deletions
|
@ -272,10 +272,7 @@
|
|||
|
||||
"settingsVideoEnablePip": "Picture-in-picture",
|
||||
|
||||
"videoControlsPlay": "Play",
|
||||
"videoControlsPlaySeek": "Play & seek backward/forward",
|
||||
"videoControlsPlayOutside": "Open with other player",
|
||||
"videoControlsNone": "None",
|
||||
|
||||
"videoLoopModeNever": "Never",
|
||||
"videoLoopModeShortOnly": "Short videos only",
|
||||
|
|
|
@ -133,7 +133,7 @@ class Settings with ChangeNotifier, SettingsAccess, AppSettings, DisplaySettings
|
|||
viewerGestureSideTapNext = false;
|
||||
viewerUseCutout = true;
|
||||
videoBackgroundMode = VideoBackgroundMode.disabled;
|
||||
videoControls = VideoControls.none;
|
||||
videoControlActions = [];
|
||||
videoGestureDoubleTapTogglePlay = false;
|
||||
videoGestureSideDoubleTapSeek = false;
|
||||
enableBin = false;
|
||||
|
@ -459,7 +459,6 @@ class Settings with ChangeNotifier, SettingsAccess, AppSettings, DisplaySettings
|
|||
case SettingKeys.videoBackgroundModeKey:
|
||||
case SettingKeys.videoLoopModeKey:
|
||||
case SettingKeys.videoResumptionModeKey:
|
||||
case SettingKeys.videoControlsKey:
|
||||
case SettingKeys.subtitleTextAlignmentKey:
|
||||
case SettingKeys.subtitleTextPositionKey:
|
||||
case SettingKeys.tagEditorExpandedSectionKey:
|
||||
|
@ -490,6 +489,7 @@ class Settings with ChangeNotifier, SettingsAccess, AppSettings, DisplaySettings
|
|||
case SettingKeys.collectionBrowsingQuickActionsKey:
|
||||
case SettingKeys.collectionSelectionQuickActionsKey:
|
||||
case SettingKeys.viewerQuickActionsKey:
|
||||
case SettingKeys.videoControlActionsKey:
|
||||
case SettingKeys.screenSaverCollectionFiltersKey:
|
||||
if (newValue is List) {
|
||||
store.setStringList(key, newValue.cast<String>());
|
||||
|
|
|
@ -47,7 +47,8 @@ extension ExtraEntryActionView on EntryAction {
|
|||
EntryAction.videoShowNextFrame => l10n.videoActionShowNextFrame,
|
||||
// external
|
||||
EntryAction.edit => l10n.entryActionEdit,
|
||||
EntryAction.open || EntryAction.openVideo => l10n.entryActionOpen,
|
||||
EntryAction.open => l10n.entryActionOpen,
|
||||
EntryAction.openVideo => l10n.videoControlsPlayOutside,
|
||||
EntryAction.openMap => l10n.entryActionOpenMap,
|
||||
EntryAction.setAs => l10n.entryActionSetAs,
|
||||
EntryAction.cast => l10n.entryActionCast,
|
||||
|
|
|
@ -174,18 +174,6 @@ extension ExtraVideoBackgroundModeView on VideoBackgroundMode {
|
|||
}
|
||||
}
|
||||
|
||||
extension ExtraVideoControlsView on VideoControls {
|
||||
String getName(BuildContext context) {
|
||||
final l10n = context.l10n;
|
||||
return switch (this) {
|
||||
VideoControls.play => l10n.videoControlsPlay,
|
||||
VideoControls.playSeek => l10n.videoControlsPlaySeek,
|
||||
VideoControls.playOutside => l10n.videoControlsPlayOutside,
|
||||
VideoControls.none => l10n.videoControlsNone,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
extension ExtraVideoLoopModeView on VideoLoopMode {
|
||||
String getName(BuildContext context) {
|
||||
final l10n = context.l10n;
|
||||
|
|
58
lib/widgets/settings/video/control_actions.dart
Normal file
58
lib/widgets/settings/video/control_actions.dart
Normal file
|
@ -0,0 +1,58 @@
|
|||
import 'package:aves/model/settings/settings.dart';
|
||||
import 'package:aves/view/view.dart';
|
||||
import 'package:aves/widgets/common/basic/scaffold.dart';
|
||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||
import 'package:aves_model/aves_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class VideoControlButtonsPage extends StatefulWidget {
|
||||
static const routeName = '/settings/video/control_buttons';
|
||||
|
||||
const VideoControlButtonsPage({super.key});
|
||||
|
||||
@override
|
||||
State<VideoControlButtonsPage> createState() => _VideoControlButtonsPageState();
|
||||
}
|
||||
|
||||
class _VideoControlButtonsPageState extends State<VideoControlButtonsPage> {
|
||||
late final Set<EntryAction> _selectedActions;
|
||||
|
||||
static const _availableActions = [...EntryActions.videoPlayback, EntryAction.openVideo];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_selectedActions = settings.videoControlActions.toSet();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AvesScaffold(
|
||||
appBar: AppBar(
|
||||
automaticallyImplyLeading: !settings.useTvLayout,
|
||||
title: Text(context.l10n.settingsViewerOverlayPageTitle),
|
||||
),
|
||||
body: SafeArea(
|
||||
child: PopScope(
|
||||
canPop: true,
|
||||
onPopInvokedWithResult: (didPop, result) => settings.videoControlActions = _availableActions.where(_selectedActions.contains).toList(),
|
||||
child: ListView(
|
||||
children: _availableActions.map((action) {
|
||||
return SwitchListTile(
|
||||
value: _selectedActions.contains(action),
|
||||
onChanged: (v) => setState(() {
|
||||
if (v) {
|
||||
_selectedActions.add(action);
|
||||
} else {
|
||||
_selectedActions.remove(action);
|
||||
}
|
||||
}),
|
||||
title: Text(action.getText(context)),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,9 +1,8 @@
|
|||
import 'package:aves/model/settings/settings.dart';
|
||||
import 'package:aves/view/view.dart';
|
||||
import 'package:aves/widgets/common/basic/scaffold.dart';
|
||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||
import 'package:aves/widgets/settings/common/tiles.dart';
|
||||
import 'package:aves_model/aves_model.dart';
|
||||
import 'package:aves/widgets/settings/video/control_actions.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class VideoControlsPage extends StatelessWidget {
|
||||
|
@ -20,12 +19,10 @@ class VideoControlsPage extends StatelessWidget {
|
|||
body: SafeArea(
|
||||
child: ListView(
|
||||
children: [
|
||||
SettingsSelectionListTile<VideoControls>(
|
||||
values: VideoControls.values,
|
||||
getName: (context, v) => v.getName(context),
|
||||
selector: (context, s) => s.videoControls,
|
||||
onSelection: (v) => settings.videoControls = v,
|
||||
tileTitle: context.l10n.settingsVideoButtonsTile,
|
||||
SettingsSubPageTile(
|
||||
title: context.l10n.settingsVideoButtonsTile,
|
||||
routeName: VideoControlButtonsPage.routeName,
|
||||
builder: (context) => const VideoControlButtonsPage(),
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
selector: (context, s) => s.videoGestureDoubleTapTogglePlay,
|
||||
|
|
|
@ -28,11 +28,9 @@ class VideoControlRow extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Selector<Settings, VideoControls>(
|
||||
selector: (context, s) => s.videoControls,
|
||||
builder: (context, videoControls, child) {
|
||||
final actions = _toActions(videoControls);
|
||||
|
||||
return Selector<Settings, List<EntryAction>>(
|
||||
selector: (context, s) => s.videoControlActions,
|
||||
builder: (context, actions, child) {
|
||||
if (actions.isEmpty) {
|
||||
return const SizedBox();
|
||||
}
|
||||
|
@ -65,23 +63,6 @@ class VideoControlRow extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
List<EntryAction> _toActions(VideoControls videoControls) {
|
||||
switch (videoControls) {
|
||||
case VideoControls.play:
|
||||
return [EntryAction.videoTogglePlay];
|
||||
case VideoControls.playSeek:
|
||||
return [
|
||||
EntryAction.videoReplay10,
|
||||
EntryAction.videoTogglePlay,
|
||||
EntryAction.videoSkip10,
|
||||
];
|
||||
case VideoControls.playOutside:
|
||||
return [EntryAction.openVideo];
|
||||
case VideoControls.none:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildOverlayButton(
|
||||
BuildContext context,
|
||||
EntryAction action, {
|
||||
|
|
|
@ -117,8 +117,6 @@ class EntryActions {
|
|||
EntryAction.videoToggleMute,
|
||||
EntryAction.videoSetSpeed,
|
||||
EntryAction.videoABRepeat,
|
||||
EntryAction.videoShowPreviousFrame,
|
||||
EntryAction.videoShowNextFrame,
|
||||
EntryAction.videoSelectStreams,
|
||||
EntryAction.videoSettings,
|
||||
EntryAction.lockViewer,
|
||||
|
@ -126,7 +124,9 @@ class EntryActions {
|
|||
|
||||
static const videoPlayback = [
|
||||
EntryAction.videoReplay10,
|
||||
EntryAction.videoShowPreviousFrame,
|
||||
EntryAction.videoTogglePlay,
|
||||
EntryAction.videoShowNextFrame,
|
||||
EntryAction.videoSkip10,
|
||||
];
|
||||
|
||||
|
|
|
@ -36,8 +36,6 @@ enum VideoAutoPlayMode { disabled, playMuted, playWithSound }
|
|||
|
||||
enum VideoBackgroundMode { disabled, pip }
|
||||
|
||||
enum VideoControls { play, playSeek, playOutside, none }
|
||||
|
||||
enum VideoLoopMode { never, shortOnly, always }
|
||||
|
||||
enum VideoResumptionMode { never, ask, always }
|
||||
|
|
|
@ -109,7 +109,7 @@ class SettingKeys {
|
|||
static const videoAutoPlayModeKey = 'video_auto_play_mode';
|
||||
static const videoLoopModeKey = 'video_loop';
|
||||
static const videoResumptionModeKey = 'video_resumption_mode';
|
||||
static const videoControlsKey = 'video_controls';
|
||||
static const videoControlActionsKey = 'video_control_actions';
|
||||
static const videoGestureDoubleTapTogglePlayKey = 'video_gesture_double_tap_toggle_play';
|
||||
static const videoGestureSideDoubleTapSeekKey = 'video_gesture_side_double_tap_skip';
|
||||
static const videoGestureVerticalDragBrightnessVolumeKey = 'video_gesture_vertical_drag_brightness_volume';
|
||||
|
|
|
@ -11,7 +11,7 @@ class SettingsDefaults {
|
|||
static const videoLoopMode = VideoLoopMode.shortOnly;
|
||||
static const videoResumptionMode = VideoResumptionMode.ask;
|
||||
static const videoShowRawTimedText = false;
|
||||
static const videoControls = VideoControls.play;
|
||||
static const videoControlActions = [EntryAction.videoTogglePlay];
|
||||
static const videoGestureDoubleTapTogglePlay = false;
|
||||
static const videoGestureSideDoubleTapSeek = true;
|
||||
static const videoGestureVerticalDragBrightnessVolume = false;
|
||||
|
|
|
@ -22,9 +22,9 @@ mixin VideoSettings on SettingsAccess {
|
|||
|
||||
set videoResumptionMode(VideoResumptionMode newValue) => set(SettingKeys.videoResumptionModeKey, newValue.toString());
|
||||
|
||||
VideoControls get videoControls => getEnumOrDefault(SettingKeys.videoControlsKey, SettingsDefaults.videoControls, VideoControls.values);
|
||||
List<EntryAction> get videoControlActions => getEnumListOrDefault(SettingKeys.videoControlActionsKey, SettingsDefaults.videoControlActions, EntryAction.values);
|
||||
|
||||
set videoControls(VideoControls newValue) => set(SettingKeys.videoControlsKey, newValue.toString());
|
||||
set videoControlActions(List<EntryAction> newValue) => set(SettingKeys.videoControlActionsKey, newValue.map((v) => v.toString()).toList());
|
||||
|
||||
bool get videoGestureDoubleTapTogglePlay => getBool(SettingKeys.videoGestureDoubleTapTogglePlayKey) ?? SettingsDefaults.videoGestureDoubleTapTogglePlay;
|
||||
|
||||
|
|
Loading…
Reference in a new issue