#334 collection: selection edit actions available as quick actions
This commit is contained in:
parent
9ba9ec302e
commit
59473dab64
13 changed files with 184 additions and 67 deletions
|
@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
- mosaic layout
|
- mosaic layout
|
||||||
- reverse filters to filter out/in
|
- reverse filters to filter out/in
|
||||||
|
- Collection: selection edit actions available as quick actions
|
||||||
- Albums: group by content type
|
- Albums: group by content type
|
||||||
- Stats: top albums
|
- Stats: top albums
|
||||||
- Stats: open full top listings
|
- Stats: open full top listings
|
||||||
|
|
|
@ -83,7 +83,7 @@ class EntrySetActions {
|
||||||
];
|
];
|
||||||
|
|
||||||
// exclude bin related actions
|
// exclude bin related actions
|
||||||
static const collectionEditorSelection = [
|
static const collectionEditorSelectionRegular = [
|
||||||
EntrySetAction.share,
|
EntrySetAction.share,
|
||||||
EntrySetAction.delete,
|
EntrySetAction.delete,
|
||||||
EntrySetAction.copy,
|
EntrySetAction.copy,
|
||||||
|
@ -97,6 +97,18 @@ class EntrySetActions {
|
||||||
// editing actions are in their subsection
|
// editing actions are in their subsection
|
||||||
];
|
];
|
||||||
|
|
||||||
|
static const collectionEditorSelectionEdit = [
|
||||||
|
EntrySetAction.rotateCCW,
|
||||||
|
EntrySetAction.rotateCW,
|
||||||
|
EntrySetAction.flip,
|
||||||
|
EntrySetAction.editDate,
|
||||||
|
EntrySetAction.editLocation,
|
||||||
|
EntrySetAction.editTitleDescription,
|
||||||
|
EntrySetAction.editRating,
|
||||||
|
EntrySetAction.editTags,
|
||||||
|
EntrySetAction.removeMetadata,
|
||||||
|
];
|
||||||
|
|
||||||
static const edit = [
|
static const edit = [
|
||||||
EntrySetAction.editDate,
|
EntrySetAction.editDate,
|
||||||
EntrySetAction.editLocation,
|
EntrySetAction.editLocation,
|
||||||
|
|
|
@ -312,6 +312,11 @@ class Constants {
|
||||||
license: 'MIT',
|
license: 'MIT',
|
||||||
sourceUrl: 'https://github.com/rrousselGit/provider',
|
sourceUrl: 'https://github.com/rrousselGit/provider',
|
||||||
),
|
),
|
||||||
|
Dependency(
|
||||||
|
name: 'Smooth Page Indicator',
|
||||||
|
license: 'MIT',
|
||||||
|
sourceUrl: 'https://github.com/Milad-Akarie/smooth_page_indicator',
|
||||||
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
static const List<Dependency> dartPackages = [
|
static const List<Dependency> dartPackages = [
|
||||||
|
|
|
@ -318,7 +318,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
title: context.l10n.collectionActionEdit,
|
title: context.l10n.collectionActionEdit,
|
||||||
items: [
|
items: [
|
||||||
_buildRotateAndFlipMenuItems(context, canApply: canApply),
|
_buildRotateAndFlipMenuItems(context, canApply: canApply),
|
||||||
...EntrySetActions.edit.where(isVisible).map((action) => _toMenuItem(action, enabled: canApply(action), selection: selection)),
|
...EntrySetActions.edit.where((v) => isVisible(v) && !selectionQuickActions.contains(v)).map((action) => _toMenuItem(action, enabled: canApply(action), selection: selection)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -15,14 +15,10 @@ class TileExtentControllerProvider extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return LayoutBuilder(
|
return LayoutBuilder(
|
||||||
builder: (context, constraints) {
|
builder: (context, constraints) => ProxyProvider0<TileExtentController>(
|
||||||
return LayoutBuilder(
|
update: (context, __) => controller..setViewportSize(constraints.biggest),
|
||||||
builder: (context, constraints) => ProxyProvider0<TileExtentController>(
|
child: child,
|
||||||
update: (context, __) => controller..setViewportSize(constraints.biggest),
|
),
|
||||||
child: child,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:aves/widgets/viewer/overlay/common.dart';
|
import 'package:aves/widgets/viewer/overlay/common.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/rendering.dart';
|
||||||
|
|
||||||
class ActionButton extends StatelessWidget {
|
class ActionButton extends StatelessWidget {
|
||||||
final String text;
|
final String text;
|
||||||
|
@ -14,13 +15,14 @@ class ActionButton extends StatelessWidget {
|
||||||
this.showCaption = true,
|
this.showCaption = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
static const padding = 8.0;
|
static const int maxLines = 2;
|
||||||
|
static const double padding = 8;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final textStyle = Theme.of(context).textTheme.caption;
|
final textStyle = _textStyle(context);
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
width: OverlayButton.getSize(context) + padding * 2,
|
width: _width(context),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
|
@ -35,10 +37,10 @@ class ActionButton extends StatelessWidget {
|
||||||
const SizedBox(height: padding),
|
const SizedBox(height: padding),
|
||||||
Text(
|
Text(
|
||||||
text,
|
text,
|
||||||
style: enabled ? textStyle : textStyle!.copyWith(color: textStyle.color!.withOpacity(.2)),
|
style: enabled ? textStyle : textStyle.copyWith(color: textStyle.color!.withOpacity(.2)),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
maxLines: 2,
|
maxLines: maxLines,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
const SizedBox(height: padding),
|
const SizedBox(height: padding),
|
||||||
|
@ -46,4 +48,23 @@ class ActionButton extends StatelessWidget {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static TextStyle _textStyle(BuildContext context) => Theme.of(context).textTheme.caption!;
|
||||||
|
|
||||||
|
static double _width(BuildContext context) => OverlayButton.getSize(context) + padding * 2;
|
||||||
|
|
||||||
|
static Size getSize(BuildContext context, String text, {required bool showCaption}) {
|
||||||
|
final width = _width(context);
|
||||||
|
var height = width;
|
||||||
|
if (showCaption) {
|
||||||
|
final para = RenderParagraph(
|
||||||
|
TextSpan(text: text, style: _textStyle(context)),
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
textScaleFactor: MediaQuery.textScaleFactorOf(context),
|
||||||
|
maxLines: maxLines,
|
||||||
|
)..layout(const BoxConstraints(), parentUsesSize: true);
|
||||||
|
height += para.getMaxIntrinsicHeight(width) + padding;
|
||||||
|
}
|
||||||
|
return Size(width, height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,12 @@ class ActionPanel extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final color = highlight ? Theme.of(context).colorScheme.secondary : Colors.blueGrey;
|
final theme = Theme.of(context);
|
||||||
|
final color = highlight
|
||||||
|
? theme.colorScheme.secondary
|
||||||
|
: theme.brightness == Brightness.dark
|
||||||
|
? Colors.blueGrey
|
||||||
|
: Colors.blueGrey.shade100;
|
||||||
return AnimatedContainer(
|
return AnimatedContainer(
|
||||||
foregroundDecoration: BoxDecoration(
|
foregroundDecoration: BoxDecoration(
|
||||||
color: color.withOpacity(.2),
|
color: color.withOpacity(.2),
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
|
||||||
import 'package:aves/widgets/settings/common/quick_actions/action_button.dart';
|
import 'package:aves/widgets/settings/common/quick_actions/action_button.dart';
|
||||||
import 'package:aves/widgets/settings/common/quick_actions/placeholder.dart';
|
import 'package:aves/widgets/settings/common/quick_actions/placeholder.dart';
|
||||||
import 'package:aves/widgets/viewer/overlay/common.dart';
|
import 'package:aves/widgets/viewer/overlay/common.dart';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
@ -15,6 +16,9 @@ class AvailableActionPanel<T extends Object> extends StatelessWidget {
|
||||||
final Widget? Function(T action) actionIcon;
|
final Widget? Function(T action) actionIcon;
|
||||||
final String Function(BuildContext context, T action) actionText;
|
final String Function(BuildContext context, T action) actionText;
|
||||||
|
|
||||||
|
static const double spacing = 8;
|
||||||
|
static const padding = EdgeInsets.all(spacing);
|
||||||
|
|
||||||
const AvailableActionPanel({
|
const AvailableActionPanel({
|
||||||
super.key,
|
super.key,
|
||||||
required this.allActions,
|
required this.allActions,
|
||||||
|
@ -46,26 +50,28 @@ class AvailableActionPanel<T extends Object> extends StatelessWidget {
|
||||||
builder: (context, accepted, rejected) {
|
builder: (context, accepted, rejected) {
|
||||||
return AnimatedBuilder(
|
return AnimatedBuilder(
|
||||||
animation: Listenable.merge([quickActionsChangeNotifier, draggedAvailableAction]),
|
animation: Listenable.merge([quickActionsChangeNotifier, draggedAvailableAction]),
|
||||||
builder: (context, child) => Padding(
|
builder: (context, child) {
|
||||||
padding: const EdgeInsets.all(8),
|
return Padding(
|
||||||
child: Wrap(
|
padding: padding,
|
||||||
alignment: WrapAlignment.spaceEvenly,
|
child: Wrap(
|
||||||
spacing: 8,
|
alignment: WrapAlignment.spaceEvenly,
|
||||||
runSpacing: 8,
|
spacing: spacing,
|
||||||
children: allActions.map((action) {
|
runSpacing: spacing,
|
||||||
final dragged = action == draggedAvailableAction.value;
|
children: allActions.map((action) {
|
||||||
final enabled = dragged || !quickActions.contains(action);
|
final dragged = action == draggedAvailableAction.value;
|
||||||
var child = _buildActionButton(context, action, enabled: enabled);
|
final enabled = dragged || !quickActions.contains(action);
|
||||||
if (dragged) {
|
var child = _buildActionButton(context, action, enabled: enabled);
|
||||||
child = DraggedPlaceholder(child: child);
|
if (dragged) {
|
||||||
}
|
child = DraggedPlaceholder(child: child);
|
||||||
if (enabled) {
|
}
|
||||||
child = _buildDraggable(context, action, child);
|
if (enabled) {
|
||||||
}
|
child = _buildDraggable(context, action, child);
|
||||||
return child;
|
}
|
||||||
}).toList(),
|
return child;
|
||||||
),
|
}).toList(),
|
||||||
),
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -113,4 +119,16 @@ class AvailableActionPanel<T extends Object> extends StatelessWidget {
|
||||||
void _setDraggedAvailableAction(T? action) => draggedAvailableAction.value = action;
|
void _setDraggedAvailableAction(T? action) => draggedAvailableAction.value = action;
|
||||||
|
|
||||||
void _setPanelHighlight(bool flag) => panelHighlight.value = flag;
|
void _setPanelHighlight(bool flag) => panelHighlight.value = flag;
|
||||||
|
|
||||||
|
static double heightFor(BuildContext context, List<String> captions, double width) {
|
||||||
|
final buttonSizes = captions.map((v) => ActionButton.getSize(context, v, showCaption: true));
|
||||||
|
final actionsPerRun = (width - padding.horizontal + spacing) ~/ (buttonSizes.first.width + spacing);
|
||||||
|
final runCount = (captions.length / actionsPerRun).ceil();
|
||||||
|
var height = .0;
|
||||||
|
for (var i = 0; i < runCount; i++) {
|
||||||
|
height += buttonSizes.skip(i * actionsPerRun).take(actionsPerRun).map((v) => v.height).max;
|
||||||
|
}
|
||||||
|
height += spacing * (runCount - 1) + padding.vertical;
|
||||||
|
return height;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,12 +12,14 @@ import 'package:aves/widgets/settings/common/quick_actions/available_actions.dar
|
||||||
import 'package:aves/widgets/settings/common/quick_actions/placeholder.dart';
|
import 'package:aves/widgets/settings/common/quick_actions/placeholder.dart';
|
||||||
import 'package:aves/widgets/settings/common/quick_actions/quick_actions.dart';
|
import 'package:aves/widgets/settings/common/quick_actions/quick_actions.dart';
|
||||||
import 'package:aves/widgets/viewer/overlay/common.dart';
|
import 'package:aves/widgets/viewer/overlay/common.dart';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
|
||||||
|
|
||||||
class QuickActionEditorPage<T extends Object> extends StatelessWidget {
|
class QuickActionEditorPage<T extends Object> extends StatelessWidget {
|
||||||
final String title, bannerText;
|
final String title, bannerText;
|
||||||
final List<T> allAvailableActions;
|
final List<List<T>> allAvailableActions;
|
||||||
final Widget? Function(T action) actionIcon;
|
final Widget? Function(T action) actionIcon;
|
||||||
final String Function(BuildContext context, T action) actionText;
|
final String Function(BuildContext context, T action) actionText;
|
||||||
final List<T> Function() load;
|
final List<T> Function() load;
|
||||||
|
@ -58,7 +60,7 @@ class QuickActionEditorPage<T extends Object> extends StatelessWidget {
|
||||||
|
|
||||||
class QuickActionEditorBody<T extends Object> extends StatefulWidget {
|
class QuickActionEditorBody<T extends Object> extends StatefulWidget {
|
||||||
final String bannerText;
|
final String bannerText;
|
||||||
final List<T> allAvailableActions;
|
final List<List<T>> allAvailableActions;
|
||||||
final Widget? Function(T action) actionIcon;
|
final Widget? Function(T action) actionIcon;
|
||||||
final String Function(BuildContext context, T action) actionText;
|
final String Function(BuildContext context, T action) actionText;
|
||||||
final List<T> Function() load;
|
final List<T> Function() load;
|
||||||
|
@ -87,6 +89,7 @@ class _QuickActionEditorBodyState<T extends Object> extends State<QuickActionEdi
|
||||||
final ValueNotifier<bool> _quickActionHighlight = ValueNotifier(false);
|
final ValueNotifier<bool> _quickActionHighlight = ValueNotifier(false);
|
||||||
final ValueNotifier<bool> _availableActionHighlight = ValueNotifier(false);
|
final ValueNotifier<bool> _availableActionHighlight = ValueNotifier(false);
|
||||||
final AChangeNotifier _quickActionsChangeNotifier = AChangeNotifier();
|
final AChangeNotifier _quickActionsChangeNotifier = AChangeNotifier();
|
||||||
|
final PageController _availableActionPageController = PageController();
|
||||||
|
|
||||||
// use a flag to prevent quick action target accept/leave when already animating reorder
|
// use a flag to prevent quick action target accept/leave when already animating reorder
|
||||||
// as dragging a button against axis direction messes index resolution while items pop in and out
|
// as dragging a button against axis direction messes index resolution while items pop in and out
|
||||||
|
@ -119,6 +122,8 @@ class _QuickActionEditorBodyState<T extends Object> extends State<QuickActionEdi
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
super.build(context);
|
super.build(context);
|
||||||
|
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
final colorScheme = theme.colorScheme;
|
||||||
final header = QuickActionButton<T>(
|
final header = QuickActionButton<T>(
|
||||||
placement: QuickActionPlacement.header,
|
placement: QuickActionPlacement.header,
|
||||||
panelHighlight: _quickActionHighlight,
|
panelHighlight: _quickActionHighlight,
|
||||||
|
@ -222,7 +227,7 @@ class _QuickActionEditorBodyState<T extends Object> extends State<QuickActionEdi
|
||||||
? Center(
|
? Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
context.l10n.settingsViewerQuickActionEmpty,
|
context.l10n.settingsViewerQuickActionEmpty,
|
||||||
style: Theme.of(context).textTheme.caption,
|
style: theme.textTheme.caption,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: const SizedBox(),
|
: const SizedBox(),
|
||||||
|
@ -244,16 +249,55 @@ class _QuickActionEditorBodyState<T extends Object> extends State<QuickActionEdi
|
||||||
highlight: highlight,
|
highlight: highlight,
|
||||||
child: child!,
|
child: child!,
|
||||||
),
|
),
|
||||||
child: AvailableActionPanel<T>(
|
child: LayoutBuilder(
|
||||||
allActions: widget.allAvailableActions,
|
builder: (context, constraints) {
|
||||||
quickActions: _quickActions,
|
final allAvailableActions = widget.allAvailableActions;
|
||||||
quickActionsChangeNotifier: _quickActionsChangeNotifier,
|
final maxWidth = constraints.maxWidth;
|
||||||
panelHighlight: _availableActionHighlight,
|
final maxHeight = allAvailableActions
|
||||||
draggedQuickAction: _draggedQuickAction,
|
.map((page) => AvailableActionPanel.heightFor(
|
||||||
draggedAvailableAction: _draggedAvailableAction,
|
context,
|
||||||
removeQuickAction: _removeQuickAction,
|
page.map((v) => widget.actionText(context, v)).toList(),
|
||||||
actionIcon: widget.actionIcon,
|
maxWidth,
|
||||||
actionText: widget.actionText,
|
))
|
||||||
|
.max;
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
if (allAvailableActions.length > 1)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 8),
|
||||||
|
child: SmoothPageIndicator(
|
||||||
|
controller: _availableActionPageController,
|
||||||
|
count: allAvailableActions.length,
|
||||||
|
effect: WormEffect(
|
||||||
|
dotWidth: 8,
|
||||||
|
dotHeight: 8,
|
||||||
|
dotColor: colorScheme.onPrimary.withOpacity(.3),
|
||||||
|
activeDotColor: colorScheme.secondary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: maxHeight,
|
||||||
|
child: PageView(
|
||||||
|
controller: _availableActionPageController,
|
||||||
|
children: allAvailableActions
|
||||||
|
.map((allActions) => AvailableActionPanel<T>(
|
||||||
|
allActions: allActions,
|
||||||
|
quickActions: _quickActions,
|
||||||
|
quickActionsChangeNotifier: _quickActionsChangeNotifier,
|
||||||
|
panelHighlight: _availableActionHighlight,
|
||||||
|
draggedQuickAction: _draggedQuickAction,
|
||||||
|
draggedAvailableAction: _draggedAvailableAction,
|
||||||
|
removeQuickAction: _removeQuickAction,
|
||||||
|
actionIcon: widget.actionIcon,
|
||||||
|
actionText: widget.actionText,
|
||||||
|
))
|
||||||
|
.toList(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -19,7 +19,7 @@ class CollectionActionEditorPage extends StatelessWidget {
|
||||||
Tab(text: l10n.settingsCollectionQuickActionTabBrowsing),
|
Tab(text: l10n.settingsCollectionQuickActionTabBrowsing),
|
||||||
QuickActionEditorBody<EntrySetAction>(
|
QuickActionEditorBody<EntrySetAction>(
|
||||||
bannerText: context.l10n.settingsCollectionBrowsingQuickActionEditorBanner,
|
bannerText: context.l10n.settingsCollectionBrowsingQuickActionEditorBanner,
|
||||||
allAvailableActions: EntrySetActions.collectionEditorBrowsing,
|
allAvailableActions: const [EntrySetActions.collectionEditorBrowsing],
|
||||||
actionIcon: (action) => action.getIcon(),
|
actionIcon: (action) => action.getIcon(),
|
||||||
actionText: (context, action) => action.getText(context),
|
actionText: (context, action) => action.getText(context),
|
||||||
load: () => settings.collectionBrowsingQuickActions,
|
load: () => settings.collectionBrowsingQuickActions,
|
||||||
|
@ -30,7 +30,10 @@ class CollectionActionEditorPage extends StatelessWidget {
|
||||||
Tab(text: l10n.settingsCollectionQuickActionTabSelecting),
|
Tab(text: l10n.settingsCollectionQuickActionTabSelecting),
|
||||||
QuickActionEditorBody<EntrySetAction>(
|
QuickActionEditorBody<EntrySetAction>(
|
||||||
bannerText: context.l10n.settingsCollectionSelectionQuickActionEditorBanner,
|
bannerText: context.l10n.settingsCollectionSelectionQuickActionEditorBanner,
|
||||||
allAvailableActions: EntrySetActions.collectionEditorSelection,
|
allAvailableActions: const [
|
||||||
|
EntrySetActions.collectionEditorSelectionRegular,
|
||||||
|
EntrySetActions.collectionEditorSelectionEdit,
|
||||||
|
],
|
||||||
actionIcon: (action) => action.getIcon(),
|
actionIcon: (action) => action.getIcon(),
|
||||||
actionText: (context, action) => action.getText(context),
|
actionText: (context, action) => action.getText(context),
|
||||||
load: () => settings.collectionSelectionQuickActions,
|
load: () => settings.collectionSelectionQuickActions,
|
||||||
|
|
|
@ -10,22 +10,26 @@ class ViewerActionEditorPage extends StatelessWidget {
|
||||||
const ViewerActionEditorPage({super.key});
|
const ViewerActionEditorPage({super.key});
|
||||||
|
|
||||||
static const allAvailableActions = [
|
static const allAvailableActions = [
|
||||||
EntryAction.share,
|
[
|
||||||
EntryAction.edit,
|
EntryAction.share,
|
||||||
EntryAction.rename,
|
EntryAction.edit,
|
||||||
EntryAction.delete,
|
EntryAction.rename,
|
||||||
EntryAction.copy,
|
EntryAction.delete,
|
||||||
EntryAction.move,
|
EntryAction.copy,
|
||||||
EntryAction.toggleFavourite,
|
EntryAction.move,
|
||||||
EntryAction.rotateScreen,
|
EntryAction.toggleFavourite,
|
||||||
EntryAction.videoCaptureFrame,
|
EntryAction.rotateScreen,
|
||||||
EntryAction.videoToggleMute,
|
EntryAction.viewSource,
|
||||||
EntryAction.videoSetSpeed,
|
EntryAction.rotateCCW,
|
||||||
EntryAction.videoSelectStreams,
|
EntryAction.rotateCW,
|
||||||
EntryAction.viewSource,
|
EntryAction.flip,
|
||||||
EntryAction.rotateCCW,
|
],
|
||||||
EntryAction.rotateCW,
|
[
|
||||||
EntryAction.flip,
|
EntryAction.videoCaptureFrame,
|
||||||
|
EntryAction.videoToggleMute,
|
||||||
|
EntryAction.videoSetSpeed,
|
||||||
|
EntryAction.videoSelectStreams,
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -1045,6 +1045,13 @@ packages:
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.99"
|
version: "0.0.99"
|
||||||
|
smooth_page_indicator:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: smooth_page_indicator
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0+2"
|
||||||
source_map_stack_trace:
|
source_map_stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -75,6 +75,7 @@ dependencies:
|
||||||
provider:
|
provider:
|
||||||
screen_brightness:
|
screen_brightness:
|
||||||
shared_preferences:
|
shared_preferences:
|
||||||
|
smooth_page_indicator:
|
||||||
sqflite:
|
sqflite:
|
||||||
streams_channel:
|
streams_channel:
|
||||||
git:
|
git:
|
||||||
|
|
Loading…
Reference in a new issue