public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH proxmox_login_manager] fix: ui: remove `SafeArea` to avoid black background in status bar
@ 2025-05-15 13:34 Shan Shaji
  2025-05-16 11:53 ` Michael Köppl
  2025-05-21 12:30 ` [pve-devel] applied: " Dominik Csapak
  0 siblings, 2 replies; 3+ messages in thread
From: Shan Shaji @ 2025-05-15 13:34 UTC (permalink / raw)
  To: pve-devel

Since the `SafeArea` widget was wrapping the `Scaffold` widget, the
background color of the status bar was black rather than influenced by
the `AppBar` color.

This patch fixes it by removing the `SafeArea` widget. According to
flutter docs [0] when using `AppBar` with `Scaffold` the
appropriate spacing will be calculated at the top of the screen
without the needing to wrap the `Scaffold` in a `SafeArea` and the
status bar color will be influenced by the app bar color.

This patch also fixes the app name title alignment issue in iOS.

[0] - https://api.flutter.dev/flutter/material/AppBar-class.html?utm_source

Signed-off-by: Shan Shaji <s.shaji@proxmox.com>
---
 lib/proxmox_login_selector.dart | 264 ++++++++++++++++----------------
 1 file changed, 130 insertions(+), 134 deletions(-)

diff --git a/lib/proxmox_login_selector.dart b/lib/proxmox_login_selector.dart
index f063699..fb1218b 100644
--- a/lib/proxmox_login_selector.dart
+++ b/lib/proxmox_login_selector.dart
@@ -29,152 +29,87 @@ class _ProxmoxLoginSelectorState extends State<ProxmoxLoginSelector> {
 
   @override
   Widget build(BuildContext context) {
-    return SafeArea(
-      child: Scaffold(
-        backgroundColor: Theme.of(context).colorScheme.background,
-        appBar: AppBar(
-          title: const Column(
-            crossAxisAlignment: CrossAxisAlignment.start,
-            children: [
-              Text(
-                'Proxmox',
-                style: TextStyle(
-                  fontSize: 14,
-                ),
+    return Scaffold(
+      backgroundColor: Theme.of(context).colorScheme.background,
+      appBar: AppBar(
+        centerTitle: false,
+        title: const Column(
+          crossAxisAlignment: CrossAxisAlignment.start,
+          children: [
+            Text(
+              'Proxmox',
+              style: TextStyle(
+                fontSize: 14,
               ),
-              Text(
-                'Virtual Environment',
-                style: TextStyle(
-                  fontSize: 14,
-                ),
-              )
-            ],
-          ),
-          actions: [
-            IconButton(
-                icon: const Icon(Icons.settings),
-                onPressed: () {
-                  Navigator.of(context).push(MaterialPageRoute(
-                    builder: (context) => const ProxmoxGeneralSettingsForm(),
-                  ));
-                })
+            ),
+            Text(
+              'Virtual Environment',
+              style: TextStyle(
+                fontSize: 14,
+              ),
+            )
           ],
         ),
-        body: FutureBuilder<ProxmoxLoginStorage?>(
-            future: loginStorage,
-            builder: (context, snapshot) {
-              if (!snapshot.hasData) {
-                return const Center(
-                  child: CircularProgressIndicator(),
-                );
-              }
-              if (snapshot.hasData &&
-                  (snapshot.data!.logins?.isEmpty ?? true)) {
-                return const Center(
-                  child: Text('Add an account'),
-                );
-              }
-              var items = <Widget>[];
-              final BuiltList<ProxmoxLoginModel> logins =
-                  snapshot.data?.logins ?? BuiltList<ProxmoxLoginModel>();
+        actions: [
+          IconButton(
+              icon: const Icon(Icons.settings),
+              onPressed: () {
+                Navigator.of(context).push(MaterialPageRoute(
+                  builder: (context) => const ProxmoxGeneralSettingsForm(),
+                ));
+              })
+        ],
+      ),
+      body: FutureBuilder<ProxmoxLoginStorage?>(
+          future: loginStorage,
+          builder: (context, snapshot) {
+            if (!snapshot.hasData) {
+              return const Center(
+                child: CircularProgressIndicator(),
+              );
+            }
+            if (snapshot.hasData && (snapshot.data!.logins?.isEmpty ?? true)) {
+              return const Center(
+                child: Text('Add an account'),
+              );
+            }
+            var items = <Widget>[];
+            final BuiltList<ProxmoxLoginModel> logins =
+                snapshot.data?.logins ?? BuiltList<ProxmoxLoginModel>();
 
-              final activeSessions =
-                  logins.rebuild((b) => b.where((b) => b.activeSession));
+            final activeSessions =
+                logins.rebuild((b) => b.where((b) => b.activeSession));
 
-              if (activeSessions.isNotEmpty) {
-                items.addAll([
-                  const Padding(
-                    padding: EdgeInsets.all(12.0),
-                    child: Text(
-                      'Active Sessions',
-                      style: TextStyle(
-                        fontSize: 18,
-                        fontWeight: FontWeight.bold,
-                      ),
-                    ),
-                  ),
-                  ...activeSessions.map((s) => ListTile(
-                        title: Text(s.fullHostname),
-                        subtitle: Text(s.fullUsername),
-                        trailing: const Icon(Icons.navigate_next),
-                        leading: PopupMenuButton(
-                            icon: const Icon(Icons.more_vert,
-                                color: Colors.green),
-                            itemBuilder: (context) => [
-                                  PopupMenuItem(
-                                    child: ListTile(
-                                      dense: true,
-                                      leading: const Icon(Icons.logout),
-                                      title: const Text('Logout'),
-                                      onTap: () async {
-                                        await snapshot.data!
-                                            .rebuild((b) => b.logins
-                                                .rebuildWhere((m) => s == m,
-                                                    (b) => b..ticket = ''))
-                                            .saveToDisk();
-                                        refreshFromStorage();
-                                        if (context.mounted) {
-                                          Navigator.of(context).pop();
-                                        }
-                                      },
-                                    ),
-                                  ),
-                                ]),
-                        onTap: () => _login(user: s),
-                      )),
-                ]);
-              }
+            if (activeSessions.isNotEmpty) {
               items.addAll([
                 const Padding(
                   padding: EdgeInsets.all(12.0),
                   child: Text(
-                    'Available Sites',
+                    'Active Sessions',
                     style: TextStyle(
                       fontSize: 18,
                       fontWeight: FontWeight.bold,
                     ),
                   ),
                 ),
-                ...logins.where((b) => !b.activeSession).map((login) =>
-                    ListTile(
-                      title: Text(login.fullHostname),
-                      subtitle: Text(login.fullUsername),
+                ...activeSessions.map((s) => ListTile(
+                      title: Text(s.fullHostname),
+                      subtitle: Text(s.fullUsername),
                       trailing: const Icon(Icons.navigate_next),
                       leading: PopupMenuButton(
+                          icon:
+                              const Icon(Icons.more_vert, color: Colors.green),
                           itemBuilder: (context) => [
-                                if (login.passwordSaved ?? false)
-                                  PopupMenuItem(
-                                    child: ListTile(
-                                      dense: true,
-                                      leading: const Icon(Icons.key_off),
-                                      title: const Text('Delete Password'),
-                                      onTap: () async {
-                                        await deletePassword(login.identifier!);
-
-                                        await snapshot.data!
-                                            .rebuild((b) => b
-                                              ..logins.rebuildWhere(
-                                                  (m) => m == login,
-                                                  (b) =>
-                                                      b..passwordSaved = false))
-                                            .saveToDisk();
-                                        refreshFromStorage();
-                                        if (context.mounted) {
-                                          Navigator.of(context).pop();
-                                        }
-                                      },
-                                    ),
-                                  ),
                                 PopupMenuItem(
                                   child: ListTile(
                                     dense: true,
-                                    leading: const Icon(Icons.delete),
-                                    title: const Text('Delete'),
+                                    leading: const Icon(Icons.logout),
+                                    title: const Text('Logout'),
                                     onTap: () async {
-                                      await deletePassword(login.identifier!);
                                       await snapshot.data!
-                                          .rebuild(
-                                              (b) => b.logins.remove(login))
+                                          .rebuild((b) => b.logins.rebuildWhere(
+                                              (m) => s == m,
+                                              (b) => b..ticket = ''))
                                           .saveToDisk();
                                       refreshFromStorage();
                                       if (context.mounted) {
@@ -184,18 +119,79 @@ class _ProxmoxLoginSelectorState extends State<ProxmoxLoginSelector> {
                                   ),
                                 ),
                               ]),
-                      onTap: () => _login(user: login),
-                    ))
+                      onTap: () => _login(user: s),
+                    )),
               ]);
-              return ListView(
-                children: items,
-              );
-            }),
-        floatingActionButton: FloatingActionButton.extended(
-          onPressed: () => _login(isCreate: true),
-          label: const Text('Add'),
-          icon: const Icon(Icons.account_circle),
-        ),
+            }
+            items.addAll([
+              const Padding(
+                padding: EdgeInsets.all(12.0),
+                child: Text(
+                  'Available Sites',
+                  style: TextStyle(
+                    fontSize: 18,
+                    fontWeight: FontWeight.bold,
+                  ),
+                ),
+              ),
+              ...logins.where((b) => !b.activeSession).map((login) => ListTile(
+                    title: Text(login.fullHostname),
+                    subtitle: Text(login.fullUsername),
+                    trailing: const Icon(Icons.navigate_next),
+                    leading: PopupMenuButton(
+                        itemBuilder: (context) => [
+                              if (login.passwordSaved ?? false)
+                                PopupMenuItem(
+                                  child: ListTile(
+                                    dense: true,
+                                    leading: const Icon(Icons.key_off),
+                                    title: const Text('Delete Password'),
+                                    onTap: () async {
+                                      await deletePassword(login.identifier!);
+
+                                      await snapshot.data!
+                                          .rebuild((b) => b
+                                            ..logins.rebuildWhere(
+                                                (m) => m == login,
+                                                (b) =>
+                                                    b..passwordSaved = false))
+                                          .saveToDisk();
+                                      refreshFromStorage();
+                                      if (context.mounted) {
+                                        Navigator.of(context).pop();
+                                      }
+                                    },
+                                  ),
+                                ),
+                              PopupMenuItem(
+                                child: ListTile(
+                                  dense: true,
+                                  leading: const Icon(Icons.delete),
+                                  title: const Text('Delete'),
+                                  onTap: () async {
+                                    await deletePassword(login.identifier!);
+                                    await snapshot.data!
+                                        .rebuild((b) => b.logins.remove(login))
+                                        .saveToDisk();
+                                    refreshFromStorage();
+                                    if (context.mounted) {
+                                      Navigator.of(context).pop();
+                                    }
+                                  },
+                                ),
+                              ),
+                            ]),
+                    onTap: () => _login(user: login),
+                  ))
+            ]);
+            return ListView(
+              children: items,
+            );
+          }),
+      floatingActionButton: FloatingActionButton.extended(
+        onPressed: () => _login(isCreate: true),
+        label: const Text('Add'),
+        icon: const Icon(Icons.account_circle),
       ),
     );
   }
-- 
2.39.5 (Apple Git-154)



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [pve-devel] [PATCH proxmox_login_manager] fix: ui: remove `SafeArea` to avoid black background in status bar
  2025-05-15 13:34 [pve-devel] [PATCH proxmox_login_manager] fix: ui: remove `SafeArea` to avoid black background in status bar Shan Shaji
@ 2025-05-16 11:53 ` Michael Köppl
  2025-05-21 12:30 ` [pve-devel] applied: " Dominik Csapak
  1 sibling, 0 replies; 3+ messages in thread
From: Michael Köppl @ 2025-05-16 11:53 UTC (permalink / raw)
  To: Proxmox VE development discussion, Shan Shaji

On 5/15/25 15:34, Shan Shaji wrote:
> Since the `SafeArea` widget was wrapping the `Scaffold` widget, the
> background color of the status bar was black rather than influenced by
> the `AppBar` color.
> 
> This patch fixes it by removing the `SafeArea` widget. According to
> flutter docs [0] when using `AppBar` with `Scaffold` the
> appropriate spacing will be calculated at the top of the screen
> without the needing to wrap the `Scaffold` in a `SafeArea` and the
> status bar color will be influenced by the app bar color.
> 
> This patch also fixes the app name title alignment issue in iOS.
> 
> [0] - https://api.flutter.dev/flutter/material/AppBar-class.html?utm_source
> 
> Signed-off-by: Shan Shaji <s.shaji@proxmox.com>

Quickly tested this in my Android emulator to verify that all
functionality on the login selector screen still worked as expected and
there are no visual glitches from the removal of the SafeArea. Lgtm in
portrait and landscape, did not notice any problems when navigating to
other screens.

Since I do not have an iOS device or a Mac available, I was unable to
check the title alignment issue on iOS.

Tested-by: Michael Köppl <m.koeppl@proxmox.com>


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [pve-devel] applied: [PATCH proxmox_login_manager] fix: ui: remove `SafeArea` to avoid black background in status bar
  2025-05-15 13:34 [pve-devel] [PATCH proxmox_login_manager] fix: ui: remove `SafeArea` to avoid black background in status bar Shan Shaji
  2025-05-16 11:53 ` Michael Köppl
@ 2025-05-21 12:30 ` Dominik Csapak
  1 sibling, 0 replies; 3+ messages in thread
From: Dominik Csapak @ 2025-05-21 12:30 UTC (permalink / raw)
  To: pve-devel

On 5/15/25 15:34, Shan Shaji wrote:
> Since the `SafeArea` widget was wrapping the `Scaffold` widget, the
> background color of the status bar was black rather than influenced by
> the `AppBar` color.
> 
> This patch fixes it by removing the `SafeArea` widget. According to
> flutter docs [0] when using `AppBar` with `Scaffold` the
> appropriate spacing will be calculated at the top of the screen
> without the needing to wrap the `Scaffold` in a `SafeArea` and the
> status bar color will be influenced by the app bar color.
> 
> This patch also fixes the app name title alignment issue in iOS.
> 
> [0] - https://api.flutter.dev/flutter/material/AppBar-class.html?utm_source
> 
> Signed-off-by: Shan Shaji <s.shaji@proxmox.com>
> ---
>   lib/proxmox_login_selector.dart | 264 ++++++++++++++++----------------
>   1 file changed, 130 insertions(+), 134 deletions(-)
> 
>

applied with Michael's Tested-by, thanks!


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2025-05-21 12:30 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-05-15 13:34 [pve-devel] [PATCH proxmox_login_manager] fix: ui: remove `SafeArea` to avoid black background in status bar Shan Shaji
2025-05-16 11:53 ` Michael Köppl
2025-05-21 12:30 ` [pve-devel] applied: " Dominik Csapak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal