peer ab/group tab refresh, animated refresh icon

Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
21pages 2023-06-21 11:51:35 +08:00
parent ec9062f505
commit 0bda66dd7f
5 changed files with 81 additions and 27 deletions

View File

@ -0,0 +1,30 @@
import 'package:flutter/material.dart';
class AnimatedRotationWidget extends StatefulWidget {
final VoidCallback onPressed;
final ValueChanged<bool>? onHover;
final Widget child;
const AnimatedRotationWidget(
{super.key, required this.onPressed, required this.child, this.onHover});
@override
State<AnimatedRotationWidget> createState() => AnimatedRotationWidgetState();
}
class AnimatedRotationWidgetState extends State<AnimatedRotationWidget> {
double turns = 0.0;
@override
Widget build(BuildContext context) {
return AnimatedRotation(
turns: turns,
duration: const Duration(milliseconds: 200),
child: InkWell(
onTap: () {
setState(() => turns += 1.0);
widget.onPressed();
},
onHover: widget.onHover,
child: widget.child));
}
}

View File

@ -37,7 +37,7 @@ class _MyGroupState extends State<MyGroup> {
}); });
Future<Widget> buildBody(BuildContext context) async { Future<Widget> buildBody(BuildContext context) async {
gFFI.groupModel.pullUserPeers(); gFFI.groupModel.pull();
return Obx(() { return Obx(() {
if (gFFI.groupModel.groupLoading.value || if (gFFI.groupModel.groupLoading.value ||
gFFI.groupModel.peerLoading.value) { gFFI.groupModel.peerLoading.value) {

View File

@ -1,4 +1,3 @@
import 'dart:math';
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:bot_toast/bot_toast.dart'; import 'package:bot_toast/bot_toast.dart';
@ -8,6 +7,7 @@ import 'package:flutter_hbb/common/widgets/address_book.dart';
import 'package:flutter_hbb/common/widgets/my_group.dart'; import 'package:flutter_hbb/common/widgets/my_group.dart';
import 'package:flutter_hbb/common/widgets/peers_view.dart'; import 'package:flutter_hbb/common/widgets/peers_view.dart';
import 'package:flutter_hbb/common/widgets/peer_card.dart'; import 'package:flutter_hbb/common/widgets/peer_card.dart';
import 'package:flutter_hbb/common/widgets/animated_rotation_widget.dart';
import 'package:flutter_hbb/consts.dart'; import 'package:flutter_hbb/consts.dart';
import 'package:flutter_hbb/desktop/widgets/popup_menu.dart'; import 'package:flutter_hbb/desktop/widgets/popup_menu.dart';
import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart'; import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart';
@ -18,7 +18,6 @@ import 'package:get/get.dart';
import 'package:get/get_rx/src/rx_workers/utils/debouncer.dart'; import 'package:get/get_rx/src/rx_workers/utils/debouncer.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:visibility_detector/visibility_detector.dart'; import 'package:visibility_detector/visibility_detector.dart';
import 'package:dropdown_button2/dropdown_button2.dart';
import '../../common.dart'; import '../../common.dart';
import '../../models/platform_model.dart'; import '../../models/platform_model.dart';
@ -63,12 +62,13 @@ class _PeerTabPageState extends State<PeerTabPage>
AddressBook( AddressBook(
menuPadding: _menuPadding(), menuPadding: _menuPadding(),
), ),
() => {}), () => gFFI.abModel.pullAb()),
_TabEntry( _TabEntry(
MyGroup( MyGroup(
menuPadding: _menuPadding(), menuPadding: _menuPadding(),
), ),
() => {}), () => gFFI.groupModel.pull(),
),
]; ];
final _scrollDebounce = Debouncer(delay: Duration(milliseconds: 50)); final _scrollDebounce = Debouncer(delay: Duration(milliseconds: 50));
@ -109,11 +109,11 @@ class _PeerTabPageState extends State<PeerTabPage>
child: child:
visibleContextMenuListener(_createSwitchBar(context))), visibleContextMenuListener(_createSwitchBar(context))),
buildScrollJumper(), buildScrollJumper(),
const PeerSearchBar(), const PeerSearchBar().marginOnly(right: 13),
_createRefresh(),
Offstage( Offstage(
offstage: !isDesktop, offstage: !isDesktop,
child: _createPeerViewTypeSwitch(context) child: _createPeerViewTypeSwitch(context)),
.marginOnly(left: 13)),
Offstage( Offstage(
offstage: _hideSort, offstage: _hideSort,
child: PeerSortDropdown().marginOnly(left: 8), child: PeerSortDropdown().marginOnly(left: 8),
@ -241,6 +241,29 @@ class _PeerTabPageState extends State<PeerTabPage>
child: child.marginSymmetric(vertical: isDesktop ? 12.0 : 6.0)); child: child.marginSymmetric(vertical: isDesktop ? 12.0 : 6.0));
} }
Widget _createRefresh() {
final textColor = Theme.of(context).textTheme.titleLarge?.color;
return Offstage(
offstage: gFFI.peerTabModel.currentTab < 3, // local tab can't see effect
child: Container(
padding: EdgeInsets.all(4.0),
child: AnimatedRotationWidget(
onPressed: () {
if (gFFI.peerTabModel.currentTab < entries.length) {
entries[gFFI.peerTabModel.currentTab].load();
}
},
child: RotatedBox(
quarterTurns: 2,
child: Icon(
Icons.refresh,
size: 18,
color: textColor,
))),
),
);
}
Widget _createPeerViewTypeSwitch(BuildContext context) { Widget _createPeerViewTypeSwitch(BuildContext context) {
final textColor = Theme.of(context).textTheme.titleLarge?.color; final textColor = Theme.of(context).textTheme.titleLarge?.color;
final deco = BoxDecoration( final deco = BoxDecoration(

View File

@ -6,6 +6,7 @@ import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_hbb/common.dart'; import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/common/widgets/animated_rotation_widget.dart';
import 'package:flutter_hbb/common/widgets/custom_password.dart'; import 'package:flutter_hbb/common/widgets/custom_password.dart';
import 'package:flutter_hbb/consts.dart'; import 'package:flutter_hbb/consts.dart';
import 'package:flutter_hbb/desktop/pages/connection_page.dart'; import 'package:flutter_hbb/desktop/pages/connection_page.dart';
@ -247,19 +248,19 @@ class _DesktopHomePageState extends State<DesktopHomePage>
), ),
), ),
), ),
InkWell( AnimatedRotationWidget(
child: Obx( onPressed: () => bind.mainUpdateTemporaryPassword(),
() => Icon( child: Obx(() => RotatedBox(
Icons.refresh, quarterTurns: 2,
color: refreshHover.value child: Icon(
? textColor Icons.refresh,
: Color(0xFFDDDDDD), color: refreshHover.value
size: 22, ? textColor
).marginOnly(right: 8, top: 4), : Color(0xFFDDDDDD),
), size: 22,
onTap: () => bind.mainUpdateTemporaryPassword(), ))),
onHover: (value) => refreshHover.value = value, onHover: (value) => refreshHover.value = value,
), ).marginOnly(right: 8, top: 4),
InkWell( InkWell(
child: Obx( child: Obx(
() => Icon( () => Icon(
@ -574,7 +575,7 @@ class _DesktopHomePageState extends State<DesktopHomePage>
_updateTimer?.cancel(); _updateTimer?.cancel();
super.dispose(); super.dispose();
} }
Widget buildPluginEntry() { Widget buildPluginEntry() {
final entries = PluginUiManager.instance.entries.entries; final entries = PluginUiManager.instance.entries.entries;
return Offstage( return Offstage(
@ -582,8 +583,7 @@ class _DesktopHomePageState extends State<DesktopHomePage>
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
... ...entries.map((entry) {
entries.map((entry) {
return entry.value; return entry.value;
}) })
], ],

View File

@ -103,6 +103,7 @@ class GroupModel {
} finally { } finally {
groupLoading.value = false; groupLoading.value = false;
gFFI.peerTabModel.check_dynamic_tabs(); gFFI.peerTabModel.check_dynamic_tabs();
_pullUserPeers();
} }
} }
@ -134,7 +135,7 @@ class GroupModel {
return false; return false;
} }
Future<void> pullUserPeers() async { Future<void> _pullUserPeers() async {
peersShow.clear(); peersShow.clear();
peerLoading.value = true; peerLoading.value = true;
peerLoadError.value = ""; peerLoadError.value = "";