Animate while switching between small and large icons

This commit is contained in:
vishnukvmd 2023-09-08 18:26:51 +05:30
parent 1697547091
commit 91cd77ad8d
3 changed files with 149 additions and 118 deletions

View file

@ -16,7 +16,9 @@ import 'package:ente_auth/utils/toast_util.dart';
import 'package:ente_auth/utils/totp_util.dart';
import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:local_hero/local_hero.dart';
import 'package:logging/logging.dart';
import 'package:uuid/uuid.dart';
class CodeWidget extends StatefulWidget {
final Code code;
@ -35,6 +37,7 @@ class _CodeWidgetState extends State<CodeWidget> {
bool _isInitialized = false;
late bool hasConfiguredAccount;
late bool _shouldShowLargeIcon;
final String _key = const Uuid().v4();
@override
void initState() {
@ -148,126 +151,142 @@ class _CodeWidgetState extends State<CodeWidget> {
);
}
SizedBox _getCardContents(AppLocalizations l10n) {
return SizedBox(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (widget.code.type == Type.totp)
CodeTimerProgress(
period: widget.code.period,
),
const SizedBox(
height: 16,
),
Row(
children: [
_shouldShowLargeIcon ? _getIcon() : const SizedBox.shrink(),
Expanded(
child: Column(
children: [
_getTopRow(),
const SizedBox(height: 4),
_getBottomRow(l10n),
],
),
Widget _getCardContents(AppLocalizations l10n) {
return LocalHeroScope(
duration: const Duration(milliseconds: 200),
curve: Curves.easeInOut,
child: SizedBox(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (widget.code.type == Type.totp)
CodeTimerProgress(
period: widget.code.period,
),
],
),
const SizedBox(
height: 20,
),
],
),
);
}
Container _getBottomRow(AppLocalizations l10n) {
return Container(
padding: const EdgeInsets.only(left: 16, right: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: ValueListenableBuilder<String>(
valueListenable: _currentCode,
builder: (context, value, child) {
return Text(
value,
style: const TextStyle(fontSize: 24),
);
},
const SizedBox(
height: 16,
),
),
widget.code.type == Type.totp
? Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
l10n.nextTotpTitle,
style: Theme.of(context).textTheme.bodySmall,
),
ValueListenableBuilder<String>(
valueListenable: _nextCode,
builder: (context, value, child) {
return Text(
value,
style: const TextStyle(
fontSize: 18,
color: Colors.grey,
),
);
},
),
],
)
: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
l10n.nextTotpTitle,
style: Theme.of(context).textTheme.bodySmall,
),
InkWell(
onTap: _onNextHotpTapped,
child: const Icon(
Icons.forward_outlined,
size: 32,
color: Colors.grey,
),
),
],
Row(
children: [
_shouldShowLargeIcon ? _getIcon() : const SizedBox.shrink(),
Expanded(
child: Column(
children: [
_getTopRow(),
const SizedBox(height: 4),
_getBottomRow(l10n),
],
),
),
],
],
),
const SizedBox(
height: 20,
),
],
),
),
);
}
Padding _getTopRow() {
Widget _getBottomRow(AppLocalizations l10n) {
return LocalHero(
tag: _key + "_bottom_row",
child: Container(
padding: const EdgeInsets.only(left: 16, right: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: ValueListenableBuilder<String>(
valueListenable: _currentCode,
builder: (context, value, child) {
return Material(
type: MaterialType.transparency,
child: Text(
value,
style: const TextStyle(fontSize: 24),
),
);
},
),
),
widget.code.type == Type.totp
? Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
l10n.nextTotpTitle,
style: Theme.of(context).textTheme.bodySmall,
),
ValueListenableBuilder<String>(
valueListenable: _nextCode,
builder: (context, value, child) {
return Material(
type: MaterialType.transparency,
child: Text(
value,
style: const TextStyle(
fontSize: 18,
color: Colors.grey,
),
),
);
},
),
],
)
: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
l10n.nextTotpTitle,
style: Theme.of(context).textTheme.bodySmall,
),
InkWell(
onTap: _onNextHotpTapped,
child: const Icon(
Icons.forward_outlined,
size: 32,
color: Colors.grey,
),
),
],
),
],
),
),
);
}
Widget _getTopRow() {
return Padding(
padding: const EdgeInsets.only(left: 16, right: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
safeDecode(widget.code.issuer).trim(),
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 2),
Text(
safeDecode(widget.code.account).trim(),
style: Theme.of(context).textTheme.bodySmall?.copyWith(
fontSize: 12,
color: Colors.grey,
),
),
],
LocalHero(
tag: _key + "_top_row",
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
safeDecode(widget.code.issuer).trim(),
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 2),
Text(
safeDecode(widget.code.account).trim(),
style: Theme.of(context).textTheme.bodySmall?.copyWith(
fontSize: 12,
color: Colors.grey,
),
),
],
),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
@ -290,17 +309,20 @@ class _CodeWidgetState extends State<CodeWidget> {
}
Widget _getIcon() {
return Padding(
padding: _shouldShowLargeIcon
? const EdgeInsets.only(left: 16)
: const EdgeInsets.all(0),
child: GestureDetector(
onTap: () {
PreferenceService.instance.setShowLargeIcons(!_shouldShowLargeIcon);
},
child: IconUtils.instance.getIcon(
safeDecode(widget.code.issuer).trim(),
width: _shouldShowLargeIcon ? 42 : 24,
return LocalHero(
tag: _key,
child: Padding(
padding: _shouldShowLargeIcon
? const EdgeInsets.only(left: 16)
: const EdgeInsets.all(0),
child: GestureDetector(
onTap: () {
PreferenceService.instance.setShowLargeIcons(!_shouldShowLargeIcon);
},
child: IconUtils.instance.getIcon(
safeDecode(widget.code.issuer).trim(),
width: _shouldShowLargeIcon ? 42 : 24,
),
),
),
);

View file

@ -783,6 +783,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.8"
local_hero:
dependency: "direct main"
description:
name: local_hero
sha256: "2dd2904c46d786dbc6f7179ba863e04f2be1fd603c530501a336a07744b60c7b"
url: "https://pub.dev"
source: hosted
version: "0.2.0"
logging:
dependency: "direct main"
description:

View file

@ -51,6 +51,7 @@ dependencies:
intl: ^0.18.0
json_annotation: ^4.5.0
local_auth: ^2.1.3
local_hero: ^0.2.0
logging: ^1.0.1
modal_bottom_sheet: ^3.0.0-pre
move_to_background: ^1.0.2