don't use Offstage as widget of animated loading, reuse refresh as

loading

Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
21pages 2023-08-18 12:52:50 +08:00
parent d56356e595
commit 24e6b54650
5 changed files with 28 additions and 102 deletions

View File

@ -10,7 +10,6 @@ import 'package:get/get.dart';
import '../../common.dart';
import 'dialog.dart';
import 'loading_dot_widget.dart';
import 'login.dart';
final hideAbTagsPanel = false.obs;
@ -47,8 +46,7 @@ class _AddressBookState extends State<AddressBook> {
}
return Column(
children: [
_buildNotEmptyLoading(),
_buildRetryProgress(),
if (gFFI.abModel.retrying.value) LinearProgressIndicator(),
_buildErrorBanner(
err: gFFI.abModel.pullError,
retry: null,
@ -121,29 +119,6 @@ class _AddressBookState extends State<AddressBook> {
));
}
Widget _buildNotEmptyLoading() {
double size = 15;
return Obx(() => Offstage(
offstage: !(gFFI.abModel.abLoading.value && !gFFI.abModel.emtpy),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
height: size,
child: Center(child: LoadingDotWidget(size: size)))
.marginSymmetric(vertical: 10)
],
),
));
}
Widget _buildRetryProgress() {
return Obx(() => Offstage(
offstage: !gFFI.abModel.retrying.value,
child: LinearProgressIndicator(),
));
}
Widget _buildAddressBookDesktop() {
return Row(
children: [

View File

@ -1,11 +1,17 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class AnimatedRotationWidget extends StatefulWidget {
final VoidCallback onPressed;
final ValueChanged<bool>? onHover;
final Widget child;
final RxBool? spinning;
const AnimatedRotationWidget(
{super.key, required this.onPressed, required this.child, this.onHover});
{super.key,
required this.onPressed,
required this.child,
this.spinning,
this.onHover});
@override
State<AnimatedRotationWidget> createState() => AnimatedRotationWidgetState();
@ -14,14 +20,31 @@ class AnimatedRotationWidget extends StatefulWidget {
class AnimatedRotationWidgetState extends State<AnimatedRotationWidget> {
double turns = 0.0;
@override
void initState() {
super.initState();
widget.spinning?.listen((v) {
if (v && mounted) {
setState(() {
turns += 1;
});
}
});
}
@override
Widget build(BuildContext context) {
return AnimatedRotation(
turns: turns,
duration: const Duration(milliseconds: 200),
onEnd: () {
if (widget.spinning?.value == true && mounted) {
setState(() => turns += 1.0);
}
},
child: InkWell(
onTap: () {
setState(() => turns += 1.0);
if (mounted) setState(() => turns += 1.0);
widget.onPressed();
},
onHover: widget.onHover,

View File

@ -1,65 +0,0 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class LoadingDotWidget extends StatefulWidget {
final int count;
final double size;
final int duration;
LoadingDotWidget(
{Key? key, required this.size, this.count = 3, this.duration = 200})
: super(key: key);
@override
State<LoadingDotWidget> createState() => _LoadingDotWidgetState();
}
class _LoadingDotWidgetState extends State<LoadingDotWidget> {
int counter = 0;
Timer? timer;
@override
void initState() {
super.initState();
startAnimation();
}
@override
void dispose() {
timer?.cancel();
super.dispose();
}
void startAnimation() {
timer = Timer.periodic(Duration(milliseconds: widget.duration), (timer) {
if (mounted) {
setState(() {
counter = (counter + 1) % widget.count;
});
}
});
}
@override
Widget build(BuildContext context) {
getChild(int index) {
return AnimatedContainer(
duration: Duration(milliseconds: widget.duration),
width: counter == index ? widget.size : widget.size / 2,
height: counter == index ? widget.size : widget.size / 2,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.grey,
),
).marginSymmetric(horizontal: widget.size);
}
return Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(widget.count, (e) => e)
.map((e) => getChild(e))
.toList()),
);
}
}

View File

@ -219,6 +219,7 @@ class _PeerTabPageState extends State<PeerTabPage>
entries[gFFI.peerTabModel.currentTab].load();
}
},
spinning: gFFI.abModel.abLoading,
child: RotatedBox(
quarterTurns: 2,
child: Tooltip(

View File

@ -59,7 +59,6 @@ class AbModel {
if (!gFFI.userModel.isLogin) return;
if (abLoading.value) return;
if (!force && initialized) return;
DateTime startTime = DateTime.now();
if (pushError.isNotEmpty) {
try {
// push to retry
@ -120,14 +119,7 @@ class AbModel {
}
}
} finally {
var ms =
(Duration(milliseconds: 300) - DateTime.now().difference(startTime))
.inMilliseconds;
ms = ms > 0 ? ms : 0;
Future.delayed(Duration(milliseconds: ms), () {
abLoading.value = false;
});
abLoading.value = false;
initialized = true;
_syncAllFromRecent = true;
_timerCounter = 0;