refactor: new flutter only typing animation

This commit is contained in:
krille-chan 2024-03-31 19:28:19 +02:00
parent 4fca106a51
commit a8606f18b6
No known key found for this signature in database
3 changed files with 67 additions and 88 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

View file

@ -1,80 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="64"
height="30"
viewBox="0 0 64 30"
version="1.1"
id="svg8"
sodipodi:docname="typing.svg"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs12" />
<sodipodi:namedview
id="namedview10"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
showgrid="false"
inkscape:zoom="9.9296875"
inkscape:cx="24.018883"
inkscape:cy="15.307632"
inkscape:window-width="1920"
inkscape:window-height="1012"
inkscape:window-x="1920"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg8" />
<circle
style="fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;paint-order:normal"
cx="10"
cy="15"
r="9"
id="circle2">
<animate
attributeName="fill"
dur="2s"
values="#000000; #efefef; #000000"
calcMode="spline"
keyTimes="0; 0.5; 1"
keySplines="0 .75 .25 1; .5 0 .5 1"
begin="0s" />
</circle>
<circle
style="fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;paint-order:normal"
cx="32"
cy="15"
r="9"
id="circle4">
<animate
attributeName="fill"
dur="2s"
values="#000000; #efefef; #000000"
calcMode="spline"
keyTimes="0; 0.5; 1"
keySplines="0 .75 .25 1; .5 0 .5 1"
begin="0.25s" />
</circle>
<circle
style="fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;paint-order:normal"
cx="54"
cy="15"
r="9"
id="circle6">
<animate
attributeName="fill"
dur="2s"
values="#000000; #efefef; #000000"
calcMode="spline"
keyTimes="0; 0.5; 1"
keySplines="0 .75 .25 1; .5 0 .5 1"
begin="0.5s" />
</circle>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/app_config.dart';
@ -78,14 +80,8 @@ class TypingIndicators extends StatelessWidget {
bottomRight: Radius.circular(AppConfig.borderRadius), bottomRight: Radius.circular(AppConfig.borderRadius),
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.symmetric(horizontal: 8),
child: typingUsers.isEmpty child: typingUsers.isEmpty ? null : const _TypingDots(),
? null
: Image.asset(
'assets/typing.gif',
height: 30,
filterQuality: FilterQuality.high,
),
), ),
), ),
), ),
@ -95,3 +91,66 @@ class TypingIndicators extends StatelessWidget {
); );
} }
} }
class _TypingDots extends StatefulWidget {
const _TypingDots();
@override
State<_TypingDots> createState() => __TypingDotsState();
}
class __TypingDotsState extends State<_TypingDots> {
int _tick = 0;
late final Timer _timer;
static const Duration animationDuration = Duration(milliseconds: 300);
@override
void initState() {
_timer = Timer.periodic(
animationDuration,
(_) {
if (!mounted) {
return;
}
setState(() {
_tick = (_tick + 1) % 4;
});
},
);
super.initState();
}
@override
void dispose() {
_timer.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
const size = 8.0;
return Row(
mainAxisSize: MainAxisSize.min,
children: [
for (var i = 1; i <= 3; i++)
AnimatedContainer(
duration: animationDuration * 1.5,
curve: FluffyThemes.animationCurve,
width: size,
height: _tick == i ? size * 2 : size,
margin: EdgeInsets.symmetric(
horizontal: 2,
vertical: _tick == i ? 4 : 8,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(size * 2),
color: Theme.of(context).colorScheme.secondary,
),
),
],
);
}
}