Parcourir la source

完善加载时的动画

Ferry-200 il y a 10 mois
Parent
commit
18552f20d0

+ 34 - 16
summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/settings_page/components/host_setting.dart

@@ -11,6 +11,8 @@ class _SetHostDialogState extends State<_SetHostDialog> {
   final hostEditingController =
       TextEditingController(text: MaxKeyPersistent.instance.host);
 
+  bool isTesting = false;
+
   /// true: 连接成功;false:链接失败
   bool testResult = true;
   String? testDesc;
@@ -35,26 +37,41 @@ class _SetHostDialogState extends State<_SetHostDialog> {
         Row(
           mainAxisAlignment: MainAxisAlignment.spaceBetween,
           children: [
-            TextButton(
-              onPressed: () async {
-                final result = await MaxKey.instance
-                    .maxKeyNetworkTest(host: hostEditingController.text);
-                setState(() {
-                  testResult = result;
-                  testDesc = result
-                      ? AppLocalizations.of(context)!
-                          .settingsPageHostSettingDialogTestSucceed
-                      : AppLocalizations.of(context)!
-                          .settingsPageHostSettingDialogTestFail;
-                });
-              },
-              child: Text(AppLocalizations.of(context)!.settingsPageHostSettingDialogTestBtn),
+            TextButton.icon(
+              onPressed: isTesting
+                  ? null
+                  : () async {
+                      setState(() {
+                        isTesting = true;
+                      });
+                      final result = await MaxKey.instance
+                          .maxKeyNetworkTest(host: hostEditingController.text);
+                      setState(() {
+                        isTesting = false;
+                        testResult = result;
+                        testDesc = result
+                            ? AppLocalizations.of(context)!
+                                .settingsPageHostSettingDialogTestSucceed
+                            : AppLocalizations.of(context)!
+                                .settingsPageHostSettingDialogTestFail;
+                      });
+                    },
+              icon: isTesting
+                  ? const SizedBox(
+                      width: 18,
+                      height: 18,
+                      child: CircularProgressIndicator(strokeWidth: 2),
+                    )
+                  : null,
+              label: Text(AppLocalizations.of(context)!
+                  .settingsPageHostSettingDialogTestBtn),
             ),
             Row(
               children: [
                 TextButton(
                   onPressed: Navigator.of(context).pop,
-                  child: Text(AppLocalizations.of(context)!.settingsPageHostSettingDialogCancleBtn),
+                  child: Text(AppLocalizations.of(context)!
+                      .settingsPageHostSettingDialogCancleBtn),
                 ),
                 const SizedBox(width: 8.0),
                 TextButton(
@@ -66,7 +83,8 @@ class _SetHostDialogState extends State<_SetHostDialog> {
                       Navigator.of(context).pop();
                     }
                   },
-                  child: Text(AppLocalizations.of(context)!.settingsPageHostSettingDialogConfirmBtn),
+                  child: Text(AppLocalizations.of(context)!
+                      .settingsPageHostSettingDialogConfirmBtn),
                 ),
               ],
             )

+ 46 - 17
summer-ospp/2024/Flutter/maxkey_flutter/lib/pages/user_page/page.dart

@@ -34,7 +34,7 @@ class UserPage extends StatelessWidget {
                     _UserCard(user: user!),
                     _UserPageButtonTile(
                       title: AppLocalizations.of(context)!.userPageUserInfoBtn,
-                      trailing: Icons.info,
+                      trailing: const Icon(Icons.info),
                       onTap: () async {
                         final userInfo = await MaxKey.instance.usersService
                             .getFullUserInfo();
@@ -55,23 +55,13 @@ class UserPage extends StatelessWidget {
             const SizedBox(height: 8.0),
             _UserPageButtonTile(
               title: AppLocalizations.of(context)!.userPageSettingsBtn,
-              trailing: Icons.settings,
+              trailing: const Icon(Icons.settings),
               onTap: () {
                 context.push(RoutePath.settingsPage);
               },
             ),
             const SizedBox(height: 8.0),
-            _UserPageButtonTile(
-              title: AppLocalizations.of(context)!.userPageLogoutBtn,
-              trailing: Icons.logout,
-              onTap: () async {
-                await MaxKey.instance.authnService.logout();
-
-                if (context.mounted) {
-                  context.pushReplacement(RoutePath.loginPage);
-                }
-              },
-            )
+            const _LogoutBtn(),
           ]),
         ),
       ),
@@ -79,17 +69,56 @@ class UserPage extends StatelessWidget {
   }
 }
 
+class _LogoutBtn extends StatefulWidget {
+  const _LogoutBtn({super.key});
+
+  @override
+  State<_LogoutBtn> createState() => _LogoutBtnState();
+}
+
+class _LogoutBtnState extends State<_LogoutBtn> {
+  bool isLogouting = false;
+  @override
+  Widget build(BuildContext context) {
+    return _UserPageButtonTile(
+      title: AppLocalizations.of(context)!.userPageLogoutBtn,
+      trailing: isLogouting
+          ? const SizedBox(
+              width: 18,
+              height: 18,
+              child: CircularProgressIndicator(strokeWidth: 2),
+            )
+          : const Icon(Icons.logout),
+      onTap: isLogouting
+          ? null
+          : () async {
+              setState(() {
+                isLogouting = true;
+              });
+              await MaxKey.instance.authnService.logout();
+              setState(() {
+                isLogouting = false;
+              });
+              if (context.mounted) {
+                Navigator.of(context).pop();
+                context.pushReplacement(RoutePath.loginPage);
+              }
+            },
+    );
+  }
+}
+
 class _UserPageButtonTile extends StatelessWidget {
   const _UserPageButtonTile({
     super.key,
     required this.title,
     required this.trailing,
-    required this.onTap,
+    this.onTap,
   });
 
   final String title;
-  final IconData trailing;
-  final void Function() onTap;
+  final Widget trailing;
+  final void Function()? onTap;
 
   @override
   Widget build(BuildContext context) {
@@ -100,7 +129,7 @@ class _UserPageButtonTile extends StatelessWidget {
       ),
       tileColor: scheme.surfaceContainer,
       title: Text(title),
-      trailing: Icon(trailing),
+      trailing: trailing,
       onTap: onTap,
     );
   }