diff --git a/assets/translations/en.json b/assets/translations/en.json index b862cba6..f5194cdd 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -606,5 +606,16 @@ "reset_onboarding": "Reset onboarding switch", "reset_onboarding_description": "Reset onboarding switch to show onboarding screen again", "cubit_statuses": "Cubit loading statuses" + }, + "countries": { + "germany": "Germany", + "netherlands": "Netherlands", + "singapore": "Singapore", + "united_kingdom": "United Kingdom", + "canada": "Canada", + "india": "India", + "australia": "Australia", + "united_states": "United States", + "finland": "Finland" } -} +} \ No newline at end of file diff --git a/lib/logic/models/json/digital_ocean_server_info.dart b/lib/logic/models/json/digital_ocean_server_info.dart index 811536e4..dbe41f66 100644 --- a/lib/logic/models/json/digital_ocean_server_info.dart +++ b/lib/logic/models/json/digital_ocean_server_info.dart @@ -65,14 +65,59 @@ class DigitalOceanLocation { emoji = '🇮🇳'; break; + case 'syd': + emoji = '🇦🇺'; + break; + case 'nyc': case 'sfo': emoji = '🇺🇸'; break; } - return emoji; } + + String get countryDisplayKey { + String displayKey = 'countries.'; + switch (slug.substring(0, 3)) { + case 'fra': + displayKey += 'germany'; + break; + + case 'ams': + displayKey += 'netherlands'; + break; + + case 'sgp': + displayKey += 'singapore'; + break; + + case 'lon': + displayKey += 'united_kingdom'; + break; + + case 'tor': + displayKey += 'canada'; + break; + + case 'blr': + displayKey += 'india'; + break; + + case 'syd': + displayKey += 'australia'; + break; + + case 'nyc': + case 'sfo': + displayKey += 'united_states'; + break; + + default: + displayKey = slug; + } + return displayKey; + } } @JsonSerializable() diff --git a/lib/logic/models/json/hetzner_server_info.dart b/lib/logic/models/json/hetzner_server_info.dart index 122d0288..a0559de6 100644 --- a/lib/logic/models/json/hetzner_server_info.dart +++ b/lib/logic/models/json/hetzner_server_info.dart @@ -155,6 +155,27 @@ class HetznerLocation { } return emoji; } + + String get countryDisplayKey { + String displayKey = 'countries.'; + switch (country.substring(0, 2)) { + case 'DE': + displayKey += 'germany'; + break; + + case 'FI': + displayKey += 'finland'; + break; + + case 'US': + displayKey += 'united_states'; + break; + + default: + displayKey = country; + } + return displayKey; + } } /// A Volume is a highly-available, scalable, and SSD-based block storage for Servers. diff --git a/lib/logic/models/server_provider_location.dart b/lib/logic/models/server_provider_location.dart index 688eb972..09188651 100644 --- a/lib/logic/models/server_provider_location.dart +++ b/lib/logic/models/server_provider_location.dart @@ -2,12 +2,14 @@ class ServerProviderLocation { ServerProviderLocation({ required this.title, required this.identifier, + required this.countryDisplayKey, this.description, this.flag = '', }); final String title; final String identifier; + final String countryDisplayKey; final String? description; final String flag; } diff --git a/lib/logic/providers/server_providers/digital_ocean.dart b/lib/logic/providers/server_providers/digital_ocean.dart index 207da253..bc372ebc 100644 --- a/lib/logic/providers/server_providers/digital_ocean.dart +++ b/lib/logic/providers/server_providers/digital_ocean.dart @@ -438,6 +438,7 @@ class DigitalOceanServerProvider extends ServerProvider { description: rawLocation.name, flag: rawLocation.flag, identifier: rawLocation.slug, + countryDisplayKey: rawLocation.countryDisplayKey, ); } catch (e) { continue; diff --git a/lib/logic/providers/server_providers/hetzner.dart b/lib/logic/providers/server_providers/hetzner.dart index 5386cebb..67037610 100644 --- a/lib/logic/providers/server_providers/hetzner.dart +++ b/lib/logic/providers/server_providers/hetzner.dart @@ -156,6 +156,7 @@ class HetznerServerProvider extends ServerProvider { description: server.location.description, flag: server.location.flag, identifier: server.location.name, + countryDisplayKey: server.location.countryDisplayKey, ), ), ); @@ -456,6 +457,7 @@ class HetznerServerProvider extends ServerProvider { description: rawLocation.description, flag: rawLocation.flag, identifier: rawLocation.name, + countryDisplayKey: rawLocation.countryDisplayKey, ); } catch (e) { continue; diff --git a/lib/ui/pages/backups/backup_details.dart b/lib/ui/pages/backups/backup_details.dart index a5650bbb..2373d8dd 100644 --- a/lib/ui/pages/backups/backup_details.dart +++ b/lib/ui/pages/backups/backup_details.dart @@ -38,8 +38,14 @@ class BackupDetailsPage extends StatelessWidget { : StateType.uninitialized; final bool preventActions = backupsState.preventActions; final List backups = backupsState.backups; - final List services = - context.watch().state.servicesThatCanBeBackedUp; + final List services = context + .watch() + .state + .servicesThatCanBeBackedUp + .where( + (final service) => service.isEnabled, + ) + .toList(); final Duration? autobackupPeriod = backupsState.autobackupPeriod; final List backupJobs = context .watch() diff --git a/lib/ui/pages/backups/create_backups_modal.dart b/lib/ui/pages/backups/create_backups_modal.dart index f78e1075..455976a7 100644 --- a/lib/ui/pages/backups/create_backups_modal.dart +++ b/lib/ui/pages/backups/create_backups_modal.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:selfprivacy/logic/bloc/backups/backups_bloc.dart'; import 'package:selfprivacy/logic/bloc/server_jobs/server_jobs_bloc.dart'; +import 'package:selfprivacy/logic/bloc/volumes/volumes_bloc.dart'; import 'package:selfprivacy/logic/models/json/server_job.dart'; import 'package:selfprivacy/logic/models/service.dart'; @@ -103,6 +104,29 @@ class _CreateBackupsModalState extends State { ...widget.services.map( (final Service service) { final bool busy = busyServices.contains(service.id); + final List descriptionWidgets = []; + if (busy) { + descriptionWidgets.add(Text('backup.service_busy'.tr())); + } else { + descriptionWidgets.add( + Text( + 'service_page.uses'.tr( + namedArgs: { + 'usage': service.storageUsage.used.toString(), + 'volume': context + .read() + .state + .getVolume(service.storageUsage.volume ?? '') + .displayName, + }, + ), + style: Theme.of(context).textTheme.labelMedium, + ), + ); + descriptionWidgets.add( + Text(service.backupDescription), + ); + } return CheckboxListTile.adaptive( onChanged: !busy ? (final bool? value) { @@ -122,8 +146,9 @@ class _CreateBackupsModalState extends State { title: Text( service.displayName, ), - subtitle: Text( - busy ? 'backup.service_busy'.tr() : service.backupDescription, + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: descriptionWidgets, ), secondary: SvgPicture.string( service.svgIcon, diff --git a/lib/ui/pages/setup/initializing/server_type_picker.dart b/lib/ui/pages/setup/initializing/server_type_picker.dart index 6fb09f4b..bdcabe92 100644 --- a/lib/ui/pages/setup/initializing/server_type_picker.dart +++ b/lib/ui/pages/setup/initializing/server_type_picker.dart @@ -120,6 +120,14 @@ class SelectLocationPage extends StatelessWidget { .titleMedium, ), const SizedBox(height: 8), + Text( + location.countryDisplayKey.tr(), + style: Theme.of(context) + .textTheme + .bodyMedium, + ), + if (location.description != null) + const SizedBox(height: 4), if (location.description != null) Text( location.description!,