From 8017c5ab4c8ab85ab19be8b55e5ff9bc37f8f2f4 Mon Sep 17 00:00:00 2001 From: Inex Code Date: Sun, 18 Sep 2022 19:06:17 +0300 Subject: [PATCH] Show services in Server Storage screen --- .../server_storage_list_item.dart | 106 +++++++++++++----- .../service_migration_list_item.dart | 62 +++++----- .../pages/server_storage/server_storage.dart | 57 ++++++++++ 3 files changed, 171 insertions(+), 54 deletions(-) diff --git a/lib/ui/components/storage_list_items/server_storage_list_item.dart b/lib/ui/components/storage_list_items/server_storage_list_item.dart index 371769a8..1cc07572 100644 --- a/lib/ui/components/storage_list_items/server_storage_list_item.dart +++ b/lib/ui/components/storage_list_items/server_storage_list_item.dart @@ -15,6 +15,55 @@ class ServerStorageListItem extends StatelessWidget { final bool showIcon; final bool dense; + @override + Widget build(final BuildContext context) => ConsumptionListItem( + title: 'providers.storage.disk_usage'.tr( + args: [ + volume.sizeUsed.toString(), + ], + ), + subtitle: 'providers.storage.disk_total'.tr( + args: [ + volume.sizeTotal.toString(), + volume.displayName, + ], + ), + dense: dense, + color: volume.root + ? Theme.of(context).colorScheme.primary + : Theme.of(context).colorScheme.secondary, + backgroundColor: Theme.of(context).colorScheme.surfaceVariant, + percentage: volume.percentage, + icon: Icon( + Icons.storage_outlined, + size: 24, + color: Theme.of(context).colorScheme.onBackground, + ), + ); +} + +class ConsumptionListItem extends StatelessWidget { + const ConsumptionListItem({ + required this.title, + required this.color, + required this.backgroundColor, + required this.percentage, + this.subtitle, + this.rightSideText, + this.icon, + this.dense = false, + final super.key, + }); + + final String title; + final String? subtitle; + final String? rightSideText; + final Color color; + final Color backgroundColor; + final double percentage; + final Widget? icon; + final bool dense; + @override Widget build(final BuildContext context) { final TextStyle? titleStyle = dense @@ -26,45 +75,46 @@ class ServerStorageListItem extends StatelessWidget { : Theme.of(context).textTheme.bodyMedium; return Row( + crossAxisAlignment: CrossAxisAlignment.center, children: [ - if (showIcon) - Icon( - Icons.storage_outlined, - size: 24, - color: Theme.of(context).colorScheme.onBackground, - ), - if (showIcon) const SizedBox(width: 16), + if (icon != null) icon!, + if (icon != null) const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - 'providers.storage.disk_usage'.tr( - args: [ - volume.sizeUsed.toString(), - ], - ), - style: titleStyle, + Row( + mainAxisAlignment: rightSideText != null + ? MainAxisAlignment.spaceBetween + : MainAxisAlignment.start, + children: [ + Text( + title, + style: titleStyle, + textAlign: TextAlign.start, + ), + if (rightSideText != null) + Text( + rightSideText!, + style: Theme.of(context).textTheme.bodyMedium, + textAlign: TextAlign.end, + ), + ], ), const SizedBox(height: 4), BrandLinearIndicator( - value: volume.percentage, - color: volume.root - ? Theme.of(context).colorScheme.primary - : Theme.of(context).colorScheme.secondary, - backgroundColor: Theme.of(context).colorScheme.surfaceVariant, - height: 14.0, + value: percentage, + color: color, + backgroundColor: backgroundColor, + height: dense ? 8.0 : 14.0, ), const SizedBox(height: 4), - Text( - 'providers.storage.disk_total'.tr( - args: [ - volume.sizeTotal.toString(), - volume.displayName, - ], + if (subtitle != null) + Text( + subtitle!, + style: subtitleStyle, + textAlign: TextAlign.start, ), - style: subtitleStyle, - ), ], ), ), diff --git a/lib/ui/components/storage_list_items/service_migration_list_item.dart b/lib/ui/components/storage_list_items/service_migration_list_item.dart index f6b59663..847d2cf6 100644 --- a/lib/ui/components/storage_list_items/service_migration_list_item.dart +++ b/lib/ui/components/storage_list_items/service_migration_list_item.dart @@ -20,13 +20,47 @@ class ServiceMigrationListItem extends StatelessWidget { @override Widget build(final BuildContext context) => Column( children: [ - _headerRow(context), + ServiceConsumptionTitle(service: service), const SizedBox(height: 16), ..._radioRows(context), ], ); - Widget _headerRow(final BuildContext context) => SizedBox( + List _radioRows(final BuildContext context) { + final List volumeRows = []; + + for (final DiskVolume volume in diskStatus.diskVolumes) { + volumeRows.add( + RadioListTile( + title: Text( + volume.displayName, + ), + contentPadding: EdgeInsets.zero, + activeColor: Theme.of(context).colorScheme.secondary, + dense: true, + value: volume.name, + groupValue: selectedVolume, + onChanged: (final value) { + onChange(value, service.id); + }, + ), + ); + } + + return volumeRows; + } +} + +class ServiceConsumptionTitle extends StatelessWidget { + const ServiceConsumptionTitle({ + required this.service, + final super.key, + }); + + final Service service; + + @override + Widget build(final BuildContext context) => SizedBox( height: 24, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 8), @@ -63,28 +97,4 @@ class ServiceMigrationListItem extends StatelessWidget { ), ), ); - - List _radioRows(final BuildContext context) { - final List volumeRows = []; - - for (final DiskVolume volume in diskStatus.diskVolumes) { - volumeRows.add( - RadioListTile( - title: Text( - volume.displayName, - ), - contentPadding: EdgeInsets.zero, - activeColor: Theme.of(context).colorScheme.secondary, - dense: true, - value: volume.name, - groupValue: selectedVolume, - onChanged: (final value) { - onChange(value, service.id); - }, - ), - ); - } - - return volumeRows; - } } diff --git a/lib/ui/pages/server_storage/server_storage.dart b/lib/ui/pages/server_storage/server_storage.dart index f29e9694..9a83789a 100644 --- a/lib/ui/pages/server_storage/server_storage.dart +++ b/lib/ui/pages/server_storage/server_storage.dart @@ -1,6 +1,9 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart'; +import 'package:selfprivacy/logic/cubit/services/services_cubit.dart'; +import 'package:selfprivacy/logic/models/service.dart'; import 'package:selfprivacy/ui/components/brand_button/outlined_button.dart'; import 'package:selfprivacy/ui/components/brand_hero_screen/brand_hero_screen.dart'; import 'package:selfprivacy/logic/models/disk_status.dart'; @@ -23,6 +26,9 @@ class _ServerStoragePageState extends State { final bool isReady = context.watch().state is ServerInstallationFinished; + final List services = + context.watch().state.services; + if (!isReady) { return BrandHeroScreen( hasBackButton: true, @@ -39,10 +45,17 @@ class _ServerStoragePageState extends State { ...widget.diskStatus.diskVolumes .map( (final volume) => Column( + mainAxisSize: MainAxisSize.min, children: [ ServerStorageSection( volume: volume, diskStatus: widget.diskStatus, + services: services + .where( + (final service) => + service.storageUsage.volume == volume.name, + ) + .toList(), ), const SizedBox(height: 16), const Divider(), @@ -61,18 +74,30 @@ class ServerStorageSection extends StatelessWidget { const ServerStorageSection({ required this.volume, required this.diskStatus, + required this.services, final super.key, }); final DiskVolume volume; final DiskStatus diskStatus; + final List services; @override Widget build(final BuildContext context) => Column( + mainAxisSize: MainAxisSize.min, children: [ ServerStorageListItem( volume: volume, ), + const SizedBox(height: 16), + ...services + .map( + (final service) => ServerConsumptionListTile( + service: service, + volume: volume, + ), + ) + .toList(), if (volume.isResizable) ...[ const SizedBox(height: 16), BrandOutlinedButton( @@ -90,3 +115,35 @@ class ServerStorageSection extends StatelessWidget { ], ); } + +class ServerConsumptionListTile extends StatelessWidget { + const ServerConsumptionListTile({ + required this.service, + required this.volume, + final super.key, + }); + + final Service service; + final DiskVolume volume; + + @override + Widget build(final BuildContext context) => Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: ConsumptionListItem( + title: service.displayName, + icon: SvgPicture.string( + service.svgIcon, + width: 24.0, + height: 24.0, + color: Theme.of(context).colorScheme.onBackground, + ), + rightSideText: service.storageUsage.used.toString(), + percentage: service.storageUsage.used.byte / volume.sizeTotal.byte, + color: volume.root + ? Theme.of(context).colorScheme.primary + : Theme.of(context).colorScheme.secondary, + backgroundColor: Theme.of(context).colorScheme.surfaceVariant, + dense: true, + ), + ); +}