From e53d0ecf6caa435bc825ab2380736c91b0252f73 Mon Sep 17 00:00:00 2001 From: Ming Ming Date: Sun, 23 Jul 2023 13:08:30 +0800 Subject: [PATCH] Animate settings highlight --- app/lib/k.dart | 2 + app/lib/widget/settings/account_settings.dart | 50 ++++++++++++++----- .../widget/settings/account_settings.g.dart | 5 +- 3 files changed, 42 insertions(+), 15 deletions(-) diff --git a/app/lib/k.dart b/app/lib/k.dart index 670470f1..38c0d9fe 100644 --- a/app/lib/k.dart +++ b/app/lib/k.dart @@ -22,6 +22,8 @@ const animationDurationTabTransition = Duration(milliseconds: 300); const heroDurationNormal = Duration(milliseconds: 450); +const settingsHighlightDuration = Duration(milliseconds: 750); + /// Size of the photo/video thumbnails /// /// It's advisable to use a single size to minimize cache size diff --git a/app/lib/widget/settings/account_settings.dart b/app/lib/widget/settings/account_settings.dart index bcb96693..6997f158 100644 --- a/app/lib/widget/settings/account_settings.dart +++ b/app/lib/widget/settings/account_settings.dart @@ -87,16 +87,20 @@ class _WrappedAccountSettings extends StatefulWidget { const _WrappedAccountSettings(); @override - State createState() => __WrappedAccountSettingsState(); + State createState() => _WrappedAccountSettingsState(); } @npLog -class __WrappedAccountSettingsState extends State<_WrappedAccountSettings> - with RouteAware, PageVisibilityMixin { +class _WrappedAccountSettingsState extends State<_WrappedAccountSettings> + with RouteAware, PageVisibilityMixin, TickerProviderStateMixin { @override void initState() { super.initState(); _accountController = context.read(); + + WidgetsBinding.instance.addPostFrameCallback((_) { + _animationController.repeat(reverse: true); + }); } @override @@ -107,6 +111,7 @@ class __WrappedAccountSettingsState extends State<_WrappedAccountSettings> _accountController.syncController .requestResync(_bloc.state.account, _bloc.state.personProvider); } + _animationController.dispose(); super.dispose(); } @@ -183,15 +188,28 @@ class __WrappedAccountSettingsState extends State<_WrappedAccountSettings> ), _BlocSelector( selector: (state) => state.personProvider, - builder: (context, state) => ListTile( - title: Text(L10n.global().settingsPersonProviderTitle), - subtitle: Text(state.toUserString()), - onTap: () => _onPersonProviderPressed(context), - tileColor: _bloc.highlight == - AccountSettingsOption.personProvider - ? Theme.of(context).colorScheme.primaryContainer - : null, - ), + builder: (context, state) { + if (_bloc.highlight == + AccountSettingsOption.personProvider) { + return AnimatedBuilder( + animation: _highlightAnimation, + builder: (context, child) => ListTile( + title: Text( + L10n.global().settingsPersonProviderTitle), + subtitle: Text(state.toUserString()), + onTap: () => _onPersonProviderPressed(context), + tileColor: _highlightAnimation.value, + ), + ); + } else { + return ListTile( + title: + Text(L10n.global().settingsPersonProviderTitle), + subtitle: Text(state.toUserString()), + onTap: () => _onPersonProviderPressed(context), + ); + } + }, ), ], ), @@ -263,6 +281,14 @@ class __WrappedAccountSettingsState extends State<_WrappedAccountSettings> late final _bloc = context.read<_Bloc>(); late final AccountController _accountController; + + late final _animationController = AnimationController( + vsync: this, + duration: k.settingsHighlightDuration, + ); + late final _highlightAnimation = ColorTween( + end: Theme.of(context).colorScheme.primaryContainer, + ).animate(_animationController); } class _DoneButton extends StatelessWidget { diff --git a/app/lib/widget/settings/account_settings.g.dart b/app/lib/widget/settings/account_settings.g.dart index 04051eed..f587300e 100644 --- a/app/lib/widget/settings/account_settings.g.dart +++ b/app/lib/widget/settings/account_settings.g.dart @@ -58,13 +58,12 @@ extension $_StateCopyWith on _State { // NpLogGenerator // ************************************************************************** -extension _$__WrappedAccountSettingsStateNpLog - on __WrappedAccountSettingsState { +extension _$_WrappedAccountSettingsStateNpLog on _WrappedAccountSettingsState { // ignore: unused_element Logger get _log => log; static final log = - Logger("widget.settings.account_settings.__WrappedAccountSettingsState"); + Logger("widget.settings.account_settings._WrappedAccountSettingsState"); } extension _$_PersonProviderDialogNpLog on _PersonProviderDialog {