diff --git a/flutter/lib/common/widgets/address_book.dart b/flutter/lib/common/widgets/address_book.dart index 3c192c166..4aa1326bf 100644 --- a/flutter/lib/common/widgets/address_book.dart +++ b/flutter/lib/common/widgets/address_book.dart @@ -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 { } 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 { )); } - 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: [ diff --git a/flutter/lib/common/widgets/animated_rotation_widget.dart b/flutter/lib/common/widgets/animated_rotation_widget.dart index 525508e44..0efc71552 100644 --- a/flutter/lib/common/widgets/animated_rotation_widget.dart +++ b/flutter/lib/common/widgets/animated_rotation_widget.dart @@ -1,11 +1,17 @@ import 'package:flutter/material.dart'; +import 'package:get/get.dart'; class AnimatedRotationWidget extends StatefulWidget { final VoidCallback onPressed; final ValueChanged? 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 createState() => AnimatedRotationWidgetState(); @@ -14,14 +20,31 @@ class AnimatedRotationWidget extends StatefulWidget { class AnimatedRotationWidgetState extends State { 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, diff --git a/flutter/lib/common/widgets/loading_dot_widget.dart b/flutter/lib/common/widgets/loading_dot_widget.dart deleted file mode 100644 index 6f8ca4425..000000000 --- a/flutter/lib/common/widgets/loading_dot_widget.dart +++ /dev/null @@ -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 createState() => _LoadingDotWidgetState(); -} - -class _LoadingDotWidgetState extends State { - 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()), - ); - } -} diff --git a/flutter/lib/common/widgets/peer_tab_page.dart b/flutter/lib/common/widgets/peer_tab_page.dart index 1014c283c..c05eb6243 100644 --- a/flutter/lib/common/widgets/peer_tab_page.dart +++ b/flutter/lib/common/widgets/peer_tab_page.dart @@ -219,6 +219,7 @@ class _PeerTabPageState extends State entries[gFFI.peerTabModel.currentTab].load(); } }, + spinning: gFFI.abModel.abLoading, child: RotatedBox( quarterTurns: 2, child: Tooltip( diff --git a/flutter/lib/models/ab_model.dart b/flutter/lib/models/ab_model.dart index ba6c136ff..d802f456c 100644 --- a/flutter/lib/models/ab_model.dart +++ b/flutter/lib/models/ab_model.dart @@ -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;