diff --git a/lib/ui/pages/providers/providers.dart b/lib/ui/pages/providers/providers.dart index bd150de3..6aa06287 100644 --- a/lib/ui/pages/providers/providers.dart +++ b/lib/ui/pages/providers/providers.dart @@ -3,19 +3,18 @@ import 'package:flutter/material.dart'; import 'package:selfprivacy/config/brand_theme.dart'; import 'package:selfprivacy/logic/cubit/backups/backups_cubit.dart'; import 'package:selfprivacy/logic/cubit/dns_records/dns_records_cubit.dart'; +import 'package:selfprivacy/logic/cubit/provider_volumes/provider_volume_cubit.dart'; import 'package:selfprivacy/logic/cubit/providers/providers_cubit.dart'; import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart'; -import 'package:selfprivacy/logic/cubit/provider_volumes/provider_volume_cubit.dart'; import 'package:selfprivacy/logic/cubit/server_volumes/server_volume_cubit.dart'; -import 'package:selfprivacy/logic/models/provider.dart'; -import 'package:selfprivacy/ui/components/brand_cards/brand_cards.dart'; +import 'package:selfprivacy/logic/models/hive/server_details.dart'; +import 'package:selfprivacy/logic/models/json/server_disk_volume.dart'; import 'package:selfprivacy/ui/components/brand_header/brand_header.dart'; -import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; +import 'package:selfprivacy/ui/components/brand_icons/brand_icons.dart'; import 'package:selfprivacy/ui/components/icon_status_mask/icon_status_mask.dart'; import 'package:selfprivacy/ui/components/not_ready_card/not_ready_card.dart'; import 'package:selfprivacy/ui/pages/backup_details/backup_details.dart'; import 'package:selfprivacy/ui/pages/dns_details/dns_details.dart'; -import 'package:selfprivacy/ui/pages/providers/storage_card.dart'; import 'package:selfprivacy/ui/pages/server_details/server_details_screen.dart'; import 'package:selfprivacy/ui/pages/server_storage/disk_status.dart'; import 'package:selfprivacy/utils/route_transitions/basic.dart'; @@ -39,6 +38,25 @@ class _ProvidersPageState extends State { final DnsRecordsStatus dnsStatus = context.watch().state.dnsState; + final List serverVolumes = + context.watch().state.volumes; + final List providerVolumes = + context.watch().state.volumes; + final diskStatus = DiskStatus.fromVolumes(serverVolumes, providerVolumes); + + final ServerInstallationState appConfig = + context.watch().state; + + StateType getServerStatus() { + if (!isReady) { + return StateType.uninitialized; + } + if (!diskStatus.isDiskOkay) { + return StateType.warning; + } + return StateType.stable; + } + StateType getDnsStatus() { if (dnsStatus == DnsRecordsStatus.uninitialized || dnsStatus == DnsRecordsStatus.refreshing) { @@ -50,36 +68,6 @@ class _ProvidersPageState extends State { return StateType.stable; } - final List cards = ProviderType.values - .map( - (final ProviderType type) => Padding( - padding: const EdgeInsets.only(bottom: 30), - child: _Card( - provider: ProviderModel( - state: isReady - ? (type == ProviderType.backup && !isBackupInitialized - ? StateType.uninitialized - : (type == ProviderType.domain) - ? getDnsStatus() - : StateType.stable) - : StateType.uninitialized, - type: type, - ), - ), - ), - ) - .toList(); - cards.add( - Padding( - padding: const EdgeInsets.only(bottom: 30), - child: StorageCard( - diskStatus: DiskStatus.fromVolumes( - context.read().state.volumes, - context.read().state.volumes, - ), - ), - ), - ); return Scaffold( appBar: PreferredSize( preferredSize: const Size.fromHeight(52), @@ -94,7 +82,45 @@ class _ProvidersPageState extends State { const NotReadyCard(), const SizedBox(height: 24), ], - ...cards, + _Card( + state: getServerStatus(), + icon: BrandIcons.server, + title: 'providers.server.card_title'.tr(), + subtitle: diskStatus.isDiskOkay + ? 'providers.storage.status_ok'.tr() + : 'providers.storage.status_error'.tr(), + onTap: () => Navigator.of(context) + .push(materialRoute(const ServerDetailsScreen())), + ), + const SizedBox(height: 16), + _Card( + state: getDnsStatus(), + icon: BrandIcons.globe, + title: 'providers.domain.screen_title'.tr(), + subtitle: appConfig.isDomainSelected + ? appConfig.serverDomain!.domainName + : '', + onTap: () => Navigator.of(context).push( + materialRoute( + const DnsDetailsPage(), + ), + ), + ), + const SizedBox(height: 16), + // TODO: When backups are fixed, show this card + if (isBackupInitialized) + _Card( + state: isBackupInitialized + ? StateType.stable + : StateType.uninitialized, + icon: BrandIcons.save, + title: 'providers.backup.card_title'.tr(), + subtitle: isBackupInitialized + ? 'providers.backup.card_subtitle'.tr() + : '', + onTap: () => Navigator.of(context) + .push(materialRoute(const BackupDetails())), + ), ], ), ); @@ -102,76 +128,64 @@ class _ProvidersPageState extends State { } class _Card extends StatelessWidget { - const _Card({required this.provider}); + const _Card({ + required final this.state, + required final this.icon, + required final this.title, + required final this.subtitle, + final this.onTap, + }); + + final Function()? onTap; + final StateType state; + final IconData icon; + final String title; + final String subtitle; - final ProviderModel provider; @override - Widget build(final BuildContext context) { - late String title; - String? message; - late String stableText; - late VoidCallback onTap; - final bool isReady = context.watch().state - is ServerInstallationFinished; - final ServerInstallationState appConfig = - context.watch().state; - - switch (provider.type) { - case ProviderType.server: - title = 'providers.server.card_title'.tr(); - stableText = 'providers.server.status'.tr(); - onTap = () => Navigator.of(context).push(materialRoute(const ServerDetailsScreen())); - break; - case ProviderType.domain: - title = 'providers.domain.screen_title'.tr(); - message = appConfig.isDomainSelected - ? appConfig.serverDomain!.domainName - : ''; - stableText = 'providers.domain.status'.tr(); - - onTap = () => Navigator.of(context).push( - materialRoute( - const DnsDetailsPage(), - ), - ); - break; - case ProviderType.backup: - title = 'providers.backup.card_title'.tr(); - stableText = 'providers.backup.status'.tr(); - - onTap = () => Navigator.of(context).push( - materialRoute( - const BackupDetails(), - ), - ); - break; - } - return GestureDetector( - onTap: isReady ? onTap : null, - child: BrandCards.big( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - IconStatusMask( - status: provider.state, - child: Icon(provider.icon, size: 30, color: Colors.white), + Widget build(final BuildContext context) => Card( + child: InkResponse( + highlightShape: BoxShape.rectangle, + onTap: onTap, + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + IconStatusMask( + status: state, + child: Icon(icon, size: 30, color: Colors.white), + ), + if (state != StateType.uninitialized) + IconStatusMask( + status: state, + child: Icon( + state == StateType.stable + ? Icons.check_circle_outline + : state == StateType.warning + ? Icons.warning_amber_outlined + : Icons.error_outline, + color: Colors.white, + ), + ), + ], + ), + const SizedBox(height: 8), + Text( + title, + style: Theme.of(context).textTheme.titleLarge, + ), + if (state != StateType.uninitialized) + Text( + subtitle, + style: Theme.of(context).textTheme.bodyLarge, + ), + ], ), - const SizedBox(height: 16), - Text( - title, - style: Theme.of(context).textTheme.titleLarge, - ), - if (message != null) ...[ - Text( - message, - style: Theme.of(context).textTheme.titleLarge, - ), - const SizedBox(height: 16), - ], - if (provider.state == StateType.stable) BrandText.body2(stableText), - ], + ), ), - ), - ); - } + ); } diff --git a/lib/ui/pages/server_details/server_details_screen.dart b/lib/ui/pages/server_details/server_details_screen.dart index ffd48e7e..ac7b13bb 100644 --- a/lib/ui/pages/server_details/server_details_screen.dart +++ b/lib/ui/pages/server_details/server_details_screen.dart @@ -17,7 +17,7 @@ import 'package:selfprivacy/ui/components/brand_loader/brand_loader.dart'; import 'package:selfprivacy/ui/components/brand_radio_tile/brand_radio_tile.dart'; import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; import 'package:selfprivacy/ui/components/switch_block/switch_bloc.dart'; -import 'package:selfprivacy/ui/pages/providers/storage_card.dart'; +import 'package:selfprivacy/ui/pages/server_storage/storage_card.dart'; import 'package:selfprivacy/ui/pages/server_details/time_zone/lang.dart'; import 'package:selfprivacy/ui/pages/server_storage/disk_status.dart'; import 'package:selfprivacy/utils/extensions/duration.dart'; diff --git a/lib/ui/pages/providers/storage_card.dart b/lib/ui/pages/server_storage/storage_card.dart similarity index 95% rename from lib/ui/pages/providers/storage_card.dart rename to lib/ui/pages/server_storage/storage_card.dart index 69e245c6..c7c2e4ab 100644 --- a/lib/ui/pages/providers/storage_card.dart +++ b/lib/ui/pages/server_storage/storage_card.dart @@ -44,14 +44,13 @@ class StorageCard extends StatelessWidget { return Card( child: InkResponse( highlightShape: BoxShape.rectangle, - onTap: () => Navigator.of(context).push( - materialRoute( - ServerStoragePage( - diskStatus: diskStatus, + onTap: () => Navigator.of(context).push( + materialRoute( + ServerStoragePage( + diskStatus: diskStatus, + ), ), ), - ), - child: Padding( padding: const EdgeInsets.all(16.0), child: Column(