From 0d35231dfd071e53db3ce4df33113cd0463328a9 Mon Sep 17 00:00:00 2001 From: Thomas <9749173+uhthomas@users.noreply.github.com> Date: Thu, 12 Feb 2026 15:39:55 +0000 Subject: [PATCH] chore(mobile): cleanup server storage info (#26038) The server storage info has a lot of whitespace due to the ListTile. Converting it to be inline makes the styling appear more intentional. There are also a few semantically relevant list items in the app bar dialog which have been grouped together. --- .../common/app_bar_dialog/app_bar_dialog.dart | 67 ++-- .../app_bar_dialog/app_bar_profile_info.dart | 72 ++-- .../app_bar_dialog/app_bar_server_info.dart | 341 +++++++++--------- 3 files changed, 229 insertions(+), 251 deletions(-) diff --git a/mobile/lib/widgets/common/app_bar_dialog/app_bar_dialog.dart b/mobile/lib/widgets/common/app_bar_dialog/app_bar_dialog.dart index 58c73a77b8..527aae0e6e 100644 --- a/mobile/lib/widgets/common/app_bar_dialog/app_bar_dialog.dart +++ b/mobile/lib/widgets/common/app_bar_dialog/app_bar_dialog.dart @@ -153,42 +153,26 @@ class ImmichAppBarDialog extends HookConsumerWidget { percentage = user.quotaUsageInBytes / user.quotaSizeInBytes; } - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 3), - child: Container( - padding: const EdgeInsets.symmetric(vertical: 4), - decoration: BoxDecoration(color: context.colorScheme.surface), - child: ListTile( - minLeadingWidth: 50, - leading: Icon(Icons.storage_rounded, color: theme.primaryColor), - title: Text( + return Container( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 12, + children: [ + Text( "backup_controller_page_server_storage", style: context.textTheme.labelLarge?.copyWith(fontWeight: FontWeight.w500), ).tr(), - isThreeLine: true, - subtitle: Padding( - padding: const EdgeInsets.only(top: 8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(top: 8.0), - child: LinearProgressIndicator( - minHeight: 10.0, - value: percentage, - borderRadius: const BorderRadius.all(Radius.circular(10.0)), - ), - ), - Padding( - padding: const EdgeInsets.only(top: 12.0), - child: const Text( - 'backup_controller_page_storage_format', - ).tr(namedArgs: {'used': usedDiskSpace, 'total': totalDiskSpace}), - ), - ], - ), + LinearProgressIndicator( + minHeight: 10.0, + value: percentage, + borderRadius: const BorderRadius.all(Radius.circular(10.0)), ), - ), + Text( + 'backup_controller_page_storage_format', + style: context.textTheme.bodySmall, + ).tr(namedArgs: {'used': usedDiskSpace, 'total': totalDiskSpace}), + ], ), ); } @@ -275,9 +259,22 @@ class ImmichAppBarDialog extends HookConsumerWidget { mainAxisSize: MainAxisSize.min, children: [ Container(padding: const EdgeInsets.symmetric(horizontal: 8), child: buildTopRow()), - const AppBarProfileInfoBox(), - buildStorageInformation(), - const AppBarServerInfo(), + Container( + decoration: BoxDecoration( + color: context.colorScheme.surface, + borderRadius: const BorderRadius.all(Radius.circular(10)), + ), + margin: const EdgeInsets.only(left: 8, right: 8, bottom: 8), + child: Column( + children: [ + const AppBarProfileInfoBox(), + const Divider(height: 3), + buildStorageInformation(), + const Divider(height: 3), + const AppBarServerInfo(), + ], + ), + ), if (Store.isBetaTimelineEnabled && isReadonlyModeEnabled) buildReadonlyMessage(), buildAppLogButton(), buildFreeUpSpaceButton(), diff --git a/mobile/lib/widgets/common/app_bar_dialog/app_bar_profile_info.dart b/mobile/lib/widgets/common/app_bar_dialog/app_bar_profile_info.dart index bc1d608b10..b0c005424f 100644 --- a/mobile/lib/widgets/common/app_bar_dialog/app_bar_profile_info.dart +++ b/mobile/lib/widgets/common/app_bar_dialog/app_bar_profile_info.dart @@ -80,50 +80,40 @@ class AppBarProfileInfoBox extends HookConsumerWidget { ); } - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 10.0), - child: Container( - width: double.infinity, - decoration: BoxDecoration( - color: context.colorScheme.surface, - borderRadius: const BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10)), - ), - child: ListTile( - minLeadingWidth: 50, - leading: GestureDetector( - onTap: pickUserProfileImage, - onLongPress: toggleReadonlyMode, - child: Stack( - clipBehavior: Clip.none, - children: [ - AbsorbPointer(child: buildUserProfileImage()), - if (!isReadonlyModeEnabled) - Positioned( - bottom: -5, - right: -8, - child: Material( - color: context.colorScheme.surfaceContainerHighest, - elevation: 3, - shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(50.0))), - child: Padding( - padding: const EdgeInsets.all(5.0), - child: Icon(Icons.camera_alt_outlined, color: context.primaryColor, size: 14), - ), - ), + return ListTile( + minLeadingWidth: 50, + leading: GestureDetector( + onTap: pickUserProfileImage, + onLongPress: toggleReadonlyMode, + child: Stack( + clipBehavior: Clip.none, + children: [ + AbsorbPointer(child: buildUserProfileImage()), + if (!isReadonlyModeEnabled) + Positioned( + bottom: -5, + right: -8, + child: Material( + color: context.colorScheme.surfaceContainerHighest, + elevation: 3, + shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(50.0))), + child: Padding( + padding: const EdgeInsets.all(5.0), + child: Icon(Icons.camera_alt_outlined, color: context.primaryColor, size: 14), ), - ], - ), - ), - title: Text( - authState.name, - style: context.textTheme.titleMedium?.copyWith(color: context.primaryColor, fontWeight: FontWeight.w500), - ), - subtitle: Text( - authState.userEmail, - style: context.textTheme.bodySmall?.copyWith(color: context.colorScheme.onSurfaceSecondary), - ), + ), + ), + ], ), ), + title: Text( + authState.name, + style: context.textTheme.titleMedium?.copyWith(color: context.primaryColor, fontWeight: FontWeight.w500), + ), + subtitle: Text( + authState.userEmail, + style: context.textTheme.bodySmall?.copyWith(color: context.colorScheme.onSurfaceSecondary), + ), ); } } diff --git a/mobile/lib/widgets/common/app_bar_dialog/app_bar_server_info.dart b/mobile/lib/widgets/common/app_bar_dialog/app_bar_server_info.dart index a341d6395c..789884cdd2 100644 --- a/mobile/lib/widgets/common/app_bar_dialog/app_bar_server_info.dart +++ b/mobile/lib/widgets/common/app_bar_dialog/app_bar_server_info.dart @@ -38,187 +38,178 @@ class AppBarServerInfo extends HookConsumerWidget { }, []); return Padding( - padding: const EdgeInsets.only(left: 10.0, right: 10.0, bottom: 10.0), - child: Container( - decoration: BoxDecoration( - color: context.colorScheme.surface, - borderRadius: const BorderRadius.only(bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)), - ), - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 8), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, + padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + if (showVersionWarning) ...[ + const Padding(padding: EdgeInsets.symmetric(horizontal: 8.0), child: ServerUpdateNotification()), + const Padding(padding: EdgeInsets.symmetric(horizontal: 10), child: Divider(thickness: 1)), + ], + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - if (showVersionWarning) ...[ - const Padding(padding: EdgeInsets.symmetric(horizontal: 8.0), child: ServerUpdateNotification()), - const Padding(padding: EdgeInsets.symmetric(horizontal: 10), child: Divider(thickness: 1)), - ], - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.only(left: 10.0), - child: Text( - "server_info_box_app_version".tr(), - style: TextStyle( - fontSize: titleFontSize, - color: context.textTheme.labelSmall?.color, - fontWeight: FontWeight.w500, - ), - ), + Expanded( + child: Padding( + padding: const EdgeInsets.only(left: 10.0), + child: Text( + "server_info_box_app_version".tr(), + style: TextStyle( + fontSize: titleFontSize, + color: context.textTheme.labelSmall?.color, + fontWeight: FontWeight.w500, ), ), - Expanded( - flex: 0, - child: Padding( - padding: const EdgeInsets.only(right: 10.0), - child: Text( - "${appInfo.value["version"]} build.${appInfo.value["buildNumber"]}", - style: TextStyle( - fontSize: contentFontSize, - color: context.colorScheme.onSurfaceSecondary, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - ], - ), - const Padding(padding: EdgeInsets.symmetric(horizontal: 10), child: Divider(thickness: 1)), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.only(left: 10.0), - child: Text( - "server_version".tr(), - style: TextStyle( - fontSize: titleFontSize, - color: context.textTheme.labelSmall?.color, - fontWeight: FontWeight.w500, - ), - ), - ), - ), - Expanded( - flex: 0, - child: Padding( - padding: const EdgeInsets.only(right: 10.0), - child: Text( - serverInfoState.serverVersion.major > 0 - ? "${serverInfoState.serverVersion.major}.${serverInfoState.serverVersion.minor}.${serverInfoState.serverVersion.patch}" - : "--", - style: TextStyle( - fontSize: contentFontSize, - color: context.colorScheme.onSurfaceSecondary, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - ], - ), - const Padding(padding: EdgeInsets.symmetric(horizontal: 10), child: Divider(thickness: 1)), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.only(left: 10.0), - child: Text( - "server_info_box_server_url".tr(), - style: TextStyle( - fontSize: titleFontSize, - color: context.textTheme.labelSmall?.color, - fontWeight: FontWeight.w500, - ), - ), - ), - ), - Expanded( - flex: 0, - child: Container( - width: 200, - padding: const EdgeInsets.only(right: 10.0), - child: Tooltip( - verticalOffset: 0, - decoration: BoxDecoration( - color: context.primaryColor.withValues(alpha: 0.9), - borderRadius: const BorderRadius.all(Radius.circular(10)), - ), - textStyle: TextStyle( - color: context.isDarkTheme ? Colors.black : Colors.white, - fontWeight: FontWeight.bold, - ), - message: getServerUrl() ?? '--', - preferBelow: false, - triggerMode: TooltipTriggerMode.tap, - child: Text( - getServerUrl() ?? '--', - style: TextStyle( - fontSize: contentFontSize, - color: context.colorScheme.onSurfaceSecondary, - fontWeight: FontWeight.bold, - overflow: TextOverflow.ellipsis, - ), - textAlign: TextAlign.end, - ), - ), - ), - ), - ], - ), - if (serverInfoState.latestVersion != null) ...[ - const Padding(padding: EdgeInsets.symmetric(horizontal: 10), child: Divider(thickness: 1)), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.only(left: 10.0), - child: Row( - children: [ - if (serverInfoState.versionStatus == VersionStatus.serverOutOfDate) - const Padding( - padding: EdgeInsets.only(right: 5.0), - child: Icon(Icons.info, color: Color.fromARGB(255, 243, 188, 106), size: 12), - ), - Text( - "latest_version".tr(), - style: TextStyle( - fontSize: titleFontSize, - color: context.textTheme.labelSmall?.color, - fontWeight: FontWeight.w500, - ), - ), - ], - ), - ), - ), - Expanded( - flex: 0, - child: Padding( - padding: const EdgeInsets.only(right: 10.0), - child: Text( - serverInfoState.latestVersion!.major > 0 - ? "${serverInfoState.latestVersion!.major}.${serverInfoState.latestVersion!.minor}.${serverInfoState.latestVersion!.patch}" - : "--", - style: TextStyle( - fontSize: contentFontSize, - color: context.colorScheme.onSurfaceSecondary, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - ], ), - ], + ), + Expanded( + flex: 0, + child: Padding( + padding: const EdgeInsets.only(right: 10.0), + child: Text( + "${appInfo.value["version"]} build.${appInfo.value["buildNumber"]}", + style: TextStyle( + fontSize: contentFontSize, + color: context.colorScheme.onSurfaceSecondary, + fontWeight: FontWeight.bold, + ), + ), + ), + ), ], ), - ), + const Padding(padding: EdgeInsets.symmetric(horizontal: 10), child: Divider(thickness: 1)), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.only(left: 10.0), + child: Text( + "server_version".tr(), + style: TextStyle( + fontSize: titleFontSize, + color: context.textTheme.labelSmall?.color, + fontWeight: FontWeight.w500, + ), + ), + ), + ), + Expanded( + flex: 0, + child: Padding( + padding: const EdgeInsets.only(right: 10.0), + child: Text( + serverInfoState.serverVersion.major > 0 + ? "${serverInfoState.serverVersion.major}.${serverInfoState.serverVersion.minor}.${serverInfoState.serverVersion.patch}" + : "--", + style: TextStyle( + fontSize: contentFontSize, + color: context.colorScheme.onSurfaceSecondary, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], + ), + const Padding(padding: EdgeInsets.symmetric(horizontal: 10), child: Divider(thickness: 1)), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.only(left: 10.0), + child: Text( + "server_info_box_server_url".tr(), + style: TextStyle( + fontSize: titleFontSize, + color: context.textTheme.labelSmall?.color, + fontWeight: FontWeight.w500, + ), + ), + ), + ), + Expanded( + flex: 0, + child: Container( + width: 200, + padding: const EdgeInsets.only(right: 10.0), + child: Tooltip( + verticalOffset: 0, + decoration: BoxDecoration( + color: context.primaryColor.withValues(alpha: 0.9), + borderRadius: const BorderRadius.all(Radius.circular(10)), + ), + textStyle: TextStyle( + color: context.isDarkTheme ? Colors.black : Colors.white, + fontWeight: FontWeight.bold, + ), + message: getServerUrl() ?? '--', + preferBelow: false, + triggerMode: TooltipTriggerMode.tap, + child: Text( + getServerUrl() ?? '--', + style: TextStyle( + fontSize: contentFontSize, + color: context.colorScheme.onSurfaceSecondary, + fontWeight: FontWeight.bold, + overflow: TextOverflow.ellipsis, + ), + textAlign: TextAlign.end, + ), + ), + ), + ), + ], + ), + if (serverInfoState.latestVersion != null) ...[ + const Padding(padding: EdgeInsets.symmetric(horizontal: 10), child: Divider(thickness: 1)), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.only(left: 10.0), + child: Row( + children: [ + if (serverInfoState.versionStatus == VersionStatus.serverOutOfDate) + const Padding( + padding: EdgeInsets.only(right: 5.0), + child: Icon(Icons.info, color: Color.fromARGB(255, 243, 188, 106), size: 12), + ), + Text( + "latest_version".tr(), + style: TextStyle( + fontSize: titleFontSize, + color: context.textTheme.labelSmall?.color, + fontWeight: FontWeight.w500, + ), + ), + ], + ), + ), + ), + Expanded( + flex: 0, + child: Padding( + padding: const EdgeInsets.only(right: 10.0), + child: Text( + serverInfoState.latestVersion!.major > 0 + ? "${serverInfoState.latestVersion!.major}.${serverInfoState.latestVersion!.minor}.${serverInfoState.latestVersion!.patch}" + : "--", + style: TextStyle( + fontSize: contentFontSize, + color: context.colorScheme.onSurfaceSecondary, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], + ), + ], + ], ), ); }