diff --git a/lib/model/terms.dart b/lib/model/terms.dart index ba2f9ed66..24b781def 100644 --- a/lib/model/terms.dart +++ b/lib/model/terms.dart @@ -15,4 +15,3 @@ __We collect anonymous data to improve the app.__ We use Google Firebase for Ana ## Links [Sources](https://github.com/deckerst/aves) '''; - diff --git a/lib/utils/constants.dart b/lib/utils/constants.dart index 42743c4cb..902979c8e 100644 --- a/lib/utils/constants.dart +++ b/lib/utils/constants.dart @@ -19,9 +19,6 @@ class Constants { ], ); - // ref _PopupMenuRoute._kMenuDuration - static const popupMenuTransitionDuration = Duration(milliseconds: 300); - static const svgBackground = Colors.white; static const svgColorFilter = ColorFilter.mode(svgBackground, BlendMode.dstOver); diff --git a/lib/utils/durations.dart b/lib/utils/durations.dart new file mode 100644 index 000000000..75b8b4612 --- /dev/null +++ b/lib/utils/durations.dart @@ -0,0 +1,35 @@ +import 'package:flutter/scheduler.dart'; + +class Durations { + // common animations + static const iconAnimation = Duration(milliseconds: 300); + static const opToastAnimation = Duration(milliseconds: 600); + static const sweeperOpacityAnimation = Duration(milliseconds: 150); + static const sweepingAnimation = Duration(milliseconds: 650); + static const popupMenuAnimation = Duration(milliseconds: 300); // ref _PopupMenuRoute._kMenuDuration + static const staggeredAnimation = Duration(milliseconds: 375); + + // collection animations + static const appBarTitleAnimation = Duration(milliseconds: 300); + static const filterBarRemovalAnimation = Duration(milliseconds: 200); + static const collectionOpOverlayAnimation = Duration(milliseconds: 300); + static const collectionScalingBackgroundAnimation = Duration(milliseconds: 200); + static const sectionHeaderAnimation = Duration(milliseconds: 200); + static const thumbnailTransition = Duration(milliseconds: 200); + static const thumbnailOverlayAnimation = Duration(milliseconds: 200); + + // search animations + static const filterRowExpandAnimation = Duration(milliseconds: 300); + + // fullscreen animations + static const fullscreenPageAnimation = Duration(milliseconds: 300); + static const fullscreenOverlayAnimation = Duration(milliseconds: 200); + + // delays & refresh intervals + static const opToastDisplay = Duration(seconds: 2); + static const collectionScrollMonitoringTimerDelay = Duration(milliseconds: 100); + static const collectionScalingCompleteNotificationDelay = Duration(milliseconds: 300); + static const appBarProgressTimerInterval = Duration(seconds: 1); + static const videoProgressTimerInterval = Duration(milliseconds: 300); + static var staggeredAnimationDelay = Durations.staggeredAnimation ~/ 6 * timeDilation; +} diff --git a/lib/widgets/about/licenses.dart b/lib/widgets/about/licenses.dart index 1660ba210..5c7334b63 100644 --- a/lib/widgets/about/licenses.dart +++ b/lib/widgets/about/licenses.dart @@ -1,4 +1,5 @@ import 'package:aves/utils/constants.dart'; +import 'package:aves/utils/durations.dart'; import 'package:aves/widgets/common/icons.dart'; import 'package:aves/widgets/common/menu_row.dart'; import 'package:collection/collection.dart'; @@ -48,7 +49,8 @@ class _LicensesState extends State { final child = LicenseRow(_packages[index]); return AnimationConfiguration.staggeredList( position: index, - duration: const Duration(milliseconds: 375), + duration: Durations.staggeredAnimation, + delay: Durations.staggeredAnimationDelay, child: SlideAnimation( verticalOffset: 50.0, child: FadeInAnimation( diff --git a/lib/widgets/album/app_bar.dart b/lib/widgets/album/app_bar.dart index 1dbc5774d..efc6cf76a 100644 --- a/lib/widgets/album/app_bar.dart +++ b/lib/widgets/album/app_bar.dart @@ -5,7 +5,7 @@ import 'package:aves/model/collection_lens.dart'; import 'package:aves/model/collection_source.dart'; import 'package:aves/model/image_entry.dart'; import 'package:aves/model/settings.dart'; -import 'package:aves/utils/constants.dart'; +import 'package:aves/utils/durations.dart'; import 'package:aves/widgets/album/filter_bar.dart'; import 'package:aves/widgets/album/search/search_delegate.dart'; import 'package:aves/widgets/common/action_delegates/selection_action_delegate.dart'; @@ -49,7 +49,7 @@ class _CollectionAppBarState extends State with SingleTickerPr collection: collection, ); _browseToSelectAnimation = AnimationController( - duration: const Duration(milliseconds: 300), + duration: Durations.iconAnimation, vsync: this, ); _registerWidget(widget); @@ -142,7 +142,7 @@ class _CollectionAppBarState extends State with SingleTickerPr valueListenable: collection.source.stateNotifier, builder: (context, sourceState, child) { return AnimatedSwitcher( - duration: Duration(milliseconds: (300 * timeDilation).toInt()), + duration: Durations.appBarTitleAnimation, transitionBuilder: (child, animation) => FadeTransition( opacity: animation, child: SizeTransition( @@ -297,7 +297,7 @@ class _CollectionAppBarState extends State with SingleTickerPr void _onCollectionActionSelected(CollectionAction action) async { // wait for the popup menu to hide before proceeding with the action - await Future.delayed(Constants.popupMenuTransitionDuration); + await Future.delayed(Durations.popupMenuAnimation * timeDilation); switch (action) { case CollectionAction.copy: case CollectionAction.move: @@ -384,7 +384,7 @@ class _SourceStateSubtitleState extends State { @override void initState() { super.initState(); - _progressTimer = Timer.periodic(const Duration(milliseconds: 1000), (timer) => setState(() {})); + _progressTimer = Timer.periodic(Durations.appBarProgressTimerInterval, (_) => setState(() {})); } @override diff --git a/lib/widgets/album/filter_bar.dart b/lib/widgets/album/filter_bar.dart index 40c7f854a..62e97b485 100644 --- a/lib/widgets/album/filter_bar.dart +++ b/lib/widgets/album/filter_bar.dart @@ -1,4 +1,5 @@ import 'package:aves/model/filters/filters.dart'; +import 'package:aves/utils/durations.dart'; import 'package:aves/widgets/common/aves_filter_chip.dart'; import 'package:flutter/material.dart'; @@ -56,7 +57,7 @@ class _FilterBarState extends State { ), ) : (context, animation) => _buildChip(filter), - duration: animate ? const Duration(milliseconds: 200) : Duration.zero, + duration: animate ? Durations.filterBarRemovalAnimation : Duration.zero, ); }); added.forEach((filter) { diff --git a/lib/widgets/album/grid/header_generic.dart b/lib/widgets/album/grid/header_generic.dart index 4301056ba..9d9086f58 100644 --- a/lib/widgets/album/grid/header_generic.dart +++ b/lib/widgets/album/grid/header_generic.dart @@ -4,12 +4,12 @@ import 'package:aves/model/collection_lens.dart'; import 'package:aves/model/collection_source.dart'; import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/utils/constants.dart'; +import 'package:aves/utils/durations.dart'; import 'package:aves/widgets/album/grid/header_album.dart'; import 'package:aves/widgets/album/grid/header_date.dart'; import 'package:aves/widgets/common/icons.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; -import 'package:flutter/scheduler.dart'; import 'package:provider/provider.dart'; class SectionHeader extends StatelessWidget { @@ -190,11 +190,11 @@ class SectionSelectableLeading extends StatelessWidget { final sectionEntries = collection.sections[sectionKey]; final selected = collection.isSelected(sectionEntries); final child = TooltipTheme( + key: ValueKey(selected), data: TooltipTheme.of(context).copyWith( preferBelow: false, ), child: IconButton( - key: ValueKey(selected), iconSize: 26, padding: const EdgeInsets.only(top: 1), alignment: Alignment.topLeft, @@ -214,7 +214,7 @@ class SectionSelectableLeading extends StatelessWidget { ), ); return AnimatedSwitcher( - duration: Duration(milliseconds: (200 * timeDilation).toInt()), + duration: Durations.sectionHeaderAnimation, switchInCurve: Curves.easeOutBack, switchOutCurve: Curves.easeOutBack, transitionBuilder: (child, animation) => ScaleTransition( @@ -227,7 +227,7 @@ class SectionSelectableLeading extends StatelessWidget { ) : browsingBuilder?.call(context) ?? const SizedBox(height: leadingDimension); return AnimatedSwitcher( - duration: Duration(milliseconds: (200 * timeDilation).toInt()), + duration: Durations.sectionHeaderAnimation, switchInCurve: Curves.easeInOut, switchOutCurve: Curves.easeInOut, transitionBuilder: (child, animation) { diff --git a/lib/widgets/album/grid/scaling.dart b/lib/widgets/album/grid/scaling.dart index da1bebbad..cf73d55e8 100644 --- a/lib/widgets/album/grid/scaling.dart +++ b/lib/widgets/album/grid/scaling.dart @@ -2,6 +2,7 @@ import 'dart:math'; import 'dart:ui' as ui; import 'package:aves/model/image_entry.dart'; +import 'package:aves/utils/durations.dart'; import 'package:aves/widgets/album/grid/list_section_layout.dart'; import 'package:aves/widgets/album/grid/list_sliver.dart'; import 'package:aves/widgets/album/grid/tile_extent_manager.dart'; @@ -118,7 +119,7 @@ class _GridScaleGestureDetectorState extends State { _scrollToEntry(entry); // warning: posting `onScaled` in the next frame with `addPostFrameCallback` // would trigger only when the scrollable offset actually changes - Future.delayed(const Duration(milliseconds: 300)).then((_) => widget.onScaled?.call(entry)); + Future.delayed(Durations.collectionScalingCompleteNotificationDelay).then((_) => widget.onScaled?.call(entry)); _applyingScale = false; }); } @@ -200,7 +201,7 @@ class _ScaleOverlayState extends State { ], ), ), - duration: const Duration(milliseconds: 200), + duration: Durations.collectionScalingBackgroundAnimation, child: ValueListenableBuilder( valueListenable: widget.scaledExtentNotifier, builder: (context, extent, child) { diff --git a/lib/widgets/album/search/expandable_filter_row.dart b/lib/widgets/album/search/expandable_filter_row.dart index d5e0293fc..d99491ba1 100644 --- a/lib/widgets/album/search/expandable_filter_row.dart +++ b/lib/widgets/album/search/expandable_filter_row.dart @@ -1,5 +1,6 @@ import 'package:aves/model/filters/filters.dart'; import 'package:aves/utils/constants.dart'; +import 'package:aves/utils/durations.dart'; import 'package:aves/widgets/common/aves_filter_chip.dart'; import 'package:aves/widgets/common/icons.dart'; import 'package:flutter/material.dart'; @@ -95,7 +96,7 @@ class ExpandableFilterRow extends StatelessWidget { children: [ titleRow, AnimatedSwitcher( - duration: const Duration(milliseconds: 300), + duration: Durations.filterRowExpandAnimation, child: filterChips, layoutBuilder: (currentChild, previousChildren) => Stack( children: [ diff --git a/lib/widgets/album/thumbnail/overlay.dart b/lib/widgets/album/thumbnail/overlay.dart index 58853ab94..ac6f6801f 100644 --- a/lib/widgets/album/thumbnail/overlay.dart +++ b/lib/widgets/album/thumbnail/overlay.dart @@ -2,10 +2,10 @@ import 'dart:math'; import 'package:aves/model/collection_lens.dart'; import 'package:aves/model/image_entry.dart'; +import 'package:aves/utils/durations.dart'; import 'package:aves/widgets/common/fx/sweeper.dart'; import 'package:aves/widgets/common/icons.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/scheduler.dart'; import 'package:provider/provider.dart'; class ThumbnailEntryOverlay extends StatelessWidget { @@ -57,7 +57,7 @@ class ThumbnailSelectionOverlay extends StatelessWidget { @override Widget build(BuildContext context) { - final duration = Duration(milliseconds: (200 * timeDilation).toInt()); + final duration = Durations.thumbnailOverlayAnimation; final fontSize = min(14.0, (extent / 8)).roundToDouble(); final iconSize = fontSize * 2; final collection = Provider.of(context); diff --git a/lib/widgets/album/thumbnail/raster.dart b/lib/widgets/album/thumbnail/raster.dart index ef9e615d4..08de412b0 100644 --- a/lib/widgets/album/thumbnail/raster.dart +++ b/lib/widgets/album/thumbnail/raster.dart @@ -1,6 +1,7 @@ import 'dart:math'; import 'package:aves/model/image_entry.dart'; +import 'package:aves/utils/durations.dart'; import 'package:aves/widgets/common/image_providers/thumbnail_provider.dart'; import 'package:aves/widgets/common/image_providers/uri_image_provider.dart'; import 'package:aves/widgets/common/transition_image.dart'; @@ -93,7 +94,7 @@ class _ThumbnailRasterImageState extends State { frameBuilder: (context, child, frame, wasSynchronouslyLoaded) { if (wasSynchronouslyLoaded) return child; return AnimatedSwitcher( - duration: const Duration(milliseconds: 200), + duration: Durations.thumbnailTransition, transitionBuilder: (child, animation) { var shouldFade = true; if (child is Image && child.image == _fastThumbnailProvider) { diff --git a/lib/widgets/album/thumbnail_collection.dart b/lib/widgets/album/thumbnail_collection.dart index 0fea6d2c0..5d5b89ac5 100644 --- a/lib/widgets/album/thumbnail_collection.dart +++ b/lib/widgets/album/thumbnail_collection.dart @@ -4,6 +4,7 @@ import 'package:aves/model/collection_lens.dart'; import 'package:aves/model/filters/favourite.dart'; import 'package:aves/model/filters/mime.dart'; import 'package:aves/model/mime_types.dart'; +import 'package:aves/utils/durations.dart'; import 'package:aves/widgets/album/app_bar.dart'; import 'package:aves/widgets/album/empty.dart'; import 'package:aves/widgets/album/grid/list_section_layout.dart'; @@ -220,7 +221,7 @@ class _CollectionScrollViewState extends State { void _onScrollChange() { widget.isScrollingNotifier.value = true; _stopScrollMonitoringTimer(); - _scrollMonitoringTimer = Timer(const Duration(milliseconds: 100), () { + _scrollMonitoringTimer = Timer(Durations.collectionScrollMonitoringTimerDelay, () { widget.isScrollingNotifier.value = false; }); } diff --git a/lib/widgets/common/action_delegates/create_album_dialog.dart b/lib/widgets/common/action_delegates/create_album_dialog.dart index 58d593d80..b4ecb8ec9 100644 --- a/lib/widgets/common/action_delegates/create_album_dialog.dart +++ b/lib/widgets/common/action_delegates/create_album_dialog.dart @@ -53,14 +53,14 @@ class _CreateAlbumDialogState extends State { isExpanded: true, items: allVolumes .map((volume) => DropdownMenuItem( - value: volume, - child: Text( - volume.description, - softWrap: false, - overflow: TextOverflow.fade, - maxLines: 1, - ), - )) + value: volume, + child: Text( + volume.description, + softWrap: false, + overflow: TextOverflow.fade, + maxLines: 1, + ), + )) .toList(), value: selectedVolume, onChanged: (volume) => setState(() => selectedVolume = volume), diff --git a/lib/widgets/common/action_delegates/feedback.dart b/lib/widgets/common/action_delegates/feedback.dart index dab322d90..9042ab5ad 100644 --- a/lib/widgets/common/action_delegates/feedback.dart +++ b/lib/widgets/common/action_delegates/feedback.dart @@ -1,5 +1,7 @@ +import 'package:aves/utils/durations.dart'; import 'package:flushbar/flushbar.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; mixin FeedbackMixin { void showFeedback(BuildContext context, String message) { @@ -9,9 +11,9 @@ mixin FeedbackMixin { borderRadius: 8, borderColor: Colors.white30, borderWidth: 0.5, - duration: const Duration(seconds: 2), + duration: Durations.opToastDisplay * timeDilation, flushbarPosition: FlushbarPosition.TOP, - animationDuration: const Duration(milliseconds: 600), + animationDuration: Durations.opToastAnimation, ).show(context); } -} \ No newline at end of file +} diff --git a/lib/widgets/common/action_delegates/selection_action_delegate.dart b/lib/widgets/common/action_delegates/selection_action_delegate.dart index d5473365b..56cda1c5a 100644 --- a/lib/widgets/common/action_delegates/selection_action_delegate.dart +++ b/lib/widgets/common/action_delegates/selection_action_delegate.dart @@ -7,6 +7,7 @@ import 'package:aves/model/image_entry.dart'; import 'package:aves/model/metadata_db.dart'; import 'package:aves/services/android_app_service.dart'; import 'package:aves/services/image_file_service.dart'; +import 'package:aves/utils/durations.dart'; import 'package:aves/widgets/album/app_bar.dart'; import 'package:aves/widgets/album/empty.dart'; import 'package:aves/widgets/common/action_delegates/create_album_dialog.dart'; @@ -18,6 +19,7 @@ import 'package:aves/widgets/filter_grid_page.dart'; import 'package:collection/collection.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; import 'package:flutter/widgets.dart'; import 'package:intl/intl.dart'; import 'package:percent_indicator/circular_percent_indicator.dart'; @@ -221,8 +223,6 @@ class SelectionActionDelegate with FeedbackMixin, PermissionAwareMixin { OverlayEntry _opReportOverlayEntry; - static const _overlayAnimationDuration = Duration(milliseconds: 300); - void _showOpReport({ @required BuildContext context, @required List selection, @@ -260,7 +260,7 @@ class SelectionActionDelegate with FeedbackMixin, PermissionAwareMixin { ); } return AnimatedSwitcher( - duration: _overlayAnimationDuration, + duration: Durations.collectionOpOverlayAnimation, child: child, ); }); @@ -270,7 +270,7 @@ class SelectionActionDelegate with FeedbackMixin, PermissionAwareMixin { } Future _hideOpReportOverlay() async { - await Future.delayed(_overlayAnimationDuration); + await Future.delayed(Durations.collectionOpOverlayAnimation * timeDilation); _opReportOverlayEntry.remove(); _opReportOverlayEntry = null; } diff --git a/lib/widgets/common/fx/sweeper.dart b/lib/widgets/common/fx/sweeper.dart index 53f1ab4a9..92bf7bd42 100644 --- a/lib/widgets/common/fx/sweeper.dart +++ b/lib/widgets/common/fx/sweeper.dart @@ -1,5 +1,6 @@ import 'dart:math'; +import 'package:aves/utils/durations.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; @@ -34,14 +35,11 @@ class _SweeperState extends State with SingleTickerProviderStateMixin { bool get isToggled => widget.toggledNotifier.value; - static const opacityAnimationDurationMillis = 150; - static const sweepingDurationMillis = 650; - @override void initState() { super.initState(); _angleAnimationController = AnimationController( - duration: const Duration(milliseconds: sweepingDurationMillis), + duration: Durations.sweepingAnimation, vsync: this, ); final startAngle = widget.startAngle; @@ -86,7 +84,7 @@ class _SweeperState extends State with SingleTickerProviderStateMixin { return IgnorePointer( child: AnimatedOpacity( opacity: isToggled && (_isAppearing || _angleAnimationController.status == AnimationStatus.forward) ? 1 : 0, - duration: const Duration(milliseconds: opacityAnimationDurationMillis), + duration: Durations.sweeperOpacityAnimation, child: ValueListenableBuilder( valueListenable: _angleAnimationController, builder: (context, value, child) { @@ -113,7 +111,7 @@ class _SweeperState extends State with SingleTickerProviderStateMixin { if (isToggled) { _isAppearing = true; setState(() {}); - await Future.delayed(Duration(milliseconds: (opacityAnimationDurationMillis * timeDilation).toInt())); + await Future.delayed(Durations.sweeperOpacityAnimation * timeDilation); _isAppearing = false; if (mounted) { _angleAnimationController.reset(); diff --git a/lib/widgets/filter_grid_page.dart b/lib/widgets/filter_grid_page.dart index 612ac39ef..42e7fdbe1 100644 --- a/lib/widgets/filter_grid_page.dart +++ b/lib/widgets/filter_grid_page.dart @@ -7,6 +7,7 @@ import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/image_entry.dart'; import 'package:aves/model/settings.dart'; import 'package:aves/utils/android_file_utils.dart'; +import 'package:aves/utils/durations.dart'; import 'package:aves/widgets/album/collection_page.dart'; import 'package:aves/widgets/album/thumbnail/raster.dart'; import 'package:aves/widgets/album/thumbnail/vector.dart'; @@ -115,7 +116,8 @@ class FilterGridPage extends StatelessWidget { return AnimationConfiguration.staggeredGrid( position: i, columnCount: columnCount, - duration: const Duration(milliseconds: 375), + duration: Durations.staggeredAnimation, + delay: Durations.staggeredAnimationDelay, child: SlideAnimation( verticalOffset: 50.0, child: FadeInAnimation( diff --git a/lib/widgets/fullscreen/fullscreen_body.dart b/lib/widgets/fullscreen/fullscreen_body.dart index 7fc0a5c69..81c6aea33 100644 --- a/lib/widgets/fullscreen/fullscreen_body.dart +++ b/lib/widgets/fullscreen/fullscreen_body.dart @@ -5,6 +5,7 @@ import 'package:aves/model/collection_lens.dart'; import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/image_entry.dart'; import 'package:aves/utils/change_notifier.dart'; +import 'package:aves/utils/durations.dart'; import 'package:aves/widgets/album/collection_page.dart'; import 'package:aves/widgets/common/action_delegates/entry_action_delegate.dart'; import 'package:aves/widgets/common/image_providers/thumbnail_provider.dart'; @@ -73,7 +74,7 @@ class FullscreenBodyState extends State with SingleTickerProvide _horizontalPager = PageController(initialPage: _currentHorizontalPage); _verticalPager = PageController(initialPage: _currentVerticalPage.value)..addListener(_onVerticalPageControllerChange); _overlayAnimationController = AnimationController( - duration: const Duration(milliseconds: 200), + duration: Durations.fullscreenOverlayAnimation, vsync: this, ); _topOverlayScale = CurvedAnimation( @@ -97,8 +98,8 @@ class FullscreenBodyState extends State with SingleTickerProvide ); WidgetsBinding.instance.addObserver(this); _initVideoController(); - _initOverlay(); _registerWidget(widget); + WidgetsBinding.instance.addPostFrameCallback((_) => _initOverlay()); } @override @@ -283,7 +284,7 @@ class FullscreenBodyState extends State with SingleTickerProvide Future _goToVerticalPage(int page) { return _verticalPager.animateToPage( page, - duration: Duration(milliseconds: (300 * timeDilation).toInt()), + duration: Durations.fullscreenPageAnimation, curve: Curves.easeInOut, ); } @@ -321,18 +322,18 @@ class FullscreenBodyState extends State with SingleTickerProvide _showSystemUI(); } -// system UI + // system UI static void _showSystemUI() => SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values); static void _hideSystemUI() => SystemChrome.setEnabledSystemUIOverlays([]); -// overlay + // overlay Future _initOverlay() async { // wait for MaterialPageRoute.transitionDuration // to show overlay after hero animation is complete - await Future.delayed(Duration(milliseconds: (300 * timeDilation).toInt())); + await Future.delayed(ModalRoute.of(context).transitionDuration * timeDilation); await _onOverlayVisibleChange(); } diff --git a/lib/widgets/fullscreen/info/info_page.dart b/lib/widgets/fullscreen/info/info_page.dart index 73e46de4a..bb8ce3594 100644 --- a/lib/widgets/fullscreen/info/info_page.dart +++ b/lib/widgets/fullscreen/info/info_page.dart @@ -1,6 +1,7 @@ import 'package:aves/model/collection_lens.dart'; import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/image_entry.dart'; +import 'package:aves/utils/durations.dart'; import 'package:aves/widgets/common/aves_filter_chip.dart'; import 'package:aves/widgets/common/data_providers/media_query_data_provider.dart'; import 'package:aves/widgets/common/icons.dart'; @@ -8,7 +9,6 @@ import 'package:aves/widgets/fullscreen/info/basic_section.dart'; import 'package:aves/widgets/fullscreen/info/location_section.dart'; import 'package:aves/widgets/fullscreen/info/metadata_section.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/scheduler.dart'; import 'package:provider/provider.dart'; import 'package:tuple/tuple.dart'; @@ -177,7 +177,7 @@ class InfoPageState extends State { BackUpNotification().dispatch(context); _scrollController.animateTo( 0, - duration: Duration(milliseconds: (300 * timeDilation).toInt()), + duration: Durations.fullscreenPageAnimation, curve: Curves.easeInOut, ); } diff --git a/lib/widgets/fullscreen/overlay/video.dart b/lib/widgets/fullscreen/overlay/video.dart index 69633dd69..2dbe893da 100644 --- a/lib/widgets/fullscreen/overlay/video.dart +++ b/lib/widgets/fullscreen/overlay/video.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:aves/model/image_entry.dart'; import 'package:aves/services/android_app_service.dart'; +import 'package:aves/utils/durations.dart'; import 'package:aves/utils/time_utils.dart'; import 'package:aves/widgets/common/fx/blurred.dart'; import 'package:aves/widgets/common/icons.dart'; @@ -61,7 +62,7 @@ class VideoControlOverlayState extends State with SingleTic void initState() { super.initState(); _playPauseAnimation = AnimationController( - duration: const Duration(milliseconds: 300), + duration: Durations.iconAnimation, vsync: this, ); _registerWidget(widget); @@ -220,9 +221,7 @@ class VideoControlOverlayState extends State with SingleTic void _startTimer() { if (controller.textureId == null) return; _progressTimer?.cancel(); - _progressTimer = Timer.periodic(const Duration(milliseconds: 300), (timer) { - controller.refreshVideoInfo(); - }); + _progressTimer = Timer.periodic(Durations.videoProgressTimerInterval, (_) => controller.refreshVideoInfo()); } void _stopTimer() { diff --git a/lib/widgets/welcome.dart b/lib/widgets/welcome.dart index d86497447..0a536c9a7 100644 --- a/lib/widgets/welcome.dart +++ b/lib/widgets/welcome.dart @@ -1,6 +1,7 @@ import 'package:aves/main.dart'; import 'package:aves/model/settings.dart'; import 'package:aves/model/terms.dart'; +import 'package:aves/utils/durations.dart'; import 'package:aves/widgets/common/aves_logo.dart'; import 'package:aves/widgets/common/labeled_checkbox.dart'; import 'package:flutter/material.dart'; @@ -28,7 +29,8 @@ class _WelcomePageState extends State { child: Column( mainAxisSize: MainAxisSize.min, children: _toStaggeredList( - duration: const Duration(milliseconds: 375), + duration: Durations.staggeredAnimation, + delay: Durations.staggeredAnimationDelay, childAnimationBuilder: (child) => SlideAnimation( verticalOffset: 50.0, child: FadeInAnimation(