all lists on lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH pve_flutter_frontend] fix: ui: app bar text alignment issues in iOS
@ 2025-05-15 12:19 Shan Shaji
  0 siblings, 0 replies; only message in thread
From: Shan Shaji @ 2025-05-15 12:19 UTC (permalink / raw)
  To: pve-devel

By default iOS centers the title in the appbar, which can create a
visual inconsistency with the left aligned two line app name.

Added a custom `PveAppBar` widget to maintain the design and alignment
similliar to android. Also the new widget replaces all other `AppBar`
widgets that has the title property specified.

Signed-off-by: Shan Shaji <s.shaji@proxmox.com>
---
 lib/pages/main_layout_slim.dart           |  9 ++---
 lib/widgets/pve_app_bar.dart              | 47 +++++++++++++++++++++++
 lib/widgets/pve_file_selector_widget.dart |  4 +-
 lib/widgets/pve_guest_backup_widget.dart  |  7 ++--
 lib/widgets/pve_guest_migrate_widget.dart |  4 +-
 lib/widgets/pve_lxc_overview.dart         |  4 +-
 lib/widgets/pve_node_overview.dart        |  5 +--
 lib/widgets/pve_qemu_overview.dart        |  5 +--
 8 files changed, 64 insertions(+), 21 deletions(-)
 create mode 100644 lib/widgets/pve_app_bar.dart

diff --git a/lib/pages/main_layout_slim.dart b/lib/pages/main_layout_slim.dart
index ac5a6f9..5e1bfa5 100644
--- a/lib/pages/main_layout_slim.dart
+++ b/lib/pages/main_layout_slim.dart
@@ -23,6 +23,7 @@ import 'package:pve_flutter_frontend/widgets/proxmox_custom_icon.dart';
 import 'package:pve_flutter_frontend/widgets/proxmox_gauge_chart.dart';
 import 'package:pve_flutter_frontend/widgets/proxmox_heartbeat_indicator.dart';
 import 'package:pve_flutter_frontend/widgets/proxmox_stream_builder_widget.dart';
+import 'package:pve_flutter_frontend/widgets/pve_app_bar.dart';
 import 'package:pve_flutter_frontend/widgets/pve_file_selector_widget.dart';
 import 'package:pve_flutter_frontend/widgets/pve_guest_icon_widget.dart';
 import 'package:pve_flutter_frontend/widgets/pve_help_icon_button_widget.dart';
@@ -167,7 +168,7 @@ class MobileDashboard extends StatelessWidget {
     final cBloc = Provider.of<PveClusterStatusBloc>(context);
     final rBloc = Provider.of<PveResourceBloc>(context);
     return Scaffold(
-      appBar: AppBar(
+      appBar: PveAppBar(
         title: const Column(
           crossAxisAlignment: CrossAxisAlignment.start,
           children: [
@@ -185,7 +186,6 @@ class MobileDashboard extends StatelessWidget {
             )
           ],
         ),
-        elevation: 0.0,
         leading: const Icon(
           ProxmoxIcons.proxmox,
           size: 36,
@@ -607,9 +607,8 @@ class MobileResourceOverview extends StatelessWidget {
           child: ColoredSafeArea(
               child: Scaffold(
             endDrawer: _MobileResourceFilterSheet(),
-            appBar: AppBar(
+            appBar: PveAppBar(
               automaticallyImplyLeading: false,
-              elevation: 0,
               title: AppbarSearchTextField(
                 onChanged: (filter) =>
                     rBloc.events.add(FilterResources(nameFilter: filter)),
@@ -1051,7 +1050,7 @@ class MobileAccessManagement extends StatelessWidget {
     return DefaultTabController(
       length: 5,
       child: Scaffold(
-        appBar: AppBar(
+        appBar: PveAppBar(
           title: const Text('Permissions'),
           //backgroundColor: Colors.transparent,
           elevation: 0.0,
diff --git a/lib/widgets/pve_app_bar.dart b/lib/widgets/pve_app_bar.dart
new file mode 100644
index 0000000..de24b96
--- /dev/null
+++ b/lib/widgets/pve_app_bar.dart
@@ -0,0 +1,47 @@
+import 'package:flutter/material.dart';
+
+class PveAppBar extends StatelessWidget implements PreferredSizeWidget {
+  PveAppBar({
+    super.key,
+    this.title,
+    this.automaticallyImplyLeading = true,
+    this.elevation,
+    this.leading,
+    this.actions,
+    this.centerTitle,
+    this.bottom,
+    this.toolbarHeight,
+    this.backgroundColor,
+    this.iconTheme,
+  }) : preferredSize = Size.fromHeight((toolbarHeight ?? kToolbarHeight) +
+            (bottom?.preferredSize.height ?? 0));
+
+  final Widget? title;
+  final double? elevation;
+  final Widget? leading;
+  final bool automaticallyImplyLeading;
+  final List<Widget>? actions;
+  final bool? centerTitle;
+  final PreferredSizeWidget? bottom;
+  final double? toolbarHeight;
+  final Color? backgroundColor;
+  final IconThemeData? iconTheme;
+
+  @override
+  final Size preferredSize;
+
+  @override
+  Widget build(BuildContext context) {
+    return AppBar(
+      centerTitle: centerTitle ?? false,
+      title: title,
+      elevation: elevation ?? 0,
+      leading: leading,
+      automaticallyImplyLeading: automaticallyImplyLeading,
+      actions: actions,
+      bottom: bottom,
+      backgroundColor: backgroundColor,
+      iconTheme: iconTheme,
+    );
+  }
+}
diff --git a/lib/widgets/pve_file_selector_widget.dart b/lib/widgets/pve_file_selector_widget.dart
index 9770ff8..f03a021 100644
--- a/lib/widgets/pve_file_selector_widget.dart
+++ b/lib/widgets/pve_file_selector_widget.dart
@@ -11,6 +11,7 @@ import 'package:pve_flutter_frontend/utils/renderers.dart';
 import 'package:pve_flutter_frontend/widgets/proxmox_capacity_indicator.dart';
 import 'package:pve_flutter_frontend/widgets/proxmox_stream_builder_widget.dart';
 import 'package:pve_flutter_frontend/widgets/proxmox_stream_listener.dart';
+import 'package:pve_flutter_frontend/widgets/pve_app_bar.dart';
 
 class PveFileSelector extends StatefulWidget {
   final PveFileSelectorBloc? fBloc;
@@ -32,8 +33,7 @@ class _PveFileSelectorState extends State<PveFileSelector> {
   Widget build(BuildContext context) {
     return ProxmoxLayoutBuilder(
       builder: (context, layout) => Scaffold(
-        appBar: AppBar(
-          elevation: 0,
+        appBar: PveAppBar(
           title: const Text("Storage"),
         ),
         body: PveFileSelectorWidget(
diff --git a/lib/widgets/pve_guest_backup_widget.dart b/lib/widgets/pve_guest_backup_widget.dart
index 8aa7e31..7bd38d4 100644
--- a/lib/widgets/pve_guest_backup_widget.dart
+++ b/lib/widgets/pve_guest_backup_widget.dart
@@ -12,6 +12,7 @@ import 'package:pve_flutter_frontend/utils/utils.dart';
 import 'package:pve_flutter_frontend/utils/validators.dart';
 import 'package:pve_flutter_frontend/widgets/proxmox_stream_builder_widget.dart';
 import 'package:pve_flutter_frontend/widgets/proxmox_stream_listener.dart';
+import 'package:pve_flutter_frontend/widgets/pve_app_bar.dart';
 import 'package:pve_flutter_frontend/widgets/pve_file_selector_widget.dart';
 import 'package:pve_flutter_frontend/widgets/pve_storage_selector_widget.dart';
 
@@ -25,8 +26,7 @@ class PveGuestBackupWidget extends StatelessWidget {
     final sBloc = Provider.of<PveStorageSelectorBloc>(context);
     final fBloc = Provider.of<PveFileSelectorBloc>(context);
     return Scaffold(
-      appBar: AppBar(
-        elevation: 0,
+      appBar: PveAppBar(
         title: Text("Backup $guestID"),
       ),
       body: Column(
@@ -417,10 +417,9 @@ class _PveBackupFormState extends State<PveBackupForm> {
     return ScaffoldMessenger(
         key: _scaffoldKey,
         child: Scaffold(
-          appBar: AppBar(
+          appBar: PveAppBar(
             iconTheme: const IconThemeData(color: Colors.black),
             backgroundColor: Colors.transparent,
-            elevation: 0,
             title: const Text(
               "Schedule backup",
               style: TextStyle(color: Colors.black),
diff --git a/lib/widgets/pve_guest_migrate_widget.dart b/lib/widgets/pve_guest_migrate_widget.dart
index d467dd7..5ef72eb 100644
--- a/lib/widgets/pve_guest_migrate_widget.dart
+++ b/lib/widgets/pve_guest_migrate_widget.dart
@@ -8,6 +8,7 @@ import 'package:pve_flutter_frontend/bloc/pve_resource_bloc.dart';
 import 'package:pve_flutter_frontend/states/pve_migrate_state.dart';
 import 'package:pve_flutter_frontend/states/pve_node_selector_state.dart';
 import 'package:pve_flutter_frontend/widgets/proxmox_stream_builder_widget.dart';
+import 'package:pve_flutter_frontend/widgets/pve_app_bar.dart';
 import 'package:pve_flutter_frontend/widgets/pve_guest_migration_connector_widget.dart';
 import 'package:pve_flutter_frontend/widgets/pve_help_icon_button_widget.dart';
 
@@ -23,7 +24,7 @@ class PveGuestMigrate extends StatelessWidget {
       bloc: migrateBloc,
       builder: (context, migrateState) {
         return Scaffold(
-          appBar: AppBar(
+          appBar: PveAppBar(
             title: const Text(
               "Migration",
               style: TextStyle(color: Colors.white, fontSize: 25),
@@ -34,7 +35,6 @@ class PveGuestMigrate extends StatelessWidget {
               icon: const Icon(Icons.close),
               onPressed: () => Navigator.of(context).pop(),
             ),
-            elevation: 0.0,
             actions: <Widget>[
               PveHelpIconButton(
                   baseUrl: (Provider.of<PveResourceBloc>(context)
diff --git a/lib/widgets/pve_lxc_overview.dart b/lib/widgets/pve_lxc_overview.dart
index e8e6edb..2af58df 100644
--- a/lib/widgets/pve_lxc_overview.dart
+++ b/lib/widgets/pve_lxc_overview.dart
@@ -23,6 +23,7 @@ import 'package:pve_flutter_frontend/widgets/colored_safe_area.dart';
 import 'package:pve_flutter_frontend/widgets/proxmox_stream_builder_widget.dart';
 import 'package:pve_flutter_frontend/widgets/proxmox_stream_listener.dart';
 import 'package:pve_flutter_frontend/widgets/pve_action_card_widget.dart';
+import 'package:pve_flutter_frontend/widgets/pve_app_bar.dart';
 import 'package:pve_flutter_frontend/widgets/pve_guest_backup_widget.dart';
 import 'package:pve_flutter_frontend/widgets/pve_guest_migrate_widget.dart';
 import 'package:pve_flutter_frontend/widgets/pve_guest_overview_header.dart';
@@ -72,8 +73,7 @@ class PveLxcOverview extends StatelessWidget {
             final config = state.config;
             return ColoredSafeArea(
               child: Scaffold(
-                appBar: AppBar(
-                  elevation: 0,
+                appBar: PveAppBar(
                   title: Text(config?.hostname ?? 'CT $guestID'),
                 ),
                 backgroundColor: Theme.of(context).colorScheme.surfaceContainer,
diff --git a/lib/widgets/pve_node_overview.dart b/lib/widgets/pve_node_overview.dart
index 85410fb..98767fe 100644
--- a/lib/widgets/pve_node_overview.dart
+++ b/lib/widgets/pve_node_overview.dart
@@ -9,6 +9,7 @@ import 'package:pve_flutter_frontend/states/pve_task_log_state.dart';
 import 'package:pve_flutter_frontend/utils/renderers.dart';
 import 'package:pve_flutter_frontend/utils/utils.dart';
 import 'package:pve_flutter_frontend/widgets/colored_safe_area.dart';
+import 'package:pve_flutter_frontend/widgets/pve_app_bar.dart';
 import 'package:pve_flutter_frontend/widgets/pve_node_power_settings_widget.dart';
 import 'package:pve_flutter_frontend/widgets/proxmox_capacity_indicator.dart';
 import 'package:pve_flutter_frontend/widgets/proxmox_stream_builder_widget.dart';
@@ -52,9 +53,7 @@ class PveNodeOverview extends StatelessWidget {
             Theme.of(context).colorScheme.onPrimary.withValues(alpha: 0.75);
         return ColoredSafeArea(
           child: Scaffold(
-            appBar: AppBar(
-              //backgroundColor: Colors.transparent,
-              elevation: 0,
+            appBar: PveAppBar(
               title: Text(
                 "Node $nodeID",
                 style:
diff --git a/lib/widgets/pve_qemu_overview.dart b/lib/widgets/pve_qemu_overview.dart
index b019b0f..20bb648 100644
--- a/lib/widgets/pve_qemu_overview.dart
+++ b/lib/widgets/pve_qemu_overview.dart
@@ -23,6 +23,7 @@ import 'package:pve_flutter_frontend/widgets/colored_safe_area.dart';
 import 'package:pve_flutter_frontend/widgets/proxmox_stream_builder_widget.dart';
 import 'package:pve_flutter_frontend/widgets/proxmox_stream_listener.dart';
 import 'package:pve_flutter_frontend/widgets/pve_action_card_widget.dart';
+import 'package:pve_flutter_frontend/widgets/pve_app_bar.dart';
 import 'package:pve_flutter_frontend/widgets/pve_guest_backup_widget.dart';
 import 'package:pve_flutter_frontend/widgets/pve_guest_overview_header.dart';
 import 'package:pve_flutter_frontend/widgets/pve_guest_migrate_widget.dart';
@@ -73,9 +74,7 @@ class PveQemuOverview extends StatelessWidget {
 
             return ColoredSafeArea(
               child: Scaffold(
-                  appBar: AppBar(
-                    //backgroundColor: Colors.transparent,
-                    elevation: 0,
+                  appBar: PveAppBar(
                     title: Text(config?.name ?? 'VM $guestID'),
                   ),
                   backgroundColor:
-- 
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] only message in thread

only message in thread, other threads:[~2025-05-15 12:19 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-05-15 12:19 [pve-devel] [PATCH pve_flutter_frontend] fix: ui: app bar text alignment issues in iOS Shan Shaji

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal