From e11e5b1a7b83c11f422d82b6ad4b1e9a3902d5c9 Mon Sep 17 00:00:00 2001 From: Inex Code Date: Wed, 11 Dec 2024 20:19:51 +0300 Subject: [PATCH] refactor(ui): Skeletonize servere storage card and text details card. Enable skeleton transition animation. --- .../brand_linear_indicator.dart | 43 +- .../cards/server_text_details_card.dart | 95 ++++ lib/ui/molecules/cards/storage_card.dart | 124 +++++ lib/ui/pages/devices/devices.dart | 2 + lib/ui/pages/dns_details/dns_details.dart | 1 + lib/ui/pages/providers/providers.dart | 2 + lib/ui/pages/recovery_key/recovery_key.dart | 79 ++-- .../server_details/server_details_screen.dart | 8 +- lib/ui/pages/server_details/text_details.dart | 58 --- .../pages/server_details/time_zone/lang.dart | 431 ------------------ lib/ui/pages/server_storage/storage_card.dart | 101 ---- lib/utils/fake_data.dart | 17 + 12 files changed, 302 insertions(+), 659 deletions(-) create mode 100644 lib/ui/molecules/cards/server_text_details_card.dart create mode 100644 lib/ui/molecules/cards/storage_card.dart delete mode 100644 lib/ui/pages/server_details/text_details.dart delete mode 100644 lib/ui/pages/server_details/time_zone/lang.dart delete mode 100644 lib/ui/pages/server_storage/storage_card.dart diff --git a/lib/ui/atoms/progress_indicators/brand_linear_indicator.dart b/lib/ui/atoms/progress_indicators/brand_linear_indicator.dart index 34fb9e10..d2b37e69 100644 --- a/lib/ui/atoms/progress_indicators/brand_linear_indicator.dart +++ b/lib/ui/atoms/progress_indicators/brand_linear_indicator.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:skeletonizer/skeletonizer.dart'; class BrandLinearIndicator extends StatelessWidget { const BrandLinearIndicator({ @@ -16,29 +17,31 @@ class BrandLinearIndicator extends StatelessWidget { @override Widget build(final BuildContext context) => LayoutBuilder( - builder: (final context, final constraints) => Container( - height: height, - width: constraints.maxWidth, - clipBehavior: Clip.antiAlias, - decoration: BoxDecoration( - color: backgroundColor, - borderRadius: BorderRadius.circular(height), - ), - alignment: Alignment.centerLeft, - child: AnimatedSlide( - duration: const Duration(milliseconds: 400), - curve: Curves.easeInOutCubicEmphasized, - offset: Offset( - -(1 - value), - 0, + builder: (final context, final constraints) => Skeleton.leaf( + child: Container( + height: height, + width: constraints.maxWidth, + clipBehavior: Clip.antiAlias, + decoration: BoxDecoration( + color: backgroundColor, + borderRadius: BorderRadius.circular(height), ), - child: AnimatedContainer( + alignment: Alignment.centerLeft, + child: AnimatedSlide( duration: const Duration(milliseconds: 400), curve: Curves.easeInOutCubicEmphasized, - width: constraints.maxWidth, - decoration: BoxDecoration( - color: color, - borderRadius: BorderRadius.circular(height), + offset: Offset( + -(1 - value), + 0, + ), + child: AnimatedContainer( + duration: const Duration(milliseconds: 400), + curve: Curves.easeInOutCubicEmphasized, + width: constraints.maxWidth, + decoration: BoxDecoration( + color: color, + borderRadius: BorderRadius.circular(height), + ), ), ), ), diff --git a/lib/ui/molecules/cards/server_text_details_card.dart b/lib/ui/molecules/cards/server_text_details_card.dart new file mode 100644 index 00000000..2a9c6ed5 --- /dev/null +++ b/lib/ui/molecules/cards/server_text_details_card.dart @@ -0,0 +1,95 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:selfprivacy/logic/cubit/server_detailed_info/server_detailed_info_cubit.dart'; +import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart'; +import 'package:selfprivacy/logic/models/server_metadata.dart'; +import 'package:selfprivacy/ui/atoms/cards/filled_card.dart'; +import 'package:selfprivacy/ui/atoms/list_tiles/list_tile_on_surface_variant.dart'; +import 'package:selfprivacy/utils/fake_data.dart'; +import 'package:skeletonizer/skeletonizer.dart'; + +class ServerTextDetailsCard extends StatelessWidget { + const ServerTextDetailsCard({super.key}); + + @override + Widget build(final BuildContext context) { + final details = context.watch().state; + + final isLoading = details is! Loaded; + + if (details is ServerDetailsNotReady) { + return _TempMessage(message: 'basis.no_data'.tr()); + } else { + return Skeletonizer( + enabled: isLoading || details.metadata.isEmpty, + containersColor: Theme.of(context).colorScheme.surfaceContainerLow, + enableSwitchAnimation: true, + child: FilledCard( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(16.0), + child: Skeleton.keep( + child: Text( + 'server.general_information'.tr(), + style: Theme.of(context).textTheme.titleMedium?.copyWith( + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ), + ), + ), + if (!isLoading) + ...details.metadata.map( + (final metadata) => _ServerTextDetailTile( + metadata: metadata, + ), + ), + if (isLoading || details.metadata.isEmpty) + ...List.generate( + 8, + (final index) => FakeSelfPrivacyData.fakeServerMetadataEntity, + ).map( + (final metadata) => _ServerTextDetailTile(metadata: metadata), + ), + ], + ), + ), + ); + } + } +} + +class _ServerTextDetailTile extends StatelessWidget { + const _ServerTextDetailTile({ + required this.metadata, + }); + + final ServerMetadataEntity metadata; + + @override + Widget build(final BuildContext context) => ListTileOnSurfaceVariant( + leadingIcon: metadata.type.icon, + title: metadata.trId.tr(), + subtitle: metadata.value, + ); +} + +class _TempMessage extends StatelessWidget { + const _TempMessage({ + required this.message, + }); + + final String message; + @override + Widget build(final BuildContext context) => SizedBox( + height: 200, + child: Center( + child: Text( + message, + style: Theme.of(context).textTheme.bodyMedium, + ), + ), + ); +} diff --git a/lib/ui/molecules/cards/storage_card.dart b/lib/ui/molecules/cards/storage_card.dart new file mode 100644 index 00000000..71db9258 --- /dev/null +++ b/lib/ui/molecules/cards/storage_card.dart @@ -0,0 +1,124 @@ +import 'package:auto_route/auto_route.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart'; +import 'package:selfprivacy/logic/models/disk_status.dart'; +import 'package:selfprivacy/logic/models/state_types.dart'; +import 'package:selfprivacy/ui/atoms/masks/icon_status_mask.dart'; +import 'package:selfprivacy/ui/organisms/storage_list_items/server_storage_list_item.dart'; +import 'package:selfprivacy/ui/router/router.dart'; +import 'package:selfprivacy/utils/fake_data.dart'; +import 'package:skeletonizer/skeletonizer.dart'; + +class StorageCard extends StatelessWidget { + const StorageCard({ + required this.diskStatus, + super.key, + }); + + final DiskStatus diskStatus; + + @override + Widget build(final BuildContext context) { + final List sections = []; + for (final DiskVolume volume in diskStatus.diskVolumes) { + sections.add( + const SizedBox(height: 16), + ); + sections.add( + ServerStorageListItem( + volume: volume, + dense: true, + showIcon: false, + ), + ); + } + + final List fakeSections = [ + const SizedBox(height: 16), + ServerStorageListItem( + volume: FakeSelfPrivacyData.fakeDiskVolume, + dense: true, + showIcon: false, + ), + const SizedBox(height: 16), + ServerStorageListItem( + volume: FakeSelfPrivacyData.fakeDiskVolume, + dense: true, + showIcon: false, + ), + ]; + + StateType state = context.watch().state + is ServerInstallationFinished + ? StateType.stable + : StateType.uninitialized; + + if (state == StateType.stable && !diskStatus.isDiskOkay) { + state = StateType.error; + } + + return Skeletonizer( + enabled: diskStatus.diskVolumes.isEmpty, + enableSwitchAnimation: true, + child: Card( + clipBehavior: Clip.antiAlias, + child: InkResponse( + highlightShape: BoxShape.rectangle, + onTap: () => diskStatus.diskVolumes.isEmpty + ? null + : context.pushRoute(ServerStorageRoute(diskStatus: diskStatus)), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Skeleton.shade( + child: Text( + 'storage.card_title'.tr(), + style: Theme.of(context).textTheme.titleLarge, + ), + ), + if (state != StateType.uninitialized) + Text( + diskStatus.isDiskOkay + ? 'storage.status_ok'.tr() + : 'storage.status_error'.tr(), + style: Theme.of(context).textTheme.bodyLarge, + ), + ], + ), + ), + if (state != StateType.uninitialized) + Skeleton.ignore( + child: IconStatusMask( + status: state, + icon: Icon( + diskStatus.isDiskOkay + ? Icons.check_circle_outline + : Icons.error_outline, + size: 24, + color: Colors.white, + ), + ), + ), + ], + ), + ...sections, + if (diskStatus.diskVolumes.isEmpty) ...fakeSections, + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/ui/pages/devices/devices.dart b/lib/ui/pages/devices/devices.dart index f2d728a7..f60a8143 100644 --- a/lib/ui/pages/devices/devices.dart +++ b/lib/ui/pages/devices/devices.dart @@ -82,6 +82,7 @@ class _DevicesInfo extends StatelessWidget { Skeletonizer( enabled: devicesStatus.thisDevice == FakeSelfPrivacyData.thisDeviceToken, + enableSwitchAnimation: true, child: DeviceItem( device: devicesStatus.thisDevice, ), @@ -103,6 +104,7 @@ class _DevicesInfo extends StatelessWidget { 3, (final index) => Skeletonizer( enabled: true, + enableSwitchAnimation: true, child: DeviceItem( device: FakeSelfPrivacyData.otherDeviceToken, ), diff --git a/lib/ui/pages/dns_details/dns_details.dart b/lib/ui/pages/dns_details/dns_details.dart index 14b4db42..c918a52b 100644 --- a/lib/ui/pages/dns_details/dns_details.dart +++ b/lib/ui/pages/dns_details/dns_details.dart @@ -68,6 +68,7 @@ class _DnsDetailsPageState extends State { .map( (final dnsRecord) => Skeletonizer( enabled: refreshing, + enableSwitchAnimation: true, child: DnsRecordItem( dnsRecord: dnsRecord, refreshing: refreshing, diff --git a/lib/ui/pages/providers/providers.dart b/lib/ui/pages/providers/providers.dart index 5cb6ddd2..5cb0c4e9 100644 --- a/lib/ui/pages/providers/providers.dart +++ b/lib/ui/pages/providers/providers.dart @@ -103,6 +103,7 @@ class _ProvidersPageState extends State { const SizedBox(height: 16), Skeletonizer( enabled: dnsStatus == DnsRecordsStatus.refreshing, + enableSwitchAnimation: true, child: ProvidersPageCard( state: getDnsStatus(), icon: BrandIcons.globe, @@ -119,6 +120,7 @@ class _ProvidersPageState extends State { Skeletonizer( enabled: backupsState is BackupsLoading || backupsState is BackupsInitial, + enableSwitchAnimation: true, child: ProvidersPageCard( state: backupsState is BackupsInitialized ? StateType.stable diff --git a/lib/ui/pages/recovery_key/recovery_key.dart b/lib/ui/pages/recovery_key/recovery_key.dart index ed262940..fe8786b3 100644 --- a/lib/ui/pages/recovery_key/recovery_key.dart +++ b/lib/ui/pages/recovery_key/recovery_key.dart @@ -6,6 +6,7 @@ import 'package:selfprivacy/config/get_it_config.dart'; import 'package:selfprivacy/logic/bloc/recovery_key/recovery_key_bloc.dart'; import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart'; import 'package:selfprivacy/ui/atoms/buttons/brand_button.dart'; +import 'package:selfprivacy/ui/atoms/buttons/outlined_button.dart'; import 'package:selfprivacy/ui/atoms/cards/filled_card.dart'; import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart'; import 'package:selfprivacy/ui/pages/recovery_key/recovery_key_receiving.dart'; @@ -58,6 +59,7 @@ class _RecoveryKeyPageState extends State { heroSubtitle: subtitle, hasBackButton: true, hasFlashButton: false, + heroIcon: Icons.password_outlined, children: widgets, ), ); @@ -92,7 +94,7 @@ class _RecoveryKeyContentState extends State { ), const SizedBox(height: 16), if (!_isConfigurationVisible && keyStatus.isValid && keyStatus.exists) - BrandButton.text( + BrandOutlinedButton( title: 'recovery_key.key_replace_button'.tr(), onPressed: () { setState(() { @@ -157,55 +159,44 @@ class RecoveryKeyInformation extends StatelessWidget { final RecoveryKeyState state; @override - Widget build(final BuildContext context) { - const EdgeInsets padding = - EdgeInsets.symmetric(vertical: 8.0, horizontal: 8.0); - return SizedBox( - width: double.infinity, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (state.expiresAt != null) - Padding( - padding: padding, - child: Text( - 'recovery_key.key_valid_until'.tr( - args: [DateFormat.yMMMMd().format(state.expiresAt!)], + Widget build(final BuildContext context) => SizedBox( + width: double.infinity, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (state.expiresAt != null) + ListTile( + title: Text( + 'recovery_key.key_valid_until'.tr( + args: [DateFormat.yMMMMd().format(state.expiresAt!)], + ), ), - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: state.isInvalidBecauseExpired - ? Theme.of(context).colorScheme.error - : Theme.of(context).colorScheme.onSurface, - ), + textColor: state.isInvalidBecauseExpired + ? Theme.of(context).colorScheme.error + : Theme.of(context).colorScheme.onSurface, ), - ), - if (state.usesLeft != null) - Padding( - padding: padding, - child: Text( - 'recovery_key.key_valid_for'.tr( - args: [state.usesLeft!.toString()], + if (state.usesLeft != null) + ListTile( + title: Text( + 'recovery_key.key_valid_for'.tr( + args: [state.usesLeft!.toString()], + ), ), - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: state.isInvalidBecauseUsed - ? Theme.of(context).colorScheme.error - : Theme.of(context).colorScheme.onSurface, - ), + textColor: state.isInvalidBecauseUsed + ? Theme.of(context).colorScheme.error + : Theme.of(context).colorScheme.onSurface, ), - ), - if (state.generatedAt != null) - Padding( - padding: padding, - child: Text( - 'recovery_key.key_creation_date'.tr( - args: [DateFormat.yMMMMd().format(state.generatedAt!)], + if (state.generatedAt != null) + ListTile( + title: Text( + 'recovery_key.key_creation_date'.tr( + args: [DateFormat.yMMMMd().format(state.generatedAt!)], + ), ), ), - ), - ], - ), - ); - } + ], + ), + ); } class RecoveryKeyConfiguration extends StatefulWidget { diff --git a/lib/ui/pages/server_details/server_details_screen.dart b/lib/ui/pages/server_details/server_details_screen.dart index d521b4af..eeced536 100644 --- a/lib/ui/pages/server_details/server_details_screen.dart +++ b/lib/ui/pages/server_details/server_details_screen.dart @@ -5,7 +5,6 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:selfprivacy/logic/bloc/volumes/volumes_bloc.dart'; import 'package:selfprivacy/logic/common_enum/common_enum.dart'; import 'package:selfprivacy/logic/cubit/metrics/metrics_cubit.dart'; -import 'package:selfprivacy/logic/cubit/server_detailed_info/server_detailed_info_cubit.dart'; import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart'; import 'package:selfprivacy/logic/models/disk_status.dart'; import 'package:selfprivacy/logic/models/metrics.dart'; @@ -13,17 +12,16 @@ import 'package:selfprivacy/theming/harmonized_basic_colors.dart'; import 'package:selfprivacy/ui/atoms/buttons/segmented_buttons.dart'; import 'package:selfprivacy/ui/atoms/cards/filled_card.dart'; import 'package:selfprivacy/ui/atoms/icons/brand_icons.dart'; -import 'package:selfprivacy/ui/atoms/list_tiles/list_tile_on_surface_variant.dart'; import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart'; +import 'package:selfprivacy/ui/molecules/cards/server_text_details_card.dart'; +import 'package:selfprivacy/ui/molecules/cards/storage_card.dart'; import 'package:selfprivacy/ui/pages/server_details/charts/cpu_chart.dart'; import 'package:selfprivacy/ui/pages/server_details/charts/disk_charts.dart'; import 'package:selfprivacy/ui/pages/server_details/charts/memory_chart.dart'; import 'package:selfprivacy/ui/pages/server_details/charts/network_charts.dart'; -import 'package:selfprivacy/ui/pages/server_storage/storage_card.dart'; import 'package:selfprivacy/ui/router/router.dart'; part 'charts/chart.dart'; -part 'text_details.dart'; var navigatorKey = GlobalKey(); @@ -99,7 +97,7 @@ class _ServerDetailsScreenState extends State child: _Chart(), ), const SizedBox(height: 8), - _TextDetails(), + const ServerTextDetailsCard(), ], ); } diff --git a/lib/ui/pages/server_details/text_details.dart b/lib/ui/pages/server_details/text_details.dart deleted file mode 100644 index 95569356..00000000 --- a/lib/ui/pages/server_details/text_details.dart +++ /dev/null @@ -1,58 +0,0 @@ -part of 'server_details_screen.dart'; - -class _TextDetails extends StatelessWidget { - @override - Widget build(final BuildContext context) { - final details = context.watch().state; - - if (details is ServerDetailsLoading || details is ServerDetailsInitial) { - return _TempMessage(message: 'basis.loading'.tr()); - } else if (details is ServerDetailsNotReady) { - return _TempMessage(message: 'basis.no_data'.tr()); - } else if (details is Loaded) { - return FilledCard( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(16.0), - child: Text( - 'server.general_information'.tr(), - style: Theme.of(context).textTheme.titleMedium?.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - ), - ...details.metadata.map( - (final metadata) => ListTileOnSurfaceVariant( - leadingIcon: metadata.type.icon, - title: metadata.trId.tr(), - subtitle: metadata.value, - ), - ), - ], - ), - ); - } else { - throw Exception('wrong state'); - } - } -} - -class _TempMessage extends StatelessWidget { - const _TempMessage({ - required this.message, - }); - - final String message; - @override - Widget build(final BuildContext context) => SizedBox( - height: 200, - child: Center( - child: Text( - message, - style: Theme.of(context).textTheme.bodyMedium, - ), - ), - ); -} diff --git a/lib/ui/pages/server_details/time_zone/lang.dart b/lib/ui/pages/server_details/time_zone/lang.dart deleted file mode 100644 index b46fa721..00000000 --- a/lib/ui/pages/server_details/time_zone/lang.dart +++ /dev/null @@ -1,431 +0,0 @@ -final russian = { - 'Pacific/Midway': 'Мидуэй', - 'Pacific/Niue': 'Ниуэ', - 'Pacific/Pago_Pago': 'Паго-Паго', - 'America/Adak': 'Адак', - 'Pacific/Honolulu': 'Гонолулу', - 'Pacific/Johnston': 'Джонстон', - 'Pacific/Rarotonga': 'Раротонга', - 'Pacific/Tahiti': 'Таити', - 'US/Hawaii': 'Гавайи', - 'Pacific/Marquesas': 'Маркизские острова', - 'America/Sitka': 'Ситка', - 'America/Anchorage': 'Анкоридж', - 'America/Metlakatla': 'Метлакатла', - 'America/Juneau': 'Джуно', - 'US/Alaska': 'Аляска', - 'America/Nome': 'Ном', - 'America/Yakutat': 'Якутат', - 'Pacific/Gambier': 'Гамбье', - 'America/Tijuana': 'Тихуана', - 'Pacific/Pitcairn': 'Питкэрн', - 'US/Pacific': 'США/Тихий океан', - 'Canada/Pacific': 'США/Тихий океан', - 'America/Los_Angeles': 'Лос-Анджелес', - 'America/Vancouver': 'Ванкувер', - 'America/Santa_Isabel': 'Санта-Изабель', - 'America/Chihuahua': 'Чихуахуа', - 'America/Cambridge_Bay': 'Кембридж-Бэй', - 'America/Inuvik': 'Инувик', - 'America/Boise': 'Бойсе', - 'America/Dawson': 'Доусон', - 'America/Mazatlan': 'Масатлан', - 'America/Dawson_Creek': 'Доусон-Крик', - 'US/Arizona': 'Аризона', - 'America/Denver': 'Денвер', - 'US/Mountain': 'гора', - 'America/Edmonton': 'Эдмонтон', - 'America/Yellowknife': 'Йеллоунайф', - 'America/Ojinaga': 'Охинага', - 'America/Phoenix': 'Феникс', - 'America/Whitehorse': 'Белая лошадь', - 'Canada/Mountain': 'гора', - 'America/Hermosillo': 'Эрмосильо', - 'America/Creston': 'Крестон', - 'America/Swift_Current': 'Свифт Керрент', - 'America/Tegucigalpa': 'Тегусигальпа', - 'America/Regina': 'Регина', - 'America/Rankin_Inlet': 'Ранкин-Инлет', - 'America/Rainy_River': 'Райни-Ривер', - 'America/Winnipeg': 'Виннипег', - 'America/North_Dakota/Center': 'Северная Дакота/Центр', - 'America/North_Dakota/Beulah': 'Северная Дакота/Беула', - 'America/Monterrey': 'Монтеррей', - 'America/Mexico_City': 'Мехико', - 'US/Central': 'Центральный', - 'America/Merida': 'Мерида', - 'America/Menominee': 'Меномини', - 'America/Matamoros': 'Матаморос', - 'America/Managua': 'Манагуа', - 'America/North_Dakota/New_Salem': 'Северная Дакота/Нью-Салем', - 'Pacific/Galapagos': 'Галапагосские острова', - 'America/Indiana/Tell_City': 'Индиана/Телл-Сити', - 'America/Indiana/Knox': 'Индиана/Нокс', - 'Canada/Central': 'Центральный', - 'America/Guatemala': 'Гватемала', - 'America/El_Salvador': 'Сальвадор', - 'America/Costa_Rica': 'Коста-Рика', - 'America/Chicago': 'Чикаго', - 'America/Belize': 'Белиз', - 'America/Bahia_Banderas': 'Баия де Бандерас', - 'America/Resolute': 'Резольют', - 'America/Atikokan': 'Атикокан', - 'America/Lima': 'Лима', - 'America/Bogota': 'Богота', - 'America/Cancun': 'Канкун', - 'America/Cayman': 'Кайман', - 'America/Detroit': 'Детройт', - 'America/Indiana/Indianapolis': 'Индиана/Индианаполис', - 'America/Eirunepe': 'Эйрунепе', - 'America/Grand_Turk': 'Гранд-Терк', - 'America/Guayaquil': 'Гуаякиль', - 'America/Havana': 'Гавана', - 'America/Indiana/Marengo': 'Индиана/Маренго', - 'America/Indiana/Petersburg': 'Индиана/Петербург', - 'America/Indiana/Vevay': 'Индиана/Вева', - 'America/Indiana/Vincennes': 'Индиана/Винсеннес', - 'America/Indiana/Winamac': 'Индиана/Винамак', - 'America/Iqaluit': 'Икалуит', - 'America/Jamaica': 'Ямайка', - 'America/Kentucky/Louisville': 'Кентукки/Луисвилл', - 'America/Nassau': 'Нассау', - 'America/Toronto': 'Торонто', - 'America/Montreal': 'Монреаль', - 'America/Pangnirtung': 'Пангниртунг', - 'America/Port-au-Prince': 'Порт-о-Пренс', - 'America/Kentucky/Monticello': 'Кентукки/Монтичелло', - 'Canada/Eastern': 'Канада/Восточное', - 'US/Eastern': 'США/Восточное', - 'America/Thunder_Bay': 'Тандер-Бей', - 'Pacific/Easter': 'Пасха', - 'America/Panama': 'Панама', - 'America/Nipigon': 'Нипигон', - 'America/Rio_Branco': 'Рио-Бранко', - 'America/New_York': 'Нью-Йорк', - 'Canada/Atlantic': 'Атлантика', - 'America/Kralendijk': 'Кралендейк', - 'America/La_Paz': 'Ла-Пас', - 'America/Halifax': 'Галифакс', - 'America/Lower_Princes': 'Лоуэр-Принс-Куотер', - 'America/Manaus': 'Манаус', - 'America/Marigot': 'Мариго', - 'America/Martinique': 'Мартиника', - 'America/Moncton': 'Монктон', - 'America/Guyana': 'Гайана', - 'America/Montserrat': 'Монтсеррат', - 'America/Guadeloupe': 'Гваделупа', - 'America/Grenada': 'Гренада', - 'America/Goose_Bay': 'Гуз-Бей', - 'America/Glace_Bay': 'Глас Бэй', - 'America/Curacao': 'Кюрасао', - 'America/Cuiaba': 'Куяба', - 'America/Port_of_Spain': 'Порт-оф-Спейн', - 'America/Porto_Velho': 'Порту-Велью', - 'America/Puerto_Rico': 'Пуэрто-Рико', - 'America/Caracas': 'Каракас', - 'America/Santo_Domingo': 'Санто-Доминго', - 'America/St_Barthelemy': 'Святой Бартелеми', - 'Atlantic/Bermuda': 'Бермуды', - 'America/St_Kitts': 'Сент-Китс', - 'America/St_Lucia': 'Святая Люсия', - 'America/St_Thomas': 'Сент-Томас', - 'America/St_Vincent': 'Сент-Винсент', - 'America/Thule': 'Туле', - 'America/Campo_Grande': 'Кампу-Гранди', - 'America/Boa_Vista': 'Боа-Виста', - 'America/Tortola': 'Тортола', - 'America/Aruba': 'Аруба', - 'America/Blanc-Sablon': 'Блан-Саблон', - 'America/Barbados': 'Барбадос', - 'America/Anguilla': 'Ангилья', - 'America/Antigua': 'Антигуа', - 'America/Dominica': 'Доминика', - 'Canada/Newfoundland': 'Ньюфаундленд', - 'America/St_Johns': 'Сент-Джонс', - 'America/Sao_Paulo': 'Сан-Паулу', - 'Atlantic/Stanley': 'Стэнли', - 'America/Miquelon': 'Микелон', - 'America/Argentina/Salta': 'Аргентина/Сальта', - 'America/Montevideo': 'Монтевидео', - 'America/Argentina/Rio_Gallegos': 'Аргентина/Рио-Гальегос', - 'America/Argentina/Mendoza': 'Аргентина/Мендоса', - 'America/Argentina/La_Rioja': 'Аргентина/Ла-Риоха', - 'America/Argentina/Jujuy': 'Аргентина/Жужуй', - 'Antarctica/Rothera': 'Ротера', - 'America/Argentina/Cordoba': 'Аргентина/Кордова', - 'America/Argentina/Catamarca': 'Аргентина/Катамарка', - 'America/Argentina/Ushuaia': 'Аргентина/Ушуая', - 'America/Argentina/Tucuman': 'Аргентина/Тукуман', - 'America/Paramaribo': 'Парамарибо', - 'America/Argentina/San_Luis': 'Аргентина/Сан-Луис', - 'America/Recife': 'Ресифи', - 'America/Argentina/Buenos_Aires': 'Аргентина/Буэнос-Айрес', - 'America/Asuncion': 'Асунсьон', - 'America/Maceio': 'Масейо', - 'America/Santarem': 'Сантарен', - 'America/Santiago': 'Сантьяго', - 'Antarctica/Palmer': 'Палмер', - 'America/Argentina/San_Juan': 'Аргентина/Сан-Хуан', - 'America/Fortaleza': 'Форталеза', - 'America/Cayenne': 'Кайенна', - 'America/Godthab': 'Годтаб', - 'America/Belem': 'Белен', - 'America/Araguaina': 'Арагуайна', - 'America/Bahia': 'Баия', - 'Atlantic/South_Georgia': 'Южная_Грузия', - 'America/Noronha': 'Норонья', - 'Atlantic/Azores': 'Азорские острова', - 'Atlantic/Cape_Verde': 'Кабо-Верде', - 'America/Scoresbysund': 'Скорсбисунд', - 'Africa/Accra': 'Аккра', - 'Atlantic/Faroe': 'Фарерские острова', - 'Europe/Guernsey': 'Гернси', - 'Africa/Dakar': 'Дакар', - 'Europe/Isle_of_Man': 'Остров Мэн', - 'Africa/Conakry': 'Конакри', - 'Africa/Abidjan': 'Абиджан', - 'Atlantic/Canary': 'канарейка', - 'Africa/Banjul': 'Банжул', - 'Europe/Jersey': 'Джерси', - 'Atlantic/St_Helena': 'Остров Святой Елены', - 'Africa/Bissau': 'Бисау', - 'Europe/London': 'Лондон', - 'Africa/Nouakchott': 'Нуакшот', - 'Africa/Lome': 'Ломе', - 'America/Danmarkshavn': 'Данмарксхавн', - 'Africa/Ouagadougou': 'Уагадугу', - 'Europe/Lisbon': 'Лиссабон', - 'Africa/Sao_Tome': 'Сан-Томе', - 'Africa/Monrovia': 'Монровия', - 'Atlantic/Reykjavik': 'Рейкьявик', - 'Antarctica/Troll': 'Тролль', - 'Atlantic/Madeira': 'Мадейра', - 'Africa/Bamako': 'Бамако', - 'Europe/Dublin': 'Дублин', - 'Africa/Freetown': 'Фритаун', - 'Europe/Monaco': 'Монако', - 'Europe/Skopje': 'Скопье', - 'Europe/Amsterdam': 'Амстердам', - 'Africa/Tunis': 'Тунис', - 'Arctic/Longyearbyen': 'Лонгйир', - 'Africa/Bangui': 'Банги', - 'Africa/Lagos': 'Лагос', - 'Africa/Douala': 'Дуала', - 'Africa/Libreville': 'Либревиль', - 'Europe/Belgrade': 'Белград', - 'Europe/Stockholm': 'Стокгольм', - 'Europe/Berlin': 'Берлин', - 'Europe/Zurich': 'Цюрих', - 'Europe/Zagreb': 'Загреб', - 'Europe/Warsaw': 'Варшава', - 'Africa/Luanda': 'Луанда', - 'Africa/Porto-Novo': 'Порто-Ново', - 'Africa/Brazzaville': 'Браззавиль', - 'Europe/Vienna': 'Вена', - 'Europe/Vatican': 'Ватикан', - 'Europe/Vaduz': 'Вадуц', - 'Europe/Tirane': 'Тиран', - 'Europe/Bratislava': 'Братислава', - 'Europe/Brussels': 'Брюссель', - 'Europe/Paris': 'Париж', - 'Europe/Sarajevo': 'Сараево', - 'Europe/San_Marino': 'Сан-Марино', - 'Europe/Rome': 'Рим', - 'Africa/El_Aaiun': 'Эль-Аайун', - 'Africa/Casablanca': 'Касабланка', - 'Europe/Malta': 'Мальта', - 'Africa/Ceuta': 'Сеута', - 'Europe/Gibraltar': 'Гибралтар', - 'Africa/Malabo': 'Малабо', - 'Europe/Busingen': 'Бузинген', - 'Africa/Ndjamena': 'Нджамена', - 'Europe/Andorra': 'Андорра', - 'Europe/Oslo': 'Осло', - 'Europe/Luxembourg': 'Люксембург', - 'Africa/Niamey': 'Ниамей', - 'Europe/Copenhagen': 'Копенгаген', - 'Europe/Madrid': 'Мадрид', - 'Europe/Budapest': 'Будапешт', - 'Africa/Algiers': 'Алжир', - 'Europe/Ljubljana': 'Любляна', - 'Europe/Podgorica': 'Подгорица', - 'Africa/Kinshasa': 'Киншаса', - 'Europe/Prague': 'Прага', - 'Europe/Riga': 'Рига', - 'Africa/Bujumbura': 'Бужумбура', - 'Africa/Lubumbashi': 'Лубумбаши', - 'Europe/Bucharest': 'Бухарест', - 'Africa/Blantyre': 'Блантайр', - 'Asia/Nicosia': 'Никосия', - 'Europe/Sofia': 'София', - 'Asia/Jerusalem': 'Иерусалим', - 'Europe/Tallinn': 'Таллинн', - 'Europe/Uzhgorod': 'Ужгород', - 'Africa/Lusaka': 'Лусака', - 'Europe/Mariehamn': 'Мариехамн', - 'Asia/Hebron': 'Хеврон', - 'Asia/Gaza': 'Газа', - 'Asia/Damascus': 'Дамаск', - 'Europe/Zaporozhye': 'Запорожье', - 'Asia/Beirut': 'Бейрут', - 'Africa/Juba': 'Джуба', - 'Africa/Harare': 'Хараре', - 'Europe/Athens': 'Афины', - 'Europe/Kiev': 'Киев', - 'Europe/Kaliningrad': 'Калининград', - 'Africa/Khartoum': 'Хартум', - 'Africa/Cairo': 'Каир', - 'Africa/Kigali': 'Кигали', - 'Asia/Amman': 'Амман', - 'Africa/Maputo': 'Мапуту', - 'Africa/Gaborone': 'Габороне', - 'Africa/Tripoli': 'Триполи', - 'Africa/Maseru': 'Масеру', - 'Africa/Windhoek': 'Виндхук', - 'Africa/Johannesburg': 'Йоханнесбург', - 'Europe/Chisinau': 'Кишинев', - 'Africa/Mbabane': 'Мбабане', - 'Europe/Vilnius': 'Вильнюс', - 'Europe/Helsinki': 'Хельсинки', - 'Europe/Moscow': 'Москва', - 'Africa/Kampala': 'Кампала', - 'Africa/Nairobi': 'Найроби', - 'Africa/Asmara': 'Асмэра', - 'Europe/Istanbul': 'Стамбул', - 'Asia/Riyadh': 'Эр-Рияд', - 'Asia/Qatar': 'Катар', - 'Europe/Minsk': 'Минск', - 'Indian/Comoro': 'Коморо', - 'Asia/Kuwait': 'Кувейт', - 'Africa/Addis_Ababa': 'Аддис-Абеба', - 'Africa/Dar_es_Salaam': 'Дар-эс-Салам', - 'Europe/Volgograd': 'Волгоград', - 'Indian/Antananarivo': 'Антананариву', - 'Asia/Bahrain': 'Бахрейн', - 'Asia/Baghdad': 'Багдад', - 'Indian/Mayotte': 'Майотта', - 'Africa/Djibouti': 'Джибути', - 'Europe/Simferopol': 'Симферополь', - 'Asia/Aden': 'Аден', - 'Antarctica/Syowa': 'Сёва', - 'Africa/Mogadishu': 'Могадишо', - 'Asia/Tehran': 'Тегеран', - 'Asia/Yerevan': 'Ереван', - 'Asia/Tbilisi': 'Тбилиси', - 'Asia/Muscat': 'Мускат', - 'Europe/Samara': 'Самара', - 'Indian/Mahe': 'Маэ', - 'Asia/Baku': 'Баку', - 'Indian/Mauritius': 'Маврикий', - 'Indian/Reunion': 'Воссоединение', - 'Asia/Dubai': 'Дубай', - 'Asia/Kabul': 'Кабул', - 'Asia/Ashgabat': 'Ашхабад', - 'Antarctica/Mawson': 'Моусон', - 'Asia/Aqtau': 'Актау', - 'Asia/Yekaterinburg': 'Екатеринбург', - 'Asia/Aqtobe': 'Актобе', - 'Asia/Dushanbe': 'Душанбе', - 'Asia/Tashkent': 'Ташкент', - 'Asia/Samarkand': 'Самарканд', - 'Asia/Qyzylorda': 'Кызылорда', - 'Asia/Oral': 'Оральный', - 'Asia/Karachi': 'Карачи', - 'Indian/Kerguelen': 'Кергелен', - 'Indian/Maldives': 'Мальдивы', - 'Asia/Kolkata': 'Калькутта', - 'Asia/Colombo': 'Коломбо', - 'Asia/Kathmandu': 'Катманду', - 'Antarctica/Vostok': 'Восток', - 'Asia/Almaty': 'Алматы', - 'Asia/Urumqi': 'Урумчи', - 'Asia/Thimphu': 'Тхимпху', - 'Asia/Omsk': 'Омск', - 'Asia/Dhaka': 'Дакка', - 'Indian/Chagos': 'Чагос', - 'Asia/Bishkek': 'Бишкек', - 'Asia/Rangoon': 'Рангун', - 'Indian/Cocos': 'кокосы', - 'Asia/Bangkok': 'Бангкок', - 'Asia/Hovd': 'Ховд', - 'Asia/Novokuznetsk': 'Новокузнецк', - 'Asia/Vientiane': 'Вьентьян', - 'Asia/Krasnoyarsk': 'Красноярск', - 'Antarctica/Davis': 'Дэвис', - 'Asia/Novosibirsk': 'Новосибирск', - 'Asia/Phnom_Penh': 'Пномпень', - 'Asia/Pontianak': 'Понтианак', - 'Asia/Jakarta': 'Джакарта', - 'Asia/Ho_Chi_Minh': 'Хо Ши Мин', - 'Indian/Christmas': 'Рождество', - 'Asia/Manila': 'Манила', - 'Asia/Makassar': 'Макассар', - 'Asia/Macau': 'Макао', - 'Asia/Kuala_Lumpur': 'Куала-Лумпур', - 'Asia/Singapore': 'Сингапур', - 'Asia/Shanghai': 'Шанхай', - 'Asia/Irkutsk': 'Иркутск', - 'Asia/Kuching': 'Кучинг', - 'Asia/Hong_Kong': 'Гонконг', - 'Australia/Perth': 'Перт', - 'Asia/Taipei': 'Тайбэй', - 'Asia/Brunei': 'Бруней', - 'Asia/Choibalsan': 'Чойбалсан', - 'Asia/Ulaanbaatar': 'Улан-Батор', - 'Australia/Eucla': 'Евкла', - 'Asia/Yakutsk': 'Якутск', - 'Asia/Dili': 'Дили', - 'Pacific/Palau': 'Палау', - 'Asia/Jayapura': 'Джаяпура', - 'Asia/Seoul': 'Сеул', - 'Asia/Pyongyang': 'Пхеньян', - 'Asia/Khandyga': 'Хандыга', - 'Asia/Chita': 'Чита', - 'Asia/Tokyo': 'Токио', - 'Australia/Darwin': 'Дарвин', - 'Pacific/Saipan': 'Сайпан', - 'Australia/Brisbane': 'Брисбен', - 'Pacific/Port_Moresby': 'Порт-Морсби', - 'Pacific/Chuuk': 'Чуук', - 'Antarctica/DumontDUrville': "Дюмон-д'Юрвиль", - 'Pacific/Guam': 'Гуам', - 'Australia/Lindeman': 'Линдеман', - 'Asia/Ust-Nera': 'Усть-Нера', - 'Asia/Vladivostok': 'Владивосток', - 'Australia/Broken_Hill': 'Брокен-Хилл', - 'Australia/Adelaide': 'Аделаида', - 'Asia/Sakhalin': 'Сахалин', - 'Pacific/Guadalcanal': 'Гуадалканал', - 'Pacific/Efate': 'Эфате', - 'Antarctica/Casey': 'Кейси', - 'Antarctica/Macquarie': 'Маккуори', - 'Pacific/Kosrae': 'Косрае', - 'Australia/Sydney': 'Сидней', - 'Pacific/Noumea': 'Нумеа', - 'Australia/Melbourne': 'Мельбурн', - 'Australia/Lord_Howe': 'Остров Лорд-Хау', - 'Australia/Hobart': 'Хобарт', - 'Pacific/Pohnpei': 'Понпеи', - 'Australia/Currie': 'Карри', - 'Asia/Srednekolymsk': 'Среднеколымск', - 'Asia/Magadan': 'Магадан', - 'Pacific/Kwajalein': 'Кваджалейн', - 'Pacific/Majuro': 'Маджуро', - 'Pacific/Funafuti': 'Фунафути', - 'Asia/Anadyr': 'Анадырь', - 'Pacific/Nauru': 'Науру', - 'Asia/Kamchatka': 'Камчатка', - 'Pacific/Fiji': 'Фиджи', - 'Pacific/Norfolk': 'Норфолк', - 'Pacific/Tarawa': 'Тарава', - 'Pacific/Wallis': 'Уоллис', - 'Pacific/Wake': 'Будить', - 'Pacific/Tongatapu': 'Тонгатапу', - 'Antarctica/McMurdo': 'МакМердо', - 'Pacific/Enderbury': 'Эндербери', - 'Pacific/Fakaofo': 'Факаофо', - 'Pacific/Auckland': 'Окленд', - 'Pacific/Chatham': 'Чатем', - 'Pacific/Kiritimati': 'Киритимати', - 'Pacific/Apia': 'Апиа', -}; diff --git a/lib/ui/pages/server_storage/storage_card.dart b/lib/ui/pages/server_storage/storage_card.dart deleted file mode 100644 index 683fa6a3..00000000 --- a/lib/ui/pages/server_storage/storage_card.dart +++ /dev/null @@ -1,101 +0,0 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:easy_localization/easy_localization.dart'; -import 'package:flutter/material.dart'; -import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart'; -import 'package:selfprivacy/logic/models/disk_status.dart'; -import 'package:selfprivacy/logic/models/state_types.dart'; -import 'package:selfprivacy/ui/atoms/masks/icon_status_mask.dart'; -import 'package:selfprivacy/ui/organisms/storage_list_items/server_storage_list_item.dart'; -import 'package:selfprivacy/ui/router/router.dart'; - -class StorageCard extends StatelessWidget { - const StorageCard({ - required this.diskStatus, - super.key, - }); - - final DiskStatus diskStatus; - - @override - Widget build(final BuildContext context) { - final List sections = []; - for (final DiskVolume volume in diskStatus.diskVolumes) { - sections.add( - const SizedBox(height: 16), - ); - sections.add( - ServerStorageListItem( - volume: volume, - dense: true, - showIcon: false, - ), - ); - } - - StateType state = context.watch().state - is ServerInstallationFinished - ? StateType.stable - : StateType.uninitialized; - - if (state == StateType.stable && !diskStatus.isDiskOkay) { - state = StateType.error; - } - - return Card( - clipBehavior: Clip.antiAlias, - child: InkResponse( - highlightShape: BoxShape.rectangle, - - /// TODO: when 'isEmpty' replace with a skeleton - onTap: () => diskStatus.diskVolumes.isEmpty - ? null - : context.pushRoute(ServerStorageRoute(diskStatus: diskStatus)), - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'storage.card_title'.tr(), - style: Theme.of(context).textTheme.titleLarge, - ), - if (state != StateType.uninitialized) - Text( - diskStatus.isDiskOkay - ? 'storage.status_ok'.tr() - : 'storage.status_error'.tr(), - style: Theme.of(context).textTheme.bodyLarge, - ), - ], - ), - ), - if (state != StateType.uninitialized) - IconStatusMask( - status: state, - icon: Icon( - diskStatus.isDiskOkay - ? Icons.check_circle_outline - : Icons.error_outline, - size: 24, - color: Colors.white, - ), - ), - ], - ), - ...sections, - const SizedBox(height: 8), - ], - ), - ), - ), - ); - } -} diff --git a/lib/utils/fake_data.dart b/lib/utils/fake_data.dart index ab2079d8..70f80acd 100644 --- a/lib/utils/fake_data.dart +++ b/lib/utils/fake_data.dart @@ -1,5 +1,8 @@ import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/desired_dns_record.dart'; +import 'package:selfprivacy/logic/models/disk_size.dart'; +import 'package:selfprivacy/logic/models/disk_status.dart'; import 'package:selfprivacy/logic/models/json/api_token.dart'; +import 'package:selfprivacy/logic/models/server_metadata.dart'; /// Fake data collections to fill skeletons class FakeSelfPrivacyData { @@ -41,4 +44,18 @@ class FakeSelfPrivacyData { isCaller: false, date: DateTime.now(), ); + + static final DiskVolume fakeDiskVolume = DiskVolume( + name: 'fake_volume_name', + isResizable: false, + root: false, + sizeTotal: const DiskSize(byte: 350000000), + sizeUsed: const DiskSize(byte: 100000000), + ); + + static final ServerMetadataEntity fakeServerMetadataEntity = + ServerMetadataEntity( + trId: 'some_long_id', + value: 'some_interesting_value', + ); }