settings: video controls preview
This commit is contained in:
parent
da959874fc
commit
71efe696c1
4 changed files with 76 additions and 69 deletions
|
@ -7,7 +7,8 @@ All notable changes to this project will be documented in this file.
|
|||
### Added
|
||||
|
||||
- Map: create shortcut to custom region and filters
|
||||
- Video: frame stepping forward/backward actions
|
||||
- Video: frame stepping forward/backward
|
||||
- Video: custom playback buttons
|
||||
- English (Shavian) translation (thanks Paranoid Android)
|
||||
|
||||
### Changed
|
||||
|
|
|
@ -2,55 +2,67 @@ 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/common/identity/buttons/overlay_button.dart';
|
||||
import 'package:aves/widgets/settings/common/quick_actions/action_panel.dart';
|
||||
import 'package:aves/widgets/viewer/overlay/video/controls.dart';
|
||||
import 'package:aves_model/aves_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class VideoControlButtonsPage extends StatefulWidget {
|
||||
class VideoControlButtonsPage extends StatelessWidget {
|
||||
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.openVideoPlayer];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_selectedActions = settings.videoControlActions.toSet();
|
||||
}
|
||||
const VideoControlButtonsPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AvesScaffold(
|
||||
appBar: AppBar(
|
||||
automaticallyImplyLeading: !settings.useTvLayout,
|
||||
title: Text(context.l10n.settingsViewerOverlayPageTitle),
|
||||
title: Text(context.l10n.settingsVideoControlsPageTitle),
|
||||
),
|
||||
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(),
|
||||
),
|
||||
child: Selector<Settings, List<EntryAction>>(
|
||||
selector: (context, s) => s.videoControlActions,
|
||||
builder: (context, selectedActionList, child) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
ActionPanel(
|
||||
child: Container(
|
||||
alignment: AlignmentDirectional.center,
|
||||
height: OverlayButton.getSize(context) + 48,
|
||||
child: selectedActionList.isNotEmpty
|
||||
? VideoControlRow(onActionSelected: (_) {})
|
||||
: Text(
|
||||
context.l10n.settingsViewerQuickActionEmpty,
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ListView(
|
||||
children: _availableActions.map((action) {
|
||||
return SwitchListTile(
|
||||
value: selectedActionList.contains(action),
|
||||
onChanged: (v) {
|
||||
final selectedActionSet = settings.videoControlActions.toSet();
|
||||
if (v) {
|
||||
selectedActionSet.add(action);
|
||||
} else {
|
||||
selectedActionSet.remove(action);
|
||||
}
|
||||
settings.videoControlActions = _availableActions.where(selectedActionSet.contains).toList();
|
||||
},
|
||||
title: Text(action.getText(context)),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:aves/model/entry/entry.dart';
|
||||
import 'package:aves/model/settings/settings.dart';
|
||||
import 'package:aves/view/view.dart';
|
||||
import 'package:aves/widgets/common/action_controls/togglers/play.dart';
|
||||
|
@ -10,9 +9,9 @@ import 'package:flutter/material.dart';
|
|||
import 'package:provider/provider.dart';
|
||||
|
||||
class VideoControlRow extends StatelessWidget {
|
||||
final AvesEntry entry;
|
||||
final AvesVideoController? controller;
|
||||
final Animation<double> scale;
|
||||
final bool canOpenVideoPlayer;
|
||||
final Function(EntryAction value) onActionSelected;
|
||||
|
||||
static const double padding = 8;
|
||||
|
@ -20,9 +19,9 @@ class VideoControlRow extends StatelessWidget {
|
|||
|
||||
const VideoControlRow({
|
||||
super.key,
|
||||
required this.entry,
|
||||
required this.controller,
|
||||
required this.scale,
|
||||
this.controller,
|
||||
this.scale = kAlwaysCompleteAnimation,
|
||||
this.canOpenVideoPlayer = true,
|
||||
required this.onActionSelected,
|
||||
});
|
||||
|
||||
|
@ -31,29 +30,22 @@ class VideoControlRow extends StatelessWidget {
|
|||
return Selector<Settings, List<EntryAction>>(
|
||||
selector: (context, s) => s.videoControlActions,
|
||||
builder: (context, actions, child) {
|
||||
if (actions.isEmpty) {
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
if (actions.length == 1) {
|
||||
final action = actions.first;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: padding),
|
||||
child: _buildOverlayButton(context, action, const BorderRadius.all(radius)),
|
||||
);
|
||||
}
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: padding),
|
||||
padding: EdgeInsets.only(left: actions.isEmpty ? 0 : padding),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
textDirection: ViewerBottomOverlay.actionsDirection,
|
||||
children: actions.map((action) {
|
||||
var borderRadius = BorderRadius.zero;
|
||||
if (action == actions.first) {
|
||||
borderRadius = const BorderRadius.horizontal(left: radius);
|
||||
} else if (action == actions.last) {
|
||||
borderRadius = const BorderRadius.horizontal(right: radius);
|
||||
// null radius yields a circular button
|
||||
BorderRadius? borderRadius;
|
||||
if (actions.length > 1) {
|
||||
// zero radius yields a square button
|
||||
borderRadius = BorderRadius.zero;
|
||||
if (action == actions.first) {
|
||||
borderRadius = const BorderRadius.horizontal(left: radius);
|
||||
} else if (action == actions.last) {
|
||||
borderRadius = const BorderRadius.horizontal(right: radius);
|
||||
}
|
||||
}
|
||||
return _buildOverlayButton(context, action, borderRadius);
|
||||
}).toList(),
|
||||
|
@ -66,7 +58,7 @@ class VideoControlRow extends StatelessWidget {
|
|||
Widget _buildOverlayButton(
|
||||
BuildContext context,
|
||||
EntryAction action,
|
||||
BorderRadius borderRadius,
|
||||
BorderRadius? borderRadius,
|
||||
) {
|
||||
Widget child;
|
||||
if (action == EntryAction.videoTogglePlay) {
|
||||
|
@ -75,7 +67,7 @@ class VideoControlRow extends StatelessWidget {
|
|||
onPressed: () => onActionSelected(action),
|
||||
);
|
||||
} else {
|
||||
final enabled = action == EntryAction.openVideoPlayer ? !entry.trashed : true;
|
||||
final enabled = action == EntryAction.openVideoPlayer ? canOpenVideoPlayer : true;
|
||||
child = IconButton(
|
||||
icon: action.getIcon(),
|
||||
onPressed: enabled ? () => onActionSelected(action) : null,
|
||||
|
@ -83,13 +75,15 @@ class VideoControlRow extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
child = Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: borderRadius.topLeft.x > 0 ? padding / 3 : 0,
|
||||
right: borderRadius.topRight.x > 0 ? padding / 3 : 0,
|
||||
),
|
||||
child: child,
|
||||
);
|
||||
if (borderRadius != null) {
|
||||
child = Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: borderRadius.topLeft.x > 0 ? padding / 3 : 0,
|
||||
right: borderRadius.topRight.x > 0 ? padding / 3 : 0,
|
||||
),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
|
||||
return OverlayButton(
|
||||
scale: scale,
|
||||
|
|
|
@ -78,9 +78,9 @@ class _VideoControlOverlayState extends State<VideoControlOverlay> with SingleTi
|
|||
),
|
||||
),
|
||||
VideoControlRow(
|
||||
entry: entry,
|
||||
controller: controller,
|
||||
scale: scale,
|
||||
canOpenVideoPlayer: !entry.trashed,
|
||||
onActionSelected: widget.onActionSelected,
|
||||
),
|
||||
],
|
||||
|
|
Loading…
Reference in a new issue