2024-04-27 16:07:32 +00:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:flutter_animate/flutter_animate.dart';
|
|
|
|
import 'package:solian/models/account.dart';
|
2024-05-03 05:39:52 +00:00
|
|
|
import 'package:solian/widgets/account/account_avatar.dart';
|
2024-04-27 16:07:32 +00:00
|
|
|
import 'dart:math' as math;
|
|
|
|
|
|
|
|
class NoContentWidget extends StatefulWidget {
|
|
|
|
final Account? userinfo;
|
|
|
|
final bool isSpeaking;
|
2024-04-29 12:22:06 +00:00
|
|
|
final bool isFixed;
|
2024-04-27 16:07:32 +00:00
|
|
|
|
2024-04-29 12:22:06 +00:00
|
|
|
const NoContentWidget({
|
|
|
|
super.key,
|
|
|
|
this.userinfo,
|
|
|
|
this.isFixed = false,
|
|
|
|
required this.isSpeaking,
|
|
|
|
});
|
2024-04-27 16:07:32 +00:00
|
|
|
|
|
|
|
@override
|
|
|
|
State<NoContentWidget> createState() => _NoContentWidgetState();
|
|
|
|
}
|
|
|
|
|
2024-05-01 09:37:34 +00:00
|
|
|
class _NoContentWidgetState extends State<NoContentWidget>
|
|
|
|
with SingleTickerProviderStateMixin {
|
2024-04-27 16:07:32 +00:00
|
|
|
late final AnimationController _animationController;
|
|
|
|
|
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
super.initState();
|
|
|
|
_animationController = AnimationController(vsync: this);
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void didUpdateWidget(NoContentWidget old) {
|
|
|
|
super.didUpdateWidget(old);
|
|
|
|
if (widget.isSpeaking) {
|
|
|
|
_animationController.repeat(reverse: true);
|
|
|
|
} else {
|
2024-05-01 09:37:34 +00:00
|
|
|
_animationController
|
|
|
|
.animateTo(0, duration: 300.ms)
|
|
|
|
.then((_) => _animationController.reset());
|
2024-04-27 16:07:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
2024-04-29 12:22:06 +00:00
|
|
|
final double radius = widget.isFixed
|
2024-04-30 12:37:08 +00:00
|
|
|
? 32
|
2024-04-29 12:22:06 +00:00
|
|
|
: math.min(
|
|
|
|
MediaQuery.of(context).size.width * 0.1,
|
|
|
|
MediaQuery.of(context).size.height * 0.1,
|
|
|
|
);
|
2024-04-27 16:07:32 +00:00
|
|
|
|
|
|
|
return Container(
|
|
|
|
alignment: Alignment.center,
|
|
|
|
child: Center(
|
|
|
|
child: Animate(
|
2024-04-29 12:22:06 +00:00
|
|
|
autoPlay: false,
|
|
|
|
controller: _animationController,
|
|
|
|
effects: [
|
|
|
|
CustomEffect(
|
|
|
|
begin: widget.isSpeaking ? 2 : 0,
|
|
|
|
end: 8,
|
|
|
|
curve: Curves.easeInOut,
|
|
|
|
duration: 1250.ms,
|
|
|
|
builder: (context, value, child) => Container(
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
borderRadius: BorderRadius.all(Radius.circular(radius + 8)),
|
2024-05-01 09:37:34 +00:00
|
|
|
border: value > 0
|
|
|
|
? Border.all(color: Colors.green, width: value)
|
|
|
|
: null,
|
2024-04-27 16:07:32 +00:00
|
|
|
),
|
2024-04-29 12:22:06 +00:00
|
|
|
child: child,
|
|
|
|
),
|
|
|
|
)
|
|
|
|
],
|
|
|
|
child: AccountAvatar(
|
|
|
|
source: widget.userinfo!.avatar,
|
|
|
|
backgroundColor: Colors.transparent,
|
|
|
|
radius: radius,
|
|
|
|
direct: true,
|
|
|
|
),
|
|
|
|
),
|
2024-04-27 16:07:32 +00:00
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void dispose() {
|
|
|
|
_animationController.dispose();
|
|
|
|
super.dispose();
|
|
|
|
}
|
|
|
|
}
|