error report logs
This commit is contained in:
parent
32bbee8bfd
commit
19cdfcf23f
38 changed files with 97 additions and 8 deletions
|
@ -354,6 +354,7 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
||||||
@override
|
@override
|
||||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||||
debugPrint('$runtimeType lifecycle ${state.name}');
|
debugPrint('$runtimeType lifecycle ${state.name}');
|
||||||
|
reportService.log('Lifecycle ${state.name}');
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case AppLifecycleState.inactive:
|
case AppLifecycleState.inactive:
|
||||||
switch (_appModeNotifier.value) {
|
switch (_appModeNotifier.value) {
|
||||||
|
@ -557,7 +558,7 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
||||||
// do not reset when relaunching the app
|
// do not reset when relaunching the app
|
||||||
if (_appModeNotifier.value == AppMode.main && (intentData == null || intentData.isEmpty == true)) return;
|
if (_appModeNotifier.value == AppMode.main && (intentData == null || intentData.isEmpty == true)) return;
|
||||||
|
|
||||||
reportService.log('New intent');
|
reportService.log('New intent data=$intentData');
|
||||||
AvesApp.navigatorKey.currentState!.pushReplacement(DirectMaterialPageRoute(
|
AvesApp.navigatorKey.currentState!.pushReplacement(DirectMaterialPageRoute(
|
||||||
settings: const RouteSettings(name: HomePage.routeName),
|
settings: const RouteSettings(name: HomePage.routeName),
|
||||||
builder: (_) => _getFirstPage(intentData: intentData),
|
builder: (_) => _getFirstPage(intentData: intentData),
|
||||||
|
|
|
@ -666,6 +666,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
tileExtentController: extentController,
|
tileExtentController: extentController,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
routeSettings: const RouteSettings(name: TileViewDialog.routeName),
|
||||||
);
|
);
|
||||||
// wait for the dialog to hide as applying the change may block the UI
|
// wait for the dialog to hide as applying the change may block the UI
|
||||||
await Future.delayed(Durations.dialogTransitionAnimation * timeDilation);
|
await Future.delayed(Durations.dialogTransitionAnimation * timeDilation);
|
||||||
|
|
|
@ -160,6 +160,7 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware
|
||||||
}
|
}
|
||||||
|
|
||||||
void onActionSelected(BuildContext context, EntrySetAction action) {
|
void onActionSelected(BuildContext context, EntrySetAction action) {
|
||||||
|
reportService.log('$action');
|
||||||
switch (action) {
|
switch (action) {
|
||||||
// general
|
// general
|
||||||
case EntrySetAction.configureView:
|
case EntrySetAction.configureView:
|
||||||
|
@ -266,6 +267,7 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware
|
||||||
content: Text(context.l10n.tooManyItemsErrorDialogMessage),
|
content: Text(context.l10n.tooManyItemsErrorDialogMessage),
|
||||||
actions: const [OkButton()],
|
actions: const [OkButton()],
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: AvesDialog.warningRouteName),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -471,6 +473,7 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: AvesDialog.warningRouteName),
|
||||||
);
|
);
|
||||||
if (confirmed == null || !confirmed) return null;
|
if (confirmed == null || !confirmed) return null;
|
||||||
|
|
||||||
|
@ -550,6 +553,7 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: AvesDialog.warningRouteName),
|
||||||
);
|
);
|
||||||
if (confirmed == null || !confirmed) return;
|
if (confirmed == null || !confirmed) return;
|
||||||
|
|
||||||
|
@ -694,6 +698,7 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware
|
||||||
defaultName: defaultName ?? '',
|
defaultName: defaultName ?? '',
|
||||||
collection: collection,
|
collection: collection,
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: AddShortcutDialog.routeName),
|
||||||
);
|
);
|
||||||
if (result == null) return;
|
if (result == null) return;
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ mixin EntryEditorMixin {
|
||||||
entry: entries.first,
|
entry: entries.first,
|
||||||
collection: collection,
|
collection: collection,
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: EditEntryDateDialog.routeName),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +45,7 @@ mixin EntryEditorMixin {
|
||||||
entry: entry,
|
entry: entry,
|
||||||
collection: collection,
|
collection: collection,
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: EditEntryLocationDialog.routeName),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,6 +62,7 @@ mixin EntryEditorMixin {
|
||||||
initialTitle: initialTitle,
|
initialTitle: initialTitle,
|
||||||
initialDescription: initialDescription,
|
initialDescription: initialDescription,
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: EditEntryTitleDescriptionDialog.routeName),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,6 +74,7 @@ mixin EntryEditorMixin {
|
||||||
builder: (context) => EditEntryRatingDialog(
|
builder: (context) => EditEntryRatingDialog(
|
||||||
entry: entries.first,
|
entry: entries.first,
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: EditEntryRatingDialog.routeName),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,6 +120,7 @@ mixin EntryEditorMixin {
|
||||||
builder: (context) => RemoveEntryMetadataDialog(
|
builder: (context) => RemoveEntryMetadataDialog(
|
||||||
showJpegTypes: entries.any((entry) => entry.mimeType == MimeTypes.jpeg),
|
showJpegTypes: entries.any((entry) => entry.mimeType == MimeTypes.jpeg),
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: RemoveEntryMetadataDialog.routeName),
|
||||||
);
|
);
|
||||||
if (types == null || types.isEmpty) return null;
|
if (types == null || types.isEmpty) return null;
|
||||||
|
|
||||||
|
@ -132,6 +137,7 @@ mixin EntryEditorMixin {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: AvesDialog.warningRouteName),
|
||||||
);
|
);
|
||||||
if (confirmed == null || !confirmed) return null;
|
if (confirmed == null || !confirmed) return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,6 +80,7 @@ mixin EntryStorageMixin on FeedbackMixin, PermissionAwareMixin, SizeAwareMixin {
|
||||||
message: originAlbums.length == 1 ? l10n.nameConflictDialogSingleSourceMessage : l10n.nameConflictDialogMultipleSourceMessage,
|
message: originAlbums.length == 1 ? l10n.nameConflictDialogSingleSourceMessage : l10n.nameConflictDialogMultipleSourceMessage,
|
||||||
confirmationButtonLabel: l10n.continueButtonLabel,
|
confirmationButtonLabel: l10n.continueButtonLabel,
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: AvesSelectionDialog.routeName),
|
||||||
);
|
);
|
||||||
if (value == null) return;
|
if (value == null) return;
|
||||||
nameConflictStrategy = value;
|
nameConflictStrategy = value;
|
||||||
|
|
|
@ -149,10 +149,13 @@ mixin FeedbackMixin {
|
||||||
onDone?.call(processed);
|
onDone?.call(processed);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: ReportOverlay.routeName),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReportOverlay<T> extends StatefulWidget {
|
class ReportOverlay<T> extends StatefulWidget {
|
||||||
|
static const routeName = '/dialog/report_overlay';
|
||||||
|
|
||||||
final Stream<T> opStream;
|
final Stream<T> opStream;
|
||||||
final int? itemCount;
|
final int? itemCount;
|
||||||
final VoidCallback? onCancel;
|
final VoidCallback? onCancel;
|
||||||
|
|
|
@ -62,6 +62,7 @@ mixin PermissionAwareMixin {
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
routeSettings: const RouteSettings(name: AvesDialog.warningRouteName),
|
||||||
);
|
);
|
||||||
// abort if the user cancels in Flutter
|
// abort if the user cancels in Flutter
|
||||||
if (confirmed == null || !confirmed) return false;
|
if (confirmed == null || !confirmed) return false;
|
||||||
|
@ -73,6 +74,7 @@ mixin PermissionAwareMixin {
|
||||||
content: Text(context.l10n.missingSystemFilePickerDialogMessage),
|
content: Text(context.l10n.missingSystemFilePickerDialogMessage),
|
||||||
actions: const [OkButton()],
|
actions: const [OkButton()],
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: AvesDialog.warningRouteName),
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -96,6 +98,7 @@ mixin PermissionAwareMixin {
|
||||||
actions: const [OkButton()],
|
actions: const [OkButton()],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
routeSettings: const RouteSettings(name: AvesDialog.warningRouteName),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,7 @@ mixin SizeAwareMixin {
|
||||||
actions: const [OkButton()],
|
actions: const [OkButton()],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
routeSettings: const RouteSettings(name: AvesDialog.warningRouteName),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ class ColorListTile extends StatelessWidget {
|
||||||
builder: (context) => ColorPickerDialog(
|
builder: (context) => ColorPickerDialog(
|
||||||
initialValue: value,
|
initialValue: value,
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: ColorPickerDialog.routeName),
|
||||||
);
|
);
|
||||||
if (color != null) {
|
if (color != null) {
|
||||||
onChanged(color);
|
onChanged(color);
|
||||||
|
@ -50,6 +51,8 @@ class ColorListTile extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class ColorPickerDialog extends StatefulWidget {
|
class ColorPickerDialog extends StatefulWidget {
|
||||||
|
static const routeName = '/dialog/pick_color';
|
||||||
|
|
||||||
final Color initialValue;
|
final Color initialValue;
|
||||||
|
|
||||||
const ColorPickerDialog({
|
const ColorPickerDialog({
|
||||||
|
|
|
@ -3,16 +3,16 @@ import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class ReportingRouteTracker extends NavigatorObserver {
|
class ReportingRouteTracker extends NavigatorObserver {
|
||||||
@override
|
@override
|
||||||
void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) => reportService.log('Nav didPush to ${_name(route)}');
|
void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) => reportService.log('Nav push to ${_name(route)}');
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) => reportService.log('Nav didPop to ${_name(previousRoute)}');
|
void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) => reportService.log('Nav pop to ${_name(previousRoute)}');
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didRemove(Route<dynamic> route, Route<dynamic>? previousRoute) => reportService.log('Nav didRemove to ${_name(previousRoute)}');
|
void didRemove(Route<dynamic> route, Route<dynamic>? previousRoute) => reportService.log('Nav remove to ${_name(previousRoute)}');
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didReplace({Route<dynamic>? newRoute, Route<dynamic>? oldRoute}) => reportService.log('Nav didReplace to ${_name(newRoute)}');
|
void didReplace({Route<dynamic>? newRoute, Route<dynamic>? oldRoute}) => reportService.log('Nav replace to ${_name(newRoute)}');
|
||||||
|
|
||||||
String _name(Route<dynamic>? route) => route?.settings.name ?? 'unnamed ${route?.runtimeType}';
|
String _name(Route<dynamic>? route) => route?.settings.name ?? 'unnamed ${route?.runtimeType}';
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,11 +13,11 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/scheduler.dart';
|
import 'package:flutter/scheduler.dart';
|
||||||
|
|
||||||
class SearchPage extends StatefulWidget {
|
class SearchPage extends StatefulWidget {
|
||||||
|
static const routeName = '/search';
|
||||||
|
|
||||||
final AvesSearchDelegate delegate;
|
final AvesSearchDelegate delegate;
|
||||||
final Animation<double> animation;
|
final Animation<double> animation;
|
||||||
|
|
||||||
static const routeName = '/search';
|
|
||||||
|
|
||||||
const SearchPage({
|
const SearchPage({
|
||||||
super.key,
|
super.key,
|
||||||
required this.delegate,
|
required this.delegate,
|
||||||
|
|
|
@ -14,6 +14,8 @@ import 'package:tuple/tuple.dart';
|
||||||
import 'aves_dialog.dart';
|
import 'aves_dialog.dart';
|
||||||
|
|
||||||
class AddShortcutDialog extends StatefulWidget {
|
class AddShortcutDialog extends StatefulWidget {
|
||||||
|
static const routeName = '/dialog/add_shortcut';
|
||||||
|
|
||||||
final CollectionLens? collection;
|
final CollectionLens? collection;
|
||||||
final String defaultName;
|
final String defaultName;
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ Future<bool> showConfirmationDialog({
|
||||||
delegate: effectiveDelegate,
|
delegate: effectiveDelegate,
|
||||||
confirmationButtonLabel: confirmationButtonLabel,
|
confirmationButtonLabel: confirmationButtonLabel,
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: _AvesConfirmationDialog.routeName),
|
||||||
);
|
);
|
||||||
if (confirmed == null) return false;
|
if (confirmed == null) return false;
|
||||||
|
|
||||||
|
@ -78,6 +79,8 @@ void _skipConfirmation(ConfirmationDialog type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AvesConfirmationDialog extends StatefulWidget {
|
class _AvesConfirmationDialog extends StatefulWidget {
|
||||||
|
static const routeName = '/dialog/confirmation';
|
||||||
|
|
||||||
final ConfirmationDialog type;
|
final ConfirmationDialog type;
|
||||||
final ConfirmationDialogDelegate delegate;
|
final ConfirmationDialogDelegate delegate;
|
||||||
final String confirmationButtonLabel;
|
final String confirmationButtonLabel;
|
||||||
|
|
|
@ -5,6 +5,9 @@ import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class AvesDialog extends StatelessWidget {
|
class AvesDialog extends StatelessWidget {
|
||||||
|
static const confirmationRouteName = '/dialog/confirmation';
|
||||||
|
static const warningRouteName = '/dialog/warning';
|
||||||
|
|
||||||
final String? title;
|
final String? title;
|
||||||
final ScrollController scrollController;
|
final ScrollController scrollController;
|
||||||
final List<Widget>? scrollableContent;
|
final List<Widget>? scrollableContent;
|
||||||
|
@ -157,6 +160,7 @@ Future<void> showNoMatchingAppDialog(BuildContext context) => showDialog(
|
||||||
content: Text(context.l10n.noMatchingAppDialogMessage),
|
content: Text(context.l10n.noMatchingAppDialogMessage),
|
||||||
actions: const [OkButton()],
|
actions: const [OkButton()],
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: AvesDialog.warningRouteName),
|
||||||
);
|
);
|
||||||
|
|
||||||
class CancelButton extends StatelessWidget {
|
class CancelButton extends StatelessWidget {
|
||||||
|
|
|
@ -13,6 +13,7 @@ Future<void> showSelectionDialog<T>({
|
||||||
final value = await showDialog<T>(
|
final value = await showDialog<T>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: builder,
|
builder: builder,
|
||||||
|
routeSettings: const RouteSettings(name: AvesSelectionDialog.routeName),
|
||||||
);
|
);
|
||||||
// wait for the dialog to hide as applying the change may block the UI
|
// wait for the dialog to hide as applying the change may block the UI
|
||||||
await Future.delayed(Durations.dialogTransitionAnimation * timeDilation);
|
await Future.delayed(Durations.dialogTransitionAnimation * timeDilation);
|
||||||
|
@ -24,6 +25,8 @@ Future<void> showSelectionDialog<T>({
|
||||||
typedef TextBuilder<T> = String Function(T value);
|
typedef TextBuilder<T> = String Function(T value);
|
||||||
|
|
||||||
class AvesSelectionDialog<T> extends StatefulWidget {
|
class AvesSelectionDialog<T> extends StatefulWidget {
|
||||||
|
static const routeName = '/dialog/selection';
|
||||||
|
|
||||||
final T initialValue;
|
final T initialValue;
|
||||||
final Map<T, String> options;
|
final Map<T, String> options;
|
||||||
final TextBuilder<T>? optionSubtitleBuilder;
|
final TextBuilder<T>? optionSubtitleBuilder;
|
||||||
|
|
|
@ -21,6 +21,8 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class EditEntryDateDialog extends StatefulWidget {
|
class EditEntryDateDialog extends StatefulWidget {
|
||||||
|
static const routeName = '/dialog/edit_entry_date';
|
||||||
|
|
||||||
final AvesEntry entry;
|
final AvesEntry entry;
|
||||||
final CollectionLens? collection;
|
final CollectionLens? collection;
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@ import 'package:aves/widgets/dialogs/aves_dialog.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class EditEntryTitleDescriptionDialog extends StatefulWidget {
|
class EditEntryTitleDescriptionDialog extends StatefulWidget {
|
||||||
|
static const routeName = '/dialog/edit_entry_title_description';
|
||||||
|
|
||||||
final String initialTitle, initialDescription;
|
final String initialTitle, initialDescription;
|
||||||
|
|
||||||
const EditEntryTitleDescriptionDialog({
|
const EditEntryTitleDescriptionDialog({
|
||||||
|
|
|
@ -22,6 +22,8 @@ import 'package:latlong2/latlong.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class EditEntryLocationDialog extends StatefulWidget {
|
class EditEntryLocationDialog extends StatefulWidget {
|
||||||
|
static const routeName = '/dialog/edit_entry_location';
|
||||||
|
|
||||||
final AvesEntry entry;
|
final AvesEntry entry;
|
||||||
final CollectionLens? collection;
|
final CollectionLens? collection;
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@ import 'package:aves/widgets/dialogs/aves_dialog.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class EditEntryRatingDialog extends StatefulWidget {
|
class EditEntryRatingDialog extends StatefulWidget {
|
||||||
|
static const routeName = '/dialog/edit_entry_rating';
|
||||||
|
|
||||||
final AvesEntry entry;
|
final AvesEntry entry;
|
||||||
|
|
||||||
const EditEntryRatingDialog({
|
const EditEntryRatingDialog({
|
||||||
|
|
|
@ -16,6 +16,8 @@ import 'package:provider/provider.dart';
|
||||||
import '../aves_dialog.dart';
|
import '../aves_dialog.dart';
|
||||||
|
|
||||||
class RemoveEntryMetadataDialog extends StatefulWidget {
|
class RemoveEntryMetadataDialog extends StatefulWidget {
|
||||||
|
static const routeName = '/dialog/remove_entry_metadata';
|
||||||
|
|
||||||
final bool showJpegTypes;
|
final bool showJpegTypes;
|
||||||
|
|
||||||
const RemoveEntryMetadataDialog({
|
const RemoveEntryMetadataDialog({
|
||||||
|
|
|
@ -9,6 +9,8 @@ import 'package:flutter/material.dart';
|
||||||
import '../aves_dialog.dart';
|
import '../aves_dialog.dart';
|
||||||
|
|
||||||
class RenameEntryDialog extends StatefulWidget {
|
class RenameEntryDialog extends StatefulWidget {
|
||||||
|
static const routeName = '/dialog/rename_entry';
|
||||||
|
|
||||||
final AvesEntry entry;
|
final AvesEntry entry;
|
||||||
|
|
||||||
const RenameEntryDialog({
|
const RenameEntryDialog({
|
||||||
|
|
|
@ -9,6 +9,8 @@ import 'package:flutter/material.dart';
|
||||||
import 'aves_dialog.dart';
|
import 'aves_dialog.dart';
|
||||||
|
|
||||||
class ExportEntryDialog extends StatefulWidget {
|
class ExportEntryDialog extends StatefulWidget {
|
||||||
|
static const routeName = '/dialog/export_entry';
|
||||||
|
|
||||||
final AvesEntry entry;
|
final AvesEntry entry;
|
||||||
|
|
||||||
const ExportEntryDialog({
|
const ExportEntryDialog({
|
||||||
|
|
|
@ -23,6 +23,8 @@ import 'package:provider/provider.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
class CoverSelectionDialog extends StatefulWidget {
|
class CoverSelectionDialog extends StatefulWidget {
|
||||||
|
static const routeName = '/dialog/select_cover';
|
||||||
|
|
||||||
final CollectionFilter filter;
|
final CollectionFilter filter;
|
||||||
final AvesEntry? customEntry;
|
final AvesEntry? customEntry;
|
||||||
final String? customPackage;
|
final String? customPackage;
|
||||||
|
@ -384,6 +386,7 @@ class _CoverSelectionDialogState extends State<CoverSelectionDialog> {
|
||||||
// picker controls are not on edge and palette panel is more stable
|
// picker controls are not on edge and palette panel is more stable
|
||||||
initialValue: _customColor ?? const Color(0xff3f51b5),
|
initialValue: _customColor ?? const Color(0xff3f51b5),
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: ColorPickerDialog.routeName),
|
||||||
);
|
);
|
||||||
if (color != null) {
|
if (color != null) {
|
||||||
_customColor = color;
|
_customColor = color;
|
||||||
|
|
|
@ -10,6 +10,8 @@ import 'package:flutter/material.dart';
|
||||||
import '../aves_dialog.dart';
|
import '../aves_dialog.dart';
|
||||||
|
|
||||||
class CreateAlbumDialog extends StatefulWidget {
|
class CreateAlbumDialog extends StatefulWidget {
|
||||||
|
static const routeName = '/dialog/create_album';
|
||||||
|
|
||||||
const CreateAlbumDialog({super.key});
|
const CreateAlbumDialog({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -6,6 +6,8 @@ import 'package:aves/widgets/dialogs/aves_dialog.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class RenameAlbumDialog extends StatefulWidget {
|
class RenameAlbumDialog extends StatefulWidget {
|
||||||
|
static const routeName = '/dialog/rename_album';
|
||||||
|
|
||||||
final String album;
|
final String album;
|
||||||
|
|
||||||
const RenameAlbumDialog({
|
const RenameAlbumDialog({
|
||||||
|
|
|
@ -183,6 +183,7 @@ class _AlbumPickPageState extends State<_AlbumPickPage> {
|
||||||
final newAlbum = await showDialog<String>(
|
final newAlbum = await showDialog<String>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => const CreateAlbumDialog(),
|
builder: (context) => const CreateAlbumDialog(),
|
||||||
|
routeSettings: const RouteSettings(name: CreateAlbumDialog.routeName),
|
||||||
);
|
);
|
||||||
// wait for the dialog to hide as applying the change may block the UI
|
// wait for the dialog to hide as applying the change may block the UI
|
||||||
await Future.delayed(Durations.dialogTransitionAnimation * timeDilation);
|
await Future.delayed(Durations.dialogTransitionAnimation * timeDilation);
|
||||||
|
|
|
@ -14,6 +14,8 @@ import 'package:tuple/tuple.dart';
|
||||||
import 'aves_dialog.dart';
|
import 'aves_dialog.dart';
|
||||||
|
|
||||||
class TileViewDialog<S, G, L> extends StatefulWidget {
|
class TileViewDialog<S, G, L> extends StatefulWidget {
|
||||||
|
static const routeName = '/dialog/tile_view';
|
||||||
|
|
||||||
final Tuple4<S?, G?, L?, bool> initialValue;
|
final Tuple4<S?, G?, L?, bool> initialValue;
|
||||||
final List<TileViewDialogOption<S>> sortOptions;
|
final List<TileViewDialogOption<S>> sortOptions;
|
||||||
final List<TileViewDialogOption<G>> groupOptions;
|
final List<TileViewDialogOption<G>> groupOptions;
|
||||||
|
|
|
@ -4,6 +4,8 @@ import 'package:flutter/material.dart';
|
||||||
import 'aves_dialog.dart';
|
import 'aves_dialog.dart';
|
||||||
|
|
||||||
class VideoSpeedDialog extends StatefulWidget {
|
class VideoSpeedDialog extends StatefulWidget {
|
||||||
|
static const routeName = '/dialog/select_video_speed';
|
||||||
|
|
||||||
final double current, min, max;
|
final double current, min, max;
|
||||||
|
|
||||||
const VideoSpeedDialog({
|
const VideoSpeedDialog({
|
||||||
|
|
|
@ -11,6 +11,8 @@ import 'package:flutter/material.dart';
|
||||||
import 'aves_dialog.dart';
|
import 'aves_dialog.dart';
|
||||||
|
|
||||||
class VideoStreamSelectionDialog extends StatefulWidget {
|
class VideoStreamSelectionDialog extends StatefulWidget {
|
||||||
|
static const routeName = '/dialog/select_video_stream';
|
||||||
|
|
||||||
final Map<StreamSummary, bool> streams;
|
final Map<StreamSummary, bool> streams;
|
||||||
|
|
||||||
const VideoStreamSelectionDialog({
|
const VideoStreamSelectionDialog({
|
||||||
|
|
|
@ -8,6 +8,8 @@ import 'package:tuple/tuple.dart';
|
||||||
import 'aves_dialog.dart';
|
import 'aves_dialog.dart';
|
||||||
|
|
||||||
class WallpaperSettingsDialog extends StatefulWidget {
|
class WallpaperSettingsDialog extends StatefulWidget {
|
||||||
|
static const routeName = '/dialog/wallpaper_settings';
|
||||||
|
|
||||||
const WallpaperSettingsDialog({super.key});
|
const WallpaperSettingsDialog({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -117,6 +117,7 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate<AlbumFilter> with
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onActionSelected(BuildContext context, Set<AlbumFilter> filters, ChipSetAction action) {
|
void onActionSelected(BuildContext context, Set<AlbumFilter> filters, ChipSetAction action) {
|
||||||
|
reportService.log('$action');
|
||||||
switch (action) {
|
switch (action) {
|
||||||
// general
|
// general
|
||||||
case ChipSetAction.createAlbum:
|
case ChipSetAction.createAlbum:
|
||||||
|
@ -159,6 +160,7 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate<AlbumFilter> with
|
||||||
tileExtentController: extentController,
|
tileExtentController: extentController,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
routeSettings: const RouteSettings(name: TileViewDialog.routeName),
|
||||||
);
|
);
|
||||||
// wait for the dialog to hide as applying the change may block the UI
|
// wait for the dialog to hide as applying the change may block the UI
|
||||||
await Future.delayed(Durations.dialogTransitionAnimation * timeDilation);
|
await Future.delayed(Durations.dialogTransitionAnimation * timeDilation);
|
||||||
|
@ -174,6 +176,7 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate<AlbumFilter> with
|
||||||
final newAlbum = await showDialog<String>(
|
final newAlbum = await showDialog<String>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => const CreateAlbumDialog(),
|
builder: (context) => const CreateAlbumDialog(),
|
||||||
|
routeSettings: const RouteSettings(name: CreateAlbumDialog.routeName),
|
||||||
);
|
);
|
||||||
if (newAlbum != null && newAlbum.isNotEmpty) {
|
if (newAlbum != null && newAlbum.isNotEmpty) {
|
||||||
final source = context.read<CollectionSource>();
|
final source = context.read<CollectionSource>();
|
||||||
|
@ -243,6 +246,7 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate<AlbumFilter> with
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: AvesDialog.confirmationRouteName),
|
||||||
);
|
);
|
||||||
if (confirmed == null || !confirmed) return;
|
if (confirmed == null || !confirmed) return;
|
||||||
|
|
||||||
|
@ -301,6 +305,7 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate<AlbumFilter> with
|
||||||
final newName = await showDialog<String>(
|
final newName = await showDialog<String>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => RenameAlbumDialog(album: album),
|
builder: (context) => RenameAlbumDialog(album: album),
|
||||||
|
routeSettings: const RouteSettings(name: RenameAlbumDialog.routeName),
|
||||||
);
|
);
|
||||||
if (newName == null || newName.isEmpty) return;
|
if (newName == null || newName.isEmpty) return;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'package:aves/model/actions/chip_actions.dart';
|
||||||
import 'package:aves/model/filters/filters.dart';
|
import 'package:aves/model/filters/filters.dart';
|
||||||
import 'package:aves/model/highlight.dart';
|
import 'package:aves/model/highlight.dart';
|
||||||
import 'package:aves/model/settings/settings.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
|
import 'package:aves/services/common/services.dart';
|
||||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
import 'package:aves/widgets/dialogs/aves_dialog.dart';
|
import 'package:aves/widgets/dialogs/aves_dialog.dart';
|
||||||
import 'package:aves/widgets/filter_grids/albums_page.dart';
|
import 'package:aves/widgets/filter_grids/albums_page.dart';
|
||||||
|
@ -12,6 +13,7 @@ import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class ChipActionDelegate {
|
class ChipActionDelegate {
|
||||||
void onActionSelected(BuildContext context, CollectionFilter filter, ChipAction action) {
|
void onActionSelected(BuildContext context, CollectionFilter filter, ChipAction action) {
|
||||||
|
reportService.log('$action');
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case ChipAction.goToAlbumPage:
|
case ChipAction.goToAlbumPage:
|
||||||
_goTo(context, filter, AlbumListPage.routeName, (context) => const AlbumListPage());
|
_goTo(context, filter, AlbumListPage.routeName, (context) => const AlbumListPage());
|
||||||
|
@ -62,6 +64,7 @@ class ChipActionDelegate {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: AvesDialog.confirmationRouteName),
|
||||||
);
|
);
|
||||||
if (confirmed == null || !confirmed) return;
|
if (confirmed == null || !confirmed) return;
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import 'package:aves/model/source/collection_lens.dart';
|
||||||
import 'package:aves/model/source/collection_source.dart';
|
import 'package:aves/model/source/collection_source.dart';
|
||||||
import 'package:aves/model/source/enums/enums.dart';
|
import 'package:aves/model/source/enums/enums.dart';
|
||||||
import 'package:aves/model/source/enums/view.dart';
|
import 'package:aves/model/source/enums/view.dart';
|
||||||
|
import 'package:aves/services/common/services.dart';
|
||||||
import 'package:aves/theme/colors.dart';
|
import 'package:aves/theme/colors.dart';
|
||||||
import 'package:aves/theme/durations.dart';
|
import 'package:aves/theme/durations.dart';
|
||||||
import 'package:aves/widgets/common/action_mixins/feedback.dart';
|
import 'package:aves/widgets/common/action_mixins/feedback.dart';
|
||||||
|
@ -150,6 +151,7 @@ abstract class ChipSetActionDelegate<T extends CollectionFilter> with FeedbackMi
|
||||||
}
|
}
|
||||||
|
|
||||||
void onActionSelected(BuildContext context, Set<T> filters, ChipSetAction action) {
|
void onActionSelected(BuildContext context, Set<T> filters, ChipSetAction action) {
|
||||||
|
reportService.log('$action');
|
||||||
switch (action) {
|
switch (action) {
|
||||||
// general
|
// general
|
||||||
case ChipSetAction.configureView:
|
case ChipSetAction.configureView:
|
||||||
|
@ -235,6 +237,7 @@ abstract class ChipSetActionDelegate<T extends CollectionFilter> with FeedbackMi
|
||||||
tileExtentController: extentController,
|
tileExtentController: extentController,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
routeSettings: const RouteSettings(name: TileViewDialog.routeName),
|
||||||
);
|
);
|
||||||
// wait for the dialog to hide as applying the change may block the UI
|
// wait for the dialog to hide as applying the change may block the UI
|
||||||
await Future.delayed(Durations.dialogTransitionAnimation * timeDilation);
|
await Future.delayed(Durations.dialogTransitionAnimation * timeDilation);
|
||||||
|
@ -313,6 +316,7 @@ abstract class ChipSetActionDelegate<T extends CollectionFilter> with FeedbackMi
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: AvesDialog.confirmationRouteName),
|
||||||
);
|
);
|
||||||
if (confirmed == null || !confirmed) return;
|
if (confirmed == null || !confirmed) return;
|
||||||
|
|
||||||
|
@ -333,6 +337,7 @@ abstract class ChipSetActionDelegate<T extends CollectionFilter> with FeedbackMi
|
||||||
customPackage: existingCover?.item2,
|
customPackage: existingCover?.item2,
|
||||||
customColor: existingCover?.item3,
|
customColor: existingCover?.item3,
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: CoverSelectionDialog.routeName),
|
||||||
);
|
);
|
||||||
if (selectedCover == null) return;
|
if (selectedCover == null) return;
|
||||||
|
|
||||||
|
|
|
@ -173,6 +173,7 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix
|
||||||
}
|
}
|
||||||
|
|
||||||
void onActionSelected(BuildContext context, EntryAction action) {
|
void onActionSelected(BuildContext context, EntryAction action) {
|
||||||
|
reportService.log('$action');
|
||||||
final targetEntry = _getTargetEntry(context, action);
|
final targetEntry = _getTargetEntry(context, action);
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
|
@ -345,6 +346,7 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix
|
||||||
builder: (context) => AddShortcutDialog(
|
builder: (context) => AddShortcutDialog(
|
||||||
defaultName: targetEntry.bestTitle ?? '',
|
defaultName: targetEntry.bestTitle ?? '',
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: AddShortcutDialog.routeName),
|
||||||
);
|
);
|
||||||
if (result == null) return;
|
if (result == null) return;
|
||||||
|
|
||||||
|
@ -407,6 +409,7 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix
|
||||||
final options = await showDialog<EntryExportOptions>(
|
final options = await showDialog<EntryExportOptions>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => ExportEntryDialog(entry: targetEntry),
|
builder: (context) => ExportEntryDialog(entry: targetEntry),
|
||||||
|
routeSettings: const RouteSettings(name: ExportEntryDialog.routeName),
|
||||||
);
|
);
|
||||||
if (options == null) return;
|
if (options == null) return;
|
||||||
|
|
||||||
|
@ -504,6 +507,7 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix
|
||||||
final newName = await showDialog<String>(
|
final newName = await showDialog<String>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => RenameEntryDialog(entry: targetEntry),
|
builder: (context) => RenameEntryDialog(entry: targetEntry),
|
||||||
|
routeSettings: const RouteSettings(name: RenameEntryDialog.routeName),
|
||||||
);
|
);
|
||||||
if (newName == null || newName.isEmpty || newName == targetEntry.filenameWithoutExtension) return;
|
if (newName == null || newName.isEmpty || newName == targetEntry.filenameWithoutExtension) return;
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,7 @@ class EntryInfoActionDelegate with FeedbackMixin, PermissionAwareMixin, EntryEdi
|
||||||
}
|
}
|
||||||
|
|
||||||
void onActionSelected(BuildContext context, AvesEntry targetEntry, CollectionLens? collection, EntryAction action) async {
|
void onActionSelected(BuildContext context, AvesEntry targetEntry, CollectionLens? collection, EntryAction action) async {
|
||||||
|
await reportService.log('$action');
|
||||||
_eventStreamController.add(ActionStartedEvent(action));
|
_eventStreamController.add(ActionStartedEvent(action));
|
||||||
switch (action) {
|
switch (action) {
|
||||||
// general
|
// general
|
||||||
|
@ -239,6 +240,7 @@ class EntryInfoActionDelegate with FeedbackMixin, PermissionAwareMixin, EntryEdi
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: AvesDialog.warningRouteName),
|
||||||
);
|
);
|
||||||
if (confirmed == null || !confirmed) return;
|
if (confirmed == null || !confirmed) return;
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ class WallpaperButtons extends StatelessWidget with FeedbackMixin {
|
||||||
final value = await showDialog<Tuple2<WallpaperTarget, bool>>(
|
final value = await showDialog<Tuple2<WallpaperTarget, bool>>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => const WallpaperSettingsDialog(),
|
builder: (context) => const WallpaperSettingsDialog(),
|
||||||
|
routeSettings: const RouteSettings(name: WallpaperSettingsDialog.routeName),
|
||||||
);
|
);
|
||||||
if (value == null) return;
|
if (value == null) return;
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ abstract class AvesVideoController {
|
||||||
content: Text(context.l10n.videoResumeDialogMessage(formatFriendlyDuration(Duration(milliseconds: resumeTime)))),
|
content: Text(context.l10n.videoResumeDialogMessage(formatFriendlyDuration(Duration(milliseconds: resumeTime)))),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.maybeOf(context)?.pop(),
|
onPressed: () => Navigator.maybeOf(context)?.pop(false),
|
||||||
child: Text(context.l10n.videoStartOverButtonLabel),
|
child: Text(context.l10n.videoStartOverButtonLabel),
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
|
@ -79,6 +79,7 @@ abstract class AvesVideoController {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: AvesDialog.confirmationRouteName),
|
||||||
);
|
);
|
||||||
if (resume == null || !resume) return 0;
|
if (resume == null || !resume) return 0;
|
||||||
return resumeTime;
|
return resumeTime;
|
||||||
|
|
|
@ -151,6 +151,7 @@ class VideoActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix
|
||||||
builder: (context) => VideoStreamSelectionDialog(
|
builder: (context) => VideoStreamSelectionDialog(
|
||||||
streams: Map.fromEntries(streams.map((stream) => MapEntry(stream, currentSelectedIndices.contains(stream.index)))),
|
streams: Map.fromEntries(streams.map((stream) => MapEntry(stream, currentSelectedIndices.contains(stream.index)))),
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: VideoStreamSelectionDialog.routeName),
|
||||||
);
|
);
|
||||||
if (userSelectedStreams == null || userSelectedStreams.isEmpty) return;
|
if (userSelectedStreams == null || userSelectedStreams.isEmpty) return;
|
||||||
|
|
||||||
|
@ -168,6 +169,7 @@ class VideoActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix
|
||||||
min: controller.minSpeed,
|
min: controller.minSpeed,
|
||||||
max: controller.maxSpeed,
|
max: controller.maxSpeed,
|
||||||
),
|
),
|
||||||
|
routeSettings: const RouteSettings(name: VideoSpeedDialog.routeName),
|
||||||
);
|
);
|
||||||
if (newSpeed == null) return;
|
if (newSpeed == null) return;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue