accessibility: remove animations (WIP)
This commit is contained in:
parent
808d2de3bd
commit
8560ebdd14
14 changed files with 76 additions and 35 deletions
|
@ -17,7 +17,7 @@ extension ExtraAccessibilityAnimations on AccessibilityAnimations {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get enabled {
|
bool get animate {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case AccessibilityAnimations.system:
|
case AccessibilityAnimations.system:
|
||||||
return !window.accessibilityFeatures.disableAnimations;
|
return !window.accessibilityFeatures.disableAnimations;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:aves/model/settings/accessibility_animations.dart';
|
import 'package:aves/model/settings/accessibility_animations.dart';
|
||||||
|
import 'package:aves/model/settings/enums.dart';
|
||||||
import 'package:aves/model/settings/settings.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
@ -13,7 +14,6 @@ class Durations {
|
||||||
static const toggleableTransitionAnimation = Duration(milliseconds: 200 + 10); // ref `_kToggleDuration` used in `ToggleableStateMixin`
|
static const toggleableTransitionAnimation = Duration(milliseconds: 200 + 10); // ref `_kToggleDuration` used in `ToggleableStateMixin`
|
||||||
|
|
||||||
// common animations
|
// common animations
|
||||||
static const iconAnimation = Duration(milliseconds: 300);
|
|
||||||
static const sweeperOpacityAnimation = Duration(milliseconds: 150);
|
static const sweeperOpacityAnimation = Duration(milliseconds: 150);
|
||||||
static const sweepingAnimation = Duration(milliseconds: 650);
|
static const sweepingAnimation = Duration(milliseconds: 650);
|
||||||
static const dialogFieldReachAnimation = Duration(milliseconds: 300);
|
static const dialogFieldReachAnimation = Duration(milliseconds: 300);
|
||||||
|
@ -72,7 +72,7 @@ class Durations {
|
||||||
static const lastVersionCheckInterval = Duration(days: 7);
|
static const lastVersionCheckInterval = Duration(days: 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
class DurationsProvider extends StatelessWidget {
|
class DurationsProvider extends StatefulWidget {
|
||||||
final Widget child;
|
final Widget child;
|
||||||
|
|
||||||
const DurationsProvider({
|
const DurationsProvider({
|
||||||
|
@ -80,14 +80,38 @@ class DurationsProvider extends StatelessWidget {
|
||||||
required this.child,
|
required this.child,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_DurationsProviderState createState() => _DurationsProviderState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DurationsProviderState extends State<DurationsProvider> with WidgetsBindingObserver {
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
WidgetsBinding.instance!.addObserver(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
WidgetsBinding.instance!.removeObserver(this);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeAccessibilityFeatures() {
|
||||||
|
if (settings.accessibilityAnimations == AccessibilityAnimations.system) {
|
||||||
|
// TODO TLAD update provider
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ProxyProvider<Settings, DurationsData>(
|
return ProxyProvider<Settings, DurationsData>(
|
||||||
update: (_, settings, __) {
|
update: (context, settings, __) {
|
||||||
final enabled = settings.accessibilityAnimations.enabled;
|
final enabled = settings.accessibilityAnimations.animate;
|
||||||
return enabled ? DurationsData() : DurationsData.noAnimation();
|
return enabled ? DurationsData() : DurationsData.noAnimation();
|
||||||
},
|
},
|
||||||
child: child,
|
child: widget.child,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,6 +120,7 @@ class DurationsProvider extends StatelessWidget {
|
||||||
class DurationsData {
|
class DurationsData {
|
||||||
// common animations
|
// common animations
|
||||||
final Duration expansionTileAnimation;
|
final Duration expansionTileAnimation;
|
||||||
|
final Duration iconAnimation;
|
||||||
final Duration staggeredAnimation;
|
final Duration staggeredAnimation;
|
||||||
final Duration staggeredAnimationPageTarget;
|
final Duration staggeredAnimationPageTarget;
|
||||||
|
|
||||||
|
@ -109,6 +134,7 @@ class DurationsData {
|
||||||
|
|
||||||
const DurationsData({
|
const DurationsData({
|
||||||
this.expansionTileAnimation = const Duration(milliseconds: 200),
|
this.expansionTileAnimation = const Duration(milliseconds: 200),
|
||||||
|
this.iconAnimation = const Duration(milliseconds: 300),
|
||||||
this.staggeredAnimation = const Duration(milliseconds: 375),
|
this.staggeredAnimation = const Duration(milliseconds: 375),
|
||||||
this.staggeredAnimationPageTarget = const Duration(milliseconds: 800),
|
this.staggeredAnimationPageTarget = const Duration(milliseconds: 800),
|
||||||
this.viewerVerticalPageScrollAnimation = const Duration(milliseconds: 500),
|
this.viewerVerticalPageScrollAnimation = const Duration(milliseconds: 500),
|
||||||
|
@ -120,6 +146,7 @@ class DurationsData {
|
||||||
return DurationsData(
|
return DurationsData(
|
||||||
// as of Flutter v2.5.1, `ExpansionPanelList` throws if animation duration is zero
|
// as of Flutter v2.5.1, `ExpansionPanelList` throws if animation duration is zero
|
||||||
expansionTileAnimation: const Duration(microseconds: 1),
|
expansionTileAnimation: const Duration(microseconds: 1),
|
||||||
|
iconAnimation: Duration.zero,
|
||||||
staggeredAnimation: Duration.zero,
|
staggeredAnimation: Duration.zero,
|
||||||
staggeredAnimationPageTarget: Duration.zero,
|
staggeredAnimationPageTarget: Duration.zero,
|
||||||
viewerVerticalPageScrollAnimation: Duration.zero,
|
viewerVerticalPageScrollAnimation: Duration.zero,
|
||||||
|
|
|
@ -83,7 +83,7 @@ class _AvesAppState extends State<AvesApp> {
|
||||||
body: snapshot.hasError ? _buildError(snapshot.error!) : const SizedBox(),
|
body: snapshot.hasError ? _buildError(snapshot.error!) : const SizedBox(),
|
||||||
);
|
);
|
||||||
return Selector<Settings, Tuple2<Locale?, bool>>(
|
return Selector<Settings, Tuple2<Locale?, bool>>(
|
||||||
selector: (context, s) => Tuple2(s.locale, s.initialized ? s.accessibilityAnimations.enabled : true),
|
selector: (context, s) => Tuple2(s.locale, s.initialized ? s.accessibilityAnimations.animate : true),
|
||||||
builder: (context, s, child) {
|
builder: (context, s, child) {
|
||||||
final settingsLocale = s.item1;
|
final settingsLocale = s.item1;
|
||||||
final areAnimationsEnabled = s.item2;
|
final areAnimationsEnabled = s.item2;
|
||||||
|
|
|
@ -57,7 +57,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_browseToSelectAnimation = AnimationController(
|
_browseToSelectAnimation = AnimationController(
|
||||||
duration: Durations.iconAnimation,
|
duration: context.read<DurationsData>().iconAnimation,
|
||||||
vsync: this,
|
vsync: this,
|
||||||
);
|
);
|
||||||
_isSelectingNotifier.addListener(_onActivityChange);
|
_isSelectingNotifier.addListener(_onActivityChange);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:aves/model/settings/accessibility_animations.dart';
|
||||||
import 'package:aves/model/settings/enums.dart';
|
import 'package:aves/model/settings/enums.dart';
|
||||||
import 'package:aves/model/settings/settings.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/services/accessibility_service.dart';
|
import 'package:aves/services/accessibility_service.dart';
|
||||||
|
@ -8,6 +9,7 @@ import 'package:aves/theme/durations.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:percent_indicator/circular_percent_indicator.dart';
|
import 'package:percent_indicator/circular_percent_indicator.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
mixin FeedbackMixin {
|
mixin FeedbackMixin {
|
||||||
void dismissFeedback(BuildContext context) => ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
void dismissFeedback(BuildContext context) => ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
||||||
|
@ -142,6 +144,7 @@ class _ReportOverlayState<T> extends State<ReportOverlay<T>> with SingleTickerPr
|
||||||
final total = widget.itemCount;
|
final total = widget.itemCount;
|
||||||
assert(processedCount <= total);
|
assert(processedCount <= total);
|
||||||
final percent = min(1.0, processedCount / total);
|
final percent = min(1.0, processedCount / total);
|
||||||
|
final animate = context.select<Settings, bool>((v) => v.accessibilityAnimations.animate);
|
||||||
return FadeTransition(
|
return FadeTransition(
|
||||||
opacity: _animation,
|
opacity: _animation,
|
||||||
child: Container(
|
child: Container(
|
||||||
|
@ -156,22 +159,23 @@ class _ReportOverlayState<T> extends State<ReportOverlay<T>> with SingleTickerPr
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
if (animate)
|
||||||
width: radius,
|
Container(
|
||||||
height: radius,
|
width: radius,
|
||||||
padding: const EdgeInsets.all(strokeWidth / 2),
|
height: radius,
|
||||||
child: CircularProgressIndicator(
|
padding: const EdgeInsets.all(strokeWidth / 2),
|
||||||
color: progressColor.withOpacity(.1),
|
child: CircularProgressIndicator(
|
||||||
strokeWidth: strokeWidth,
|
color: progressColor.withOpacity(.1),
|
||||||
|
strokeWidth: strokeWidth,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
CircularPercentIndicator(
|
CircularPercentIndicator(
|
||||||
percent: percent,
|
percent: percent,
|
||||||
lineWidth: strokeWidth,
|
lineWidth: strokeWidth,
|
||||||
radius: radius,
|
radius: radius,
|
||||||
backgroundColor: Colors.white24,
|
backgroundColor: Colors.white24,
|
||||||
progressColor: progressColor,
|
progressColor: progressColor,
|
||||||
animation: true,
|
animation: animate,
|
||||||
center: Text(NumberFormat.percentPattern().format(percent)),
|
center: Text(NumberFormat.percentPattern().format(percent)),
|
||||||
animateFromLastPercent: true,
|
animateFromLastPercent: true,
|
||||||
),
|
),
|
||||||
|
|
|
@ -297,8 +297,8 @@ class _AvesFilterChipState extends State<AvesFilterChip> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
final enabledAnimations = context.select<Settings, bool>((v) => v.accessibilityAnimations.enabled);
|
final animate = context.select<Settings, bool>((v) => v.accessibilityAnimations.animate);
|
||||||
if (enabledAnimations && (widget.heroType == HeroType.always || widget.heroType == HeroType.onTap && _tapped)) {
|
if (animate && (widget.heroType == HeroType.always || widget.heroType == HeroType.onTap && _tapped)) {
|
||||||
chip = Hero(
|
chip = Hero(
|
||||||
tag: filter,
|
tag: filter,
|
||||||
transitionOnUserGestures: true,
|
transitionOnUserGestures: true,
|
||||||
|
|
|
@ -25,7 +25,7 @@ class MapTheme extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ProxyProvider<Settings, MapThemeData>(
|
return ProxyProvider<Settings, MapThemeData>(
|
||||||
update: (_, settings, __) {
|
update: (context, settings, __) {
|
||||||
return MapThemeData(
|
return MapThemeData(
|
||||||
interactive: interactive,
|
interactive: interactive,
|
||||||
navigationButton: navigationButton,
|
navigationButton: navigationButton,
|
||||||
|
|
|
@ -18,7 +18,7 @@ class TileExtentControllerProvider extends StatelessWidget {
|
||||||
builder: (context, constraints) {
|
builder: (context, constraints) {
|
||||||
return LayoutBuilder(
|
return LayoutBuilder(
|
||||||
builder: (context, constraints) => ProxyProvider0<TileExtentController>(
|
builder: (context, constraints) => ProxyProvider0<TileExtentController>(
|
||||||
update: (_, __) => controller..setViewportSize(constraints.biggest),
|
update: (context, __) => controller..setViewportSize(constraints.biggest),
|
||||||
child: child,
|
child: child,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -173,9 +173,9 @@ class _ThumbnailImageState extends State<ThumbnailImage> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final enabledAnimations = context.select<Settings, bool>((v) => v.accessibilityAnimations.enabled);
|
final animate = context.select<Settings, bool>((v) => v.accessibilityAnimations.animate);
|
||||||
if (!entry.canDecode || _lastException != null) {
|
if (!entry.canDecode || _lastException != null) {
|
||||||
return _buildError(context, enabledAnimations);
|
return _buildError(context, animate);
|
||||||
}
|
}
|
||||||
|
|
||||||
// use `RawImage` instead of `Image`, using `ImageInfo` to check dimensions
|
// use `RawImage` instead of `Image`, using `ImageInfo` to check dimensions
|
||||||
|
@ -231,7 +231,7 @@ class _ThumbnailImageState extends State<ThumbnailImage> {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (enabledAnimations && widget.heroTag != null) {
|
if (animate && widget.heroTag != null) {
|
||||||
image = Hero(
|
image = Hero(
|
||||||
tag: widget.heroTag!,
|
tag: widget.heroTag!,
|
||||||
flightShuttleBuilder: (flight, animation, direction, fromHero, toHero) {
|
flightShuttleBuilder: (flight, animation, direction, fromHero, toHero) {
|
||||||
|
@ -248,13 +248,13 @@ class _ThumbnailImageState extends State<ThumbnailImage> {
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildError(BuildContext context, bool enabledAnimations) {
|
Widget _buildError(BuildContext context, bool animate) {
|
||||||
Widget child = ErrorThumbnail(
|
Widget child = ErrorThumbnail(
|
||||||
entry: entry,
|
entry: entry,
|
||||||
extent: extent,
|
extent: extent,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (enabledAnimations && widget.heroTag != null) {
|
if (animate && widget.heroTag != null) {
|
||||||
child = Hero(
|
child = Hero(
|
||||||
tag: widget.heroTag!,
|
tag: widget.heroTag!,
|
||||||
flightShuttleBuilder: (flight, animation, direction, fromHero, toHero) {
|
flightShuttleBuilder: (flight, animation, direction, fromHero, toHero) {
|
||||||
|
|
|
@ -59,7 +59,7 @@ class _FilterGridAppBarState<T extends CollectionFilter> extends State<FilterGri
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_browseToSelectAnimation = AnimationController(
|
_browseToSelectAnimation = AnimationController(
|
||||||
duration: Durations.iconAnimation,
|
duration: context.read<DurationsData>().iconAnimation,
|
||||||
vsync: this,
|
vsync: this,
|
||||||
);
|
);
|
||||||
_isSelectingNotifier.addListener(_onActivityChange);
|
_isSelectingNotifier.addListener(_onActivityChange);
|
||||||
|
|
|
@ -5,6 +5,8 @@ import 'package:aves/model/filters/filters.dart';
|
||||||
import 'package:aves/model/filters/location.dart';
|
import 'package:aves/model/filters/location.dart';
|
||||||
import 'package:aves/model/filters/mime.dart';
|
import 'package:aves/model/filters/mime.dart';
|
||||||
import 'package:aves/model/filters/tag.dart';
|
import 'package:aves/model/filters/tag.dart';
|
||||||
|
import 'package:aves/model/settings/accessibility_animations.dart';
|
||||||
|
import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/model/source/collection_lens.dart';
|
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/theme/icons.dart';
|
import 'package:aves/theme/icons.dart';
|
||||||
|
@ -22,6 +24,7 @@ import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:percent_indicator/linear_percent_indicator.dart';
|
import 'package:percent_indicator/linear_percent_indicator.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class StatsPage extends StatelessWidget {
|
class StatsPage extends StatelessWidget {
|
||||||
static const routeName = '/collection/stats';
|
static const routeName = '/collection/stats';
|
||||||
|
@ -67,6 +70,7 @@ class StatsPage extends StatelessWidget {
|
||||||
text: context.l10n.collectionEmptyImages,
|
text: context.l10n.collectionEmptyImages,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
final animate = context.select<Settings, bool>((v) => v.accessibilityAnimations.animate);
|
||||||
final byMimeTypes = groupBy<AvesEntry, String>(entries, (entry) => entry.mimeType).map<String, int>((k, v) => MapEntry(k, v.length));
|
final byMimeTypes = groupBy<AvesEntry, String>(entries, (entry) => entry.mimeType).map<String, int>((k, v) => MapEntry(k, v.length));
|
||||||
final imagesByMimeTypes = Map.fromEntries(byMimeTypes.entries.where((kv) => kv.key.startsWith('image')));
|
final imagesByMimeTypes = Map.fromEntries(byMimeTypes.entries.where((kv) => kv.key.startsWith('image')));
|
||||||
final videoByMimeTypes = Map.fromEntries(byMimeTypes.entries.where((kv) => kv.key.startsWith('video')));
|
final videoByMimeTypes = Map.fromEntries(byMimeTypes.entries.where((kv) => kv.key.startsWith('video')));
|
||||||
|
@ -74,8 +78,8 @@ class StatsPage extends StatelessWidget {
|
||||||
alignment: WrapAlignment.center,
|
alignment: WrapAlignment.center,
|
||||||
crossAxisAlignment: WrapCrossAlignment.center,
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
_buildMimeDonut(context, (sum) => context.l10n.statsImage(sum), imagesByMimeTypes),
|
_buildMimeDonut(context, (sum) => context.l10n.statsImage(sum), imagesByMimeTypes, animate),
|
||||||
_buildMimeDonut(context, (sum) => context.l10n.statsVideo(sum), videoByMimeTypes),
|
_buildMimeDonut(context, (sum) => context.l10n.statsVideo(sum), videoByMimeTypes, animate),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -94,7 +98,7 @@ class StatsPage extends StatelessWidget {
|
||||||
lineHeight: lineHeight,
|
lineHeight: lineHeight,
|
||||||
backgroundColor: Colors.white24,
|
backgroundColor: Colors.white24,
|
||||||
progressColor: Theme.of(context).colorScheme.secondary,
|
progressColor: Theme.of(context).colorScheme.secondary,
|
||||||
animation: true,
|
animation: animate,
|
||||||
leading: const Icon(AIcons.location),
|
leading: const Icon(AIcons.location),
|
||||||
// right padding to match leading, so that inside label is aligned with outside label below
|
// right padding to match leading, so that inside label is aligned with outside label below
|
||||||
padding: EdgeInsets.symmetric(horizontal: lineHeight) + const EdgeInsets.only(right: 24),
|
padding: EdgeInsets.symmetric(horizontal: lineHeight) + const EdgeInsets.only(right: 24),
|
||||||
|
@ -130,7 +134,12 @@ class StatsPage extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildMimeDonut(BuildContext context, String Function(int) label, Map<String, int> byMimeTypes) {
|
Widget _buildMimeDonut(
|
||||||
|
BuildContext context,
|
||||||
|
String Function(int) label,
|
||||||
|
Map<String, int> byMimeTypes,
|
||||||
|
bool animate,
|
||||||
|
) {
|
||||||
if (byMimeTypes.isEmpty) return const SizedBox.shrink();
|
if (byMimeTypes.isEmpty) return const SizedBox.shrink();
|
||||||
|
|
||||||
final sum = byMimeTypes.values.fold<int>(0, (prev, v) => prev + v);
|
final sum = byMimeTypes.values.fold<int>(0, (prev, v) => prev + v);
|
||||||
|
@ -165,6 +174,7 @@ class StatsPage extends StatelessWidget {
|
||||||
children: [
|
children: [
|
||||||
charts.PieChart(
|
charts.PieChart(
|
||||||
series,
|
series,
|
||||||
|
animate: animate,
|
||||||
defaultRenderer: charts.ArcRendererConfig<String>(
|
defaultRenderer: charts.ArcRendererConfig<String>(
|
||||||
arcWidth: 16,
|
arcWidth: 16,
|
||||||
),
|
),
|
||||||
|
|
|
@ -371,7 +371,7 @@ class _PlayTogglerState extends State<_PlayToggler> with SingleTickerProviderSta
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_playPauseAnimation = AnimationController(
|
_playPauseAnimation = AnimationController(
|
||||||
duration: Durations.iconAnimation,
|
duration: context.read<DurationsData>().iconAnimation,
|
||||||
vsync: this,
|
vsync: this,
|
||||||
);
|
);
|
||||||
_registerWidget(widget);
|
_registerWidget(widget);
|
||||||
|
|
|
@ -181,7 +181,7 @@ class VideoActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix
|
||||||
} else {
|
} else {
|
||||||
await controller.play();
|
await controller.play();
|
||||||
// hide overlay
|
// hide overlay
|
||||||
_overlayHidingTimer = Timer(Durations.iconAnimation + Durations.videoOverlayHideDelay, () {
|
_overlayHidingTimer = Timer(context.read<DurationsData>().iconAnimation + Durations.videoOverlayHideDelay, () {
|
||||||
const ToggleOverlayNotification(visible: false).dispatch(context);
|
const ToggleOverlayNotification(visible: false).dispatch(context);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,8 +115,8 @@ class _EntryPageViewState extends State<EntryPageView> {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
final enabledAnimations = context.select<Settings, bool>((v) => v.accessibilityAnimations.enabled);
|
final animate = context.select<Settings, bool>((v) => v.accessibilityAnimations.animate);
|
||||||
if (enabledAnimations) {
|
if (animate) {
|
||||||
child = Consumer<HeroInfo?>(
|
child = Consumer<HeroInfo?>(
|
||||||
builder: (context, info, child) => Hero(
|
builder: (context, info, child) => Hero(
|
||||||
tag: info != null && info.entry == mainEntry ? Object.hashAll([info.collectionId, mainEntry.uri]) : hashCode,
|
tag: info != null && info.entry == mainEntry ? Object.hashAll([info.collectionId, mainEntry.uri]) : hashCode,
|
||||||
|
|
Loading…
Reference in a new issue