From 2ac8e4366b93e2c887f4c8d63971185d6d628af1 Mon Sep 17 00:00:00 2001 From: NaiJi Date: Mon, 6 Jun 2022 01:40:34 +0300 Subject: [PATCH] Linting! Co-authored-by: Inex Code --- analysis_options.yaml | 1 - lib/config/bloc_config.dart | 50 +- lib/config/bloc_observer.dart | 8 +- lib/config/brand_colors.dart | 2 - lib/config/localization.dart | 16 +- lib/logic/api_maps/api_map.dart | 32 +- lib/logic/api_maps/backblaze.dart | 26 +- lib/logic/api_maps/cloudflare.dart | 49 +- lib/logic/api_maps/hetzner.dart | 21 +- lib/logic/api_maps/server.dart | 166 ++-- .../authentication_dependend_cubit.dart | 2 - .../app_settings/app_settings_cubit.dart | 12 +- .../app_settings/app_settings_state.dart | 7 +- lib/logic/cubit/backups/backups_cubit.dart | 122 +-- lib/logic/cubit/backups/backups_state.dart | 2 - lib/logic/cubit/devices/devices_cubit.dart | 12 +- lib/logic/cubit/devices/devices_state.dart | 25 +- .../cubit/dns_records/dns_records_cubit.dart | 70 +- .../cubit/dns_records/dns_records_state.dart | 28 +- .../forms/factories/field_cubit_factory.dart | 30 +- .../initializing/backblaze_form_cubit.dart | 2 - .../initializing/cloudflare_form_cubit.dart | 6 +- .../initializing/hetzner_form_cubit.dart | 6 +- .../initializing/root_user_form_cubit.dart | 6 +- .../recovery_device_form_cubit.dart | 9 +- .../recovery_domain_form_cubit.dart | 13 +- .../cubit/forms/user/ssh_form_cubit.dart | 21 +- .../cubit/forms/user/user_form_cubit.dart | 5 +- .../cubit/forms/validations/validations.dart | 17 +- .../hetzner_metrics_repository.dart | 10 +- .../hetzner_metrics_state.dart | 2 - lib/logic/cubit/jobs/jobs_cubit.dart | 14 +- lib/logic/cubit/jobs/jobs_state.dart | 5 +- .../cubit/providers/providers_state.dart | 17 +- .../recovery_key/recovery_key_state.dart | 17 +- .../server_detailed_info_state.dart | 3 - .../server_installation_repository.dart | 112 ++- .../server_installation_state.dart | 28 +- lib/logic/cubit/services/services_state.dart | 2 - lib/logic/cubit/users/users_cubit.dart | 235 ++++-- lib/logic/cubit/users/users_state.dart | 20 +- lib/logic/get_it/api_config.dart | 2 - lib/logic/get_it/console.dart | 2 - lib/logic/models/hive/user.dart | 5 +- lib/logic/models/hive/user.g.dart | 2 - lib/logic/models/job.dart | 2 - .../models/json/auto_upgrade_settings.dart | 2 - .../models/json/hetzner_server_info.dart | 10 +- .../models/json/recovery_token_status.dart | 3 - .../models/json/server_configurations.dart | 3 - lib/logic/models/message.dart | 8 +- lib/logic/models/provider.dart | 2 - lib/logic/models/server_basic_info.dart | 4 - lib/logic/models/timezone_settings.dart | 7 +- lib/main.dart | 31 +- lib/theming/factory/app_theme_factory.dart | 22 +- .../action_button/action_button.dart | 2 +- .../brand_bottom_sheet.dart | 2 - .../components/brand_button/brand_button.dart | 51 +- .../components/brand_cards/brand_cards.dart | 11 +- .../brand_divider/brand_divider.dart | 10 +- .../components/brand_header/brand_header.dart | 40 +- .../brand_hero_screen/brand_hero_screen.dart | 78 +- .../components/brand_loader/brand_loader.dart | 20 +- .../components/brand_radio/brand_radio.dart | 46 +- .../brand_radio_tile/brand_radio_tile.dart | 32 +- .../brand_span_button/brand_span_button.dart | 16 +- .../components/brand_switch/brand_switch.dart | 10 +- .../brand_tab_bar/brand_tab_bar.dart | 39 +- lib/ui/components/brand_text/brand_text.dart | 36 +- .../components/brand_timer/brand_timer.dart | 17 +- .../icon_status_mask/icon_status_mask.dart | 2 +- .../components/jobs_content/jobs_content.dart | 191 ++--- .../not_ready_card/not_ready_card.dart | 70 +- lib/ui/components/one_page/one_page.dart | 55 +- .../components/pre_styled_buttons/close.dart | 20 +- .../components/pre_styled_buttons/flash.dart | 57 +- .../pre_styled_buttons/flash_fab.dart | 32 +- .../pre_styled_buttons.dart | 2 +- .../components/progress_bar/progress_bar.dart | 46 +- .../components/switch_block/switch_bloc.dart | 39 +- .../pages/backup_details/backup_details.dart | 83 +- lib/ui/pages/devices/devices.dart | 102 +-- lib/ui/pages/devices/new_device.dart | 121 +-- lib/ui/pages/dns_details/dns_details.dart | 10 +- lib/ui/pages/more/about/about.dart | 24 +- .../pages/more/app_settings/app_setting.dart | 151 ++-- lib/ui/pages/more/console/console.dart | 129 +-- lib/ui/pages/more/info/info.dart | 38 +- lib/ui/pages/more/more.dart | 14 +- lib/ui/pages/onboarding/onboarding.dart | 176 ++-- lib/ui/pages/providers/providers.dart | 26 +- lib/ui/pages/recovery_key/recovery_key.dart | 104 +-- .../recovery_key/recovery_key_receiving.dart | 72 +- lib/ui/pages/root_route.dart | 3 +- lib/ui/pages/server_details/chart.dart | 42 +- lib/ui/pages/server_details/cpu_chart.dart | 135 ++-- lib/ui/pages/server_details/header.dart | 87 +- .../pages/server_details/network_charts.dart | 179 ++--- .../server_details/server_details_screen.dart | 25 +- .../pages/server_details/server_settings.dart | 76 +- lib/ui/pages/server_details/text_details.dart | 62 +- .../server_details/time_zone/time_zone.dart | 135 ++-- lib/ui/pages/services/services.dart | 370 ++++----- lib/ui/pages/setup/initializing.dart | 757 +++++++++--------- .../recovering/recover_by_new_device_key.dart | 53 +- .../recovering/recover_by_old_token.dart | 71 +- .../recovering/recover_by_recovery_key.dart | 8 +- .../recovery_confirm_backblaze.dart | 88 +- .../recovery_confirm_cloudflare.dart | 81 +- .../recovering/recovery_confirm_server.dart | 468 +++++------ .../recovery_hentzner_connected.dart | 33 +- .../recovering/recovery_method_select.dart | 190 ++--- .../setup/recovering/recovery_routing.dart | 30 +- lib/ui/pages/ssh_keys/new_ssh_key.dart | 126 +-- lib/ui/pages/ssh_keys/ssh_keys.dart | 215 ++--- lib/ui/pages/users/add_user_fab.dart | 35 +- lib/ui/pages/users/empty.dart | 48 +- lib/ui/pages/users/new_user.dart | 152 ++-- lib/ui/pages/users/user.dart | 80 +- lib/ui/pages/users/user_details.dart | 140 ++-- lib/ui/pages/users/users.dart | 61 +- lib/utils/color_utils.dart | 11 +- lib/utils/extensions/duration.dart | 29 +- lib/utils/extensions/elevation_extension.dart | 30 +- lib/utils/password_generator.dart | 37 +- lib/utils/route_transitions/basic.dart | 9 +- pubspec.lock | 16 +- 128 files changed, 3773 insertions(+), 3419 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index 4aab61a8..3ab00ee3 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -36,7 +36,6 @@ linter: always_declare_return_types: true always_put_required_named_parameters_first: true always_put_control_body_on_new_line: true - always_specify_types: true avoid_escaping_inner_quotes: true avoid_setters_without_getters: true eol_at_end_of_file: true diff --git a/lib/config/bloc_config.dart b/lib/config/bloc_config.dart index f800a4e2..3946d3b9 100644 --- a/lib/config/bloc_config.dart +++ b/lib/config/bloc_config.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:selfprivacy/logic/cubit/devices/devices_cubit.dart'; @@ -20,14 +18,14 @@ class BlocAndProviderConfig extends StatelessWidget { @override Widget build(final BuildContext context) { - const bool isDark = false; - final ServerInstallationCubit serverInstallationCubit = ServerInstallationCubit()..load(); - final UsersCubit usersCubit = UsersCubit(serverInstallationCubit); - final ServicesCubit servicesCubit = ServicesCubit(serverInstallationCubit); - final BackupsCubit backupsCubit = BackupsCubit(serverInstallationCubit); - final DnsRecordsCubit dnsRecordsCubit = DnsRecordsCubit(serverInstallationCubit); - final RecoveryKeyCubit recoveryKeyCubit = RecoveryKeyCubit(serverInstallationCubit); - final ApiDevicesCubit apiDevicesCubit = ApiDevicesCubit(serverInstallationCubit); + const isDark = false; + final serverInstallationCubit = ServerInstallationCubit()..load(); + final usersCubit = UsersCubit(serverInstallationCubit); + final servicesCubit = ServicesCubit(serverInstallationCubit); + final backupsCubit = BackupsCubit(serverInstallationCubit); + final dnsRecordsCubit = DnsRecordsCubit(serverInstallationCubit); + final recoveryKeyCubit = RecoveryKeyCubit(serverInstallationCubit); + final apiDevicesCubit = ApiDevicesCubit(serverInstallationCubit); return MultiProvider( providers: [ BlocProvider( @@ -36,14 +34,32 @@ class BlocAndProviderConfig extends StatelessWidget { isOnboardingShowing: true, )..load(), ), - BlocProvider(create: (final _) => serverInstallationCubit, lazy: false), + BlocProvider( + create: (final _) => serverInstallationCubit, + lazy: false, + ), BlocProvider(create: (final _) => ProvidersCubit()), - BlocProvider(create: (final _) => usersCubit..load(), lazy: false), - BlocProvider(create: (final _) => servicesCubit..load(), lazy: false), - BlocProvider(create: (final _) => backupsCubit..load(), lazy: false), - BlocProvider(create: (final _) => dnsRecordsCubit..load()), - BlocProvider(create: (final _) => recoveryKeyCubit..load()), - BlocProvider(create: (final _) => apiDevicesCubit..load()), + BlocProvider( + create: (final _) => usersCubit..load(), + lazy: false, + ), + BlocProvider( + create: (final _) => servicesCubit..load(), + lazy: false, + ), + BlocProvider( + create: (final _) => backupsCubit..load(), + lazy: false, + ), + BlocProvider( + create: (final _) => dnsRecordsCubit..load(), + ), + BlocProvider( + create: (final _) => recoveryKeyCubit..load(), + ), + BlocProvider( + create: (final _) => apiDevicesCubit..load(), + ), BlocProvider( create: (final _) => JobsCubit(usersCubit: usersCubit, servicesCubit: servicesCubit), diff --git a/lib/config/bloc_observer.dart b/lib/config/bloc_observer.dart index 56fa5a32..e68923c9 100644 --- a/lib/config/bloc_observer.dart +++ b/lib/config/bloc_observer.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:selfprivacy/ui/components/error/error.dart'; @@ -11,7 +9,11 @@ class SimpleBlocObserver extends BlocObserver { SimpleBlocObserver(); @override - void onError(final BlocBase bloc, final Object error, final StackTrace stackTrace) { + void onError( + final BlocBase bloc, + final Object error, + final StackTrace stackTrace, + ) { final NavigatorState navigator = getIt.get().navigator!; navigator.push( diff --git a/lib/config/brand_colors.dart b/lib/config/brand_colors.dart index f6866c2d..15d1433a 100644 --- a/lib/config/brand_colors.dart +++ b/lib/config/brand_colors.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:flutter/material.dart'; class BrandColors { diff --git a/lib/config/localization.dart b/lib/config/localization.dart index e3f6d8d2..b8356950 100644 --- a/lib/config/localization.dart +++ b/lib/config/localization.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; @@ -12,11 +10,11 @@ class Localization extends StatelessWidget { final Widget? child; @override Widget build(final BuildContext context) => EasyLocalization( - supportedLocales: const [Locale('ru'), Locale('en')], - path: 'assets/translations', - fallbackLocale: const Locale('en'), - saveLocale: false, - useOnlyLangCode: true, - child: child!, - ); + supportedLocales: const [Locale('ru'), Locale('en')], + path: 'assets/translations', + fallbackLocale: const Locale('en'), + saveLocale: false, + useOnlyLangCode: true, + child: child!, + ); } diff --git a/lib/logic/api_maps/api_map.dart b/lib/logic/api_maps/api_map.dart index ce1a54b2..007bfd98 100644 --- a/lib/logic/api_maps/api_map.dart +++ b/lib/logic/api_maps/api_map.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'dart:async'; import 'dart:developer'; import 'dart:io'; @@ -20,19 +18,24 @@ abstract class ApiMap { (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (final HttpClient client) { client.badCertificateCallback = - (final X509Certificate cert, final String host, final int port) => true; + (final X509Certificate cert, final String host, final int port) => + true; return client; }; - dio.interceptors.add(InterceptorsWrapper(onError: (final DioError e, final ErrorInterceptorHandler handler) { - print(e.requestOptions.path); - print(e.requestOptions.data); + dio.interceptors.add( + InterceptorsWrapper( + onError: (final DioError e, final ErrorInterceptorHandler handler) { + print(e.requestOptions.path); + print(e.requestOptions.data); - print(e.message); - print(e.response); + print(e.message); + print(e.response); - return handler.next(e); - },),); + return handler.next(e); + }, + ), + ); return dio; } @@ -56,7 +59,7 @@ class ConsoleInterceptor extends InterceptorsWrapper { } @override - Future onRequest( + Future onRequest( final RequestOptions options, final RequestInterceptorHandler handler, ) async { @@ -70,7 +73,7 @@ class ConsoleInterceptor extends InterceptorsWrapper { } @override - Future onResponse( + Future onResponse( final Response response, final ResponseInterceptorHandler handler, ) async { @@ -87,7 +90,10 @@ class ConsoleInterceptor extends InterceptorsWrapper { } @override - Future onError(final DioError err, final ErrorInterceptorHandler handler) async { + Future onError( + final DioError err, + final ErrorInterceptorHandler handler, + ) async { final Response? response = err.response; log(err.toString()); addMessage( diff --git a/lib/logic/api_maps/backblaze.dart b/lib/logic/api_maps/backblaze.dart index 0957df2d..f6626a26 100644 --- a/lib/logic/api_maps/backblaze.dart +++ b/lib/logic/api_maps/backblaze.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'dart:io'; import 'package:dio/dio.dart'; @@ -15,8 +13,10 @@ class BackblazeApiAuth { } class BackblazeApplicationKey { - BackblazeApplicationKey( - {required this.applicationKeyId, required this.applicationKey,}); + BackblazeApplicationKey({ + required this.applicationKeyId, + required this.applicationKey, + }); final String applicationKeyId; final String applicationKey; @@ -29,7 +29,8 @@ class BackblazeApi extends ApiMap { BaseOptions get options { final BaseOptions options = BaseOptions(baseUrl: rootAddress); if (isWithToken) { - final BackblazeCredential? backblazeCredential = getIt().backblazeCredential; + final BackblazeCredential? backblazeCredential = + getIt().backblazeCredential; final String token = backblazeCredential!.applicationKey; options.headers = {'Authorization': 'Basic $token'}; } @@ -48,12 +49,15 @@ class BackblazeApi extends ApiMap { Future getAuthorizationToken() async { final Dio client = await getClient(); - final BackblazeCredential? backblazeCredential = getIt().backblazeCredential; + final BackblazeCredential? backblazeCredential = + getIt().backblazeCredential; if (backblazeCredential == null) { throw Exception('Backblaze credential is null'); } final String encodedApiKey = encodedBackblazeKey( - backblazeCredential.keyId, backblazeCredential.applicationKey,); + backblazeCredential.keyId, + backblazeCredential.applicationKey, + ); final Response response = await client.get( 'b2_authorize_account', options: Options(headers: {'Authorization': 'Basic $encodedApiKey'}), @@ -89,7 +93,8 @@ class BackblazeApi extends ApiMap { // Create bucket Future createBucket(final String bucketName) async { final BackblazeApiAuth auth = await getAuthorizationToken(); - final BackblazeCredential? backblazeCredential = getIt().backblazeCredential; + final BackblazeCredential? backblazeCredential = + getIt().backblazeCredential; final Dio client = await getClient(); client.options.baseUrl = auth.apiUrl; final Response response = await client.post( @@ -138,8 +143,9 @@ class BackblazeApi extends ApiMap { close(client); if (response.statusCode == HttpStatus.ok) { return BackblazeApplicationKey( - applicationKeyId: response.data['applicationKeyId'], - applicationKey: response.data['applicationKey'],); + applicationKeyId: response.data['applicationKeyId'], + applicationKey: response.data['applicationKey'], + ); } else { throw Exception('code: ${response.statusCode}'); } diff --git a/lib/logic/api_maps/cloudflare.dart b/lib/logic/api_maps/cloudflare.dart index 29fb2c46..9141d5fe 100644 --- a/lib/logic/api_maps/cloudflare.dart +++ b/lib/logic/api_maps/cloudflare.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'dart:io'; import 'package:dio/dio.dart'; @@ -14,7 +12,6 @@ class DomainNotFoundException implements Exception { } class CloudflareApi extends ApiMap { - CloudflareApi({ this.hasLogger = false, this.isWithToken = true, @@ -50,11 +47,14 @@ class CloudflareApi extends ApiMap { String rootAddress = 'https://api.cloudflare.com/client/v4'; Future isValid(final String token) async { - validateStatus = (final status) => status == HttpStatus.ok || status == HttpStatus.unauthorized; + validateStatus = (final status) => + status == HttpStatus.ok || status == HttpStatus.unauthorized; final Dio client = await getClient(); - final Response response = await client.get('/user/tokens/verify', - options: Options(headers: {'Authorization': 'Bearer $token'}),); + final Response response = await client.get( + '/user/tokens/verify', + options: Options(headers: {'Authorization': 'Bearer $token'}), + ); close(client); @@ -68,7 +68,8 @@ class CloudflareApi extends ApiMap { } Future getZoneId(final String domain) async { - validateStatus = (final status) => status == HttpStatus.ok || status == HttpStatus.forbidden; + validateStatus = (final status) => + status == HttpStatus.ok || status == HttpStatus.forbidden; final Dio client = await getClient(); final Response response = await client.get( '/zones', @@ -127,13 +128,15 @@ class CloudflareApi extends ApiMap { for (final record in records) { if (record['zone_name'] == domainName) { - allRecords.add(DnsRecord( - name: record['name'], - type: record['type'], - content: record['content'], - ttl: record['ttl'], - proxied: record['proxied'], - ),); + allRecords.add( + DnsRecord( + name: record['name'], + type: record['type'], + content: record['content'], + ttl: record['ttl'], + proxied: record['proxied'], + ), + ); } } @@ -169,16 +172,22 @@ class CloudflareApi extends ApiMap { } } - List projectDnsRecords(final String? domainName, final String? ip4) { - final DnsRecord domainA = DnsRecord(type: 'A', name: domainName, content: ip4); + List projectDnsRecords( + final String? domainName, + final String? ip4, + ) { + final DnsRecord domainA = + DnsRecord(type: 'A', name: domainName, content: ip4); final DnsRecord mx = DnsRecord(type: 'MX', name: '@', content: domainName); final DnsRecord apiA = DnsRecord(type: 'A', name: 'api', content: ip4); final DnsRecord cloudA = DnsRecord(type: 'A', name: 'cloud', content: ip4); final DnsRecord gitA = DnsRecord(type: 'A', name: 'git', content: ip4); final DnsRecord meetA = DnsRecord(type: 'A', name: 'meet', content: ip4); - final DnsRecord passwordA = DnsRecord(type: 'A', name: 'password', content: ip4); - final DnsRecord socialA = DnsRecord(type: 'A', name: 'social', content: ip4); + final DnsRecord passwordA = + DnsRecord(type: 'A', name: 'password', content: ip4); + final DnsRecord socialA = + DnsRecord(type: 'A', name: 'social', content: ip4); final DnsRecord vpn = DnsRecord(type: 'A', name: 'vpn', content: ip4); final DnsRecord txt1 = DnsRecord( @@ -211,7 +220,9 @@ class CloudflareApi extends ApiMap { } Future setDkim( - final String dkimRecordString, final ServerDomain cloudFlareDomain,) async { + final String dkimRecordString, + final ServerDomain cloudFlareDomain, + ) async { final String domainZoneId = cloudFlareDomain.zoneId; final String url = '$rootAddress/zones/$domainZoneId/dns_records'; diff --git a/lib/logic/api_maps/hetzner.dart b/lib/logic/api_maps/hetzner.dart index 3901cb40..54d60c21 100644 --- a/lib/logic/api_maps/hetzner.dart +++ b/lib/logic/api_maps/hetzner.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'dart:convert'; import 'dart:io'; @@ -12,7 +10,6 @@ import 'package:selfprivacy/logic/models/hive/user.dart'; import 'package:selfprivacy/utils/password_generator.dart'; class HetznerApi extends ApiMap { - HetznerApi({this.hasLogger = false, this.isWithToken = true}); @override bool hasLogger; @@ -39,7 +36,8 @@ class HetznerApi extends ApiMap { String rootAddress = 'https://api.hetzner.cloud/v1'; Future isValid(final String token) async { - validateStatus = (final int? status) => status == HttpStatus.ok || status == HttpStatus.unauthorized; + validateStatus = (final int? status) => + status == HttpStatus.ok || status == HttpStatus.unauthorized; final Dio client = await getClient(); final Response response = await client.get( '/servers', @@ -201,8 +199,12 @@ class HetznerApi extends ApiMap { } Future> getMetrics( - final DateTime start, final DateTime end, final String type,) async { - final ServerHostingDetails? hetznerServer = getIt().serverDetails; + final DateTime start, + final DateTime end, + final String type, + ) async { + final ServerHostingDetails? hetznerServer = + getIt().serverDetails; final Dio client = await getClient(); final Map queryParameters = { @@ -219,7 +221,8 @@ class HetznerApi extends ApiMap { } Future getInfo() async { - final ServerHostingDetails? hetznerServer = getIt().serverDetails; + final ServerHostingDetails? hetznerServer = + getIt().serverDetails; final Dio client = await getClient(); final Response response = await client.get('/servers/${hetznerServer!.id}'); close(client); @@ -233,6 +236,7 @@ class HetznerApi extends ApiMap { close(client); return (response.data!['servers'] as List) + // ignore: unnecessary_lambdas .map((final e) => HetznerServerInfo.fromJson(e)) .toList(); } @@ -241,7 +245,8 @@ class HetznerApi extends ApiMap { required final String ip4, required final String domainName, }) async { - final ServerHostingDetails? hetznerServer = getIt().serverDetails; + final ServerHostingDetails? hetznerServer = + getIt().serverDetails; final Dio client = await getClient(); await client.post( '/servers/${hetznerServer!.id}/actions/change_dns_ptr', diff --git a/lib/logic/api_maps/server.dart b/lib/logic/api_maps/server.dart index 522ee528..bdd544f7 100644 --- a/lib/logic/api_maps/server.dart +++ b/lib/logic/api_maps/server.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'dart:async'; import 'dart:convert'; import 'dart:io'; @@ -20,7 +18,6 @@ import 'package:selfprivacy/logic/models/timezone_settings.dart'; import 'package:selfprivacy/logic/api_maps/api_map.dart'; class ApiResponse { - ApiResponse({ required this.statusCode, required this.data, @@ -34,12 +31,12 @@ class ApiResponse { } class ServerApi extends ApiMap { - - ServerApi( - {this.hasLogger = false, - this.isWithToken = true, - this.overrideDomain, - this.customToken,}); + ServerApi({ + this.hasLogger = false, + this.isWithToken = true, + this.overrideDomain, + this.customToken, + }); @override bool hasLogger; @override @@ -52,13 +49,17 @@ class ServerApi extends ApiMap { BaseOptions options = BaseOptions(); if (isWithToken) { - final ServerDomain? cloudFlareDomain = getIt().serverDomain; + final ServerDomain? cloudFlareDomain = + getIt().serverDomain; final String domainName = cloudFlareDomain!.domainName; final String? apiToken = getIt().serverDetails?.apiToken; - options = BaseOptions(baseUrl: 'https://api.$domainName', headers: { - 'Authorization': 'Bearer $apiToken', - },); + options = BaseOptions( + baseUrl: 'https://api.$domainName', + headers: { + 'Authorization': 'Bearer $apiToken', + }, + ); } if (overrideDomain != null) { @@ -157,14 +158,18 @@ class ServerApi extends ApiMap { ); } - Future>> getUsersList({final withMainUser = false}) async { + Future>> getUsersList({ + final withMainUser = false, + }) async { final List res = []; Response response; final Dio client = await getClient(); try { - response = await client.get('/users', - queryParameters: withMainUser ? {'withMainUser': 'true'} : null,); + response = await client.get( + '/users', + queryParameters: withMainUser ? {'withMainUser': 'true'} : null, + ); for (final user in response.data) { res.add(user.toString()); } @@ -194,7 +199,10 @@ class ServerApi extends ApiMap { ); } - Future> addUserSshKey(final User user, final String sshKey) async { + Future> addUserSshKey( + final User user, + final String sshKey, + ) async { late Response response; final Dio client = await getClient(); @@ -259,7 +267,9 @@ class ServerApi extends ApiMap { final Dio client = await getClient(); try { response = await client.get('/services/ssh/keys/${user.login}'); - res = (response.data as List).map((final e) => e as String).toList(); + res = (response.data as List) + .map((final e) => e as String) + .toList(); } on DioError catch (e) { print(e.message); return ApiResponse>( @@ -290,7 +300,10 @@ class ServerApi extends ApiMap { ); } - Future> deleteUserSshKey(final User user, final String sshKey) async { + Future> deleteUserSshKey( + final User user, + final String sshKey, + ) async { Response response; final Dio client = await getClient(); @@ -360,7 +373,10 @@ class ServerApi extends ApiMap { return res; } - Future switchService(final ServiceTypes type, final bool needToTurnOn) async { + Future switchService( + final ServiceTypes type, + final bool needToTurnOn, + ) async { final Dio client = await getClient(); try { client.post( @@ -431,7 +447,7 @@ class ServerApi extends ApiMap { final Dio client = await getClient(); try { response = await client.get('/services/restic/backup/list'); - backups = response.data.map((final e) => Backup.fromJson(e)).toList(); + backups = response.data.map(Backup.fromJson).toList(); } on DioError catch (e) { print(e.message); } catch (e) { @@ -562,7 +578,9 @@ class ServerApi extends ApiMap { return settings; } - Future updateAutoUpgradeSettings(final AutoUpgradeSettings settings) async { + Future updateAutoUpgradeSettings( + final AutoUpgradeSettings settings, + ) async { final Dio client = await getClient(); try { await client.put( @@ -579,7 +597,8 @@ class ServerApi extends ApiMap { Future getServerTimezone() async { // I am not sure how to initialize TimeZoneSettings with default value... final Dio client = await getClient(); - final Response response = await client.get('/system/configuration/timezone'); + final Response response = + await client.get('/system/configuration/timezone'); close(client); return TimeZoneSettings.fromString(response.data); @@ -642,9 +661,10 @@ class ServerApi extends ApiMap { } on DioError catch (e) { print(e.message); return ApiResponse( - errorMessage: e.message, - statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, - data: const RecoveryKeyStatus(exists: false, valid: false),); + errorMessage: e.message, + statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, + data: const RecoveryKeyStatus(exists: false, valid: false), + ); } finally { close(client); } @@ -652,10 +672,11 @@ class ServerApi extends ApiMap { final int code = response.statusCode ?? HttpStatus.internalServerError; return ApiResponse( - statusCode: code, - data: response.data != null - ? RecoveryKeyStatus.fromJson(response.data) - : null,); + statusCode: code, + data: response.data != null + ? RecoveryKeyStatus.fromJson(response.data) + : null, + ); } Future> generateRecoveryToken( @@ -681,9 +702,10 @@ class ServerApi extends ApiMap { } on DioError catch (e) { print(e.message); return ApiResponse( - errorMessage: e.message, - statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, - data: '',); + errorMessage: e.message, + statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, + data: '', + ); } finally { close(client); } @@ -691,8 +713,9 @@ class ServerApi extends ApiMap { final int code = response.statusCode ?? HttpStatus.internalServerError; return ApiResponse( - statusCode: code, - data: response.data != null ? response.data['token'] : '',); + statusCode: code, + data: response.data != null ? response.data['token'] : '', + ); } Future> useRecoveryToken(final DeviceToken token) async { @@ -710,9 +733,10 @@ class ServerApi extends ApiMap { } on DioError catch (e) { print(e.message); return ApiResponse( - errorMessage: e.message, - statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, - data: '',); + errorMessage: e.message, + statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, + data: '', + ); } finally { client.close(); } @@ -720,8 +744,9 @@ class ServerApi extends ApiMap { final int code = response.statusCode ?? HttpStatus.internalServerError; return ApiResponse( - statusCode: code, - data: response.data != null ? response.data['token'] : '',); + statusCode: code, + data: response.data != null ? response.data['token'] : '', + ); } Future> authorizeDevice(final DeviceToken token) async { @@ -739,9 +764,10 @@ class ServerApi extends ApiMap { } on DioError catch (e) { print(e.message); return ApiResponse( - errorMessage: e.message, - statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, - data: '',); + errorMessage: e.message, + statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, + data: '', + ); } finally { client.close(); } @@ -760,9 +786,10 @@ class ServerApi extends ApiMap { } on DioError catch (e) { print(e.message); return ApiResponse( - errorMessage: e.message, - statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, - data: '',); + errorMessage: e.message, + statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, + data: '', + ); } finally { client.close(); } @@ -770,8 +797,9 @@ class ServerApi extends ApiMap { final int code = response.statusCode ?? HttpStatus.internalServerError; return ApiResponse( - statusCode: code, - data: response.data != null ? response.data['token'] : '',); + statusCode: code, + data: response.data != null ? response.data['token'] : '', + ); } Future> deleteDeviceToken() async { @@ -783,9 +811,10 @@ class ServerApi extends ApiMap { } on DioError catch (e) { print(e.message); return ApiResponse( - errorMessage: e.message, - statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, - data: '',); + errorMessage: e.message, + statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, + data: '', + ); } finally { client.close(); } @@ -804,9 +833,10 @@ class ServerApi extends ApiMap { } on DioError catch (e) { print(e.message); return ApiResponse( - errorMessage: e.message, - statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, - data: [],); + errorMessage: e.message, + statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, + data: [], + ); } finally { client.close(); } @@ -814,10 +844,11 @@ class ServerApi extends ApiMap { final int code = response.statusCode ?? HttpStatus.internalServerError; return ApiResponse( - statusCode: code, - data: (response.data != null) - ? response.data.map((final e) => ApiToken.fromJson(e)).toList() - : [],); + statusCode: code, + data: (response.data != null) + ? response.data.map(ApiToken.fromJson).toList() + : [], + ); } Future> refreshCurrentApiToken() async { @@ -829,9 +860,10 @@ class ServerApi extends ApiMap { } on DioError catch (e) { print(e.message); return ApiResponse( - errorMessage: e.message, - statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, - data: '',); + errorMessage: e.message, + statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, + data: '', + ); } finally { client.close(); } @@ -839,8 +871,9 @@ class ServerApi extends ApiMap { final int code = response.statusCode ?? HttpStatus.internalServerError; return ApiResponse( - statusCode: code, - data: response.data != null ? response.data['token'] : '',); + statusCode: code, + data: response.data != null ? response.data['token'] : '', + ); } Future> deleteApiToken(final String device) async { @@ -856,9 +889,10 @@ class ServerApi extends ApiMap { } on DioError catch (e) { print(e.message); return ApiResponse( - errorMessage: e.message, - statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, - data: null,); + errorMessage: e.message, + statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, + data: null, + ); } finally { client.close(); } diff --git a/lib/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart b/lib/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart index 68705b5b..096a4d4f 100644 --- a/lib/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart +++ b/lib/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'dart:async'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:equatable/equatable.dart'; diff --git a/lib/logic/cubit/app_settings/app_settings_cubit.dart b/lib/logic/cubit/app_settings/app_settings_cubit.dart index 7c2d55e3..06b46730 100644 --- a/lib/logic/cubit/app_settings/app_settings_cubit.dart +++ b/lib/logic/cubit/app_settings/app_settings_cubit.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:hive/hive.dart'; @@ -25,10 +23,12 @@ class AppSettingsCubit extends Cubit { void load() { final bool? isDarkModeOn = box.get(BNames.isDarkModeOn); final bool? isOnboardingShowing = box.get(BNames.isOnboardingShowing); - emit(state.copyWith( - isDarkModeOn: isDarkModeOn, - isOnboardingShowing: isOnboardingShowing, - ),); + emit( + state.copyWith( + isDarkModeOn: isDarkModeOn, + isOnboardingShowing: isOnboardingShowing, + ), + ); } void updateDarkMode({required final bool isDarkModeOn}) { diff --git a/lib/logic/cubit/app_settings/app_settings_state.dart b/lib/logic/cubit/app_settings/app_settings_state.dart index 6000fc55..92da9667 100644 --- a/lib/logic/cubit/app_settings/app_settings_state.dart +++ b/lib/logic/cubit/app_settings/app_settings_state.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - part of 'app_settings_cubit.dart'; class AppSettingsState extends Equatable { @@ -11,7 +9,10 @@ class AppSettingsState extends Equatable { final bool isDarkModeOn; final bool isOnboardingShowing; - AppSettingsState copyWith({final isDarkModeOn, final isOnboardingShowing}) => + AppSettingsState copyWith({ + final bool? isDarkModeOn, + final bool? isOnboardingShowing, + }) => AppSettingsState( isDarkModeOn: isDarkModeOn ?? this.isDarkModeOn, isOnboardingShowing: isOnboardingShowing ?? this.isOnboardingShowing, diff --git a/lib/logic/cubit/backups/backups_cubit.dart b/lib/logic/cubit/backups/backups_cubit.dart index e77156db..63cdfb3e 100644 --- a/lib/logic/cubit/backups/backups_cubit.dart +++ b/lib/logic/cubit/backups/backups_cubit.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'dart:async'; import 'package:easy_localization/easy_localization.dart'; @@ -15,7 +13,9 @@ part 'backups_state.dart'; class BackupsCubit extends ServerInstallationDependendCubit { BackupsCubit(final ServerInstallationCubit serverInstallationCubit) : super( - serverInstallationCubit, const BackupsState(preventActions: true),); + serverInstallationCubit, + const BackupsState(preventActions: true), + ); final ServerApi api = ServerApi(); final BackblazeApi backblaze = BackblazeApi(); @@ -25,59 +25,72 @@ class BackupsCubit extends ServerInstallationDependendCubit { if (serverInstallationCubit.state is ServerInstallationFinished) { final BackblazeBucket? bucket = getIt().backblazeBucket; if (bucket == null) { - emit(const BackupsState( - isInitialized: false, preventActions: false, refreshing: false,),); + emit( + const BackupsState( + isInitialized: false, + preventActions: false, + refreshing: false, + ), + ); } else { final BackupStatus status = await api.getBackupStatus(); switch (status.status) { case BackupStatusEnum.noKey: case BackupStatusEnum.notInitialized: - emit(BackupsState( - backups: const [], - isInitialized: true, - preventActions: false, - progress: 0, - status: status.status, - refreshing: false, - ),); + emit( + BackupsState( + backups: const [], + isInitialized: true, + preventActions: false, + progress: 0, + status: status.status, + refreshing: false, + ), + ); break; case BackupStatusEnum.initializing: - emit(BackupsState( - backups: const [], - isInitialized: true, - preventActions: false, - progress: 0, - status: status.status, - refreshTimer: const Duration(seconds: 10), - refreshing: false, - ),); + emit( + BackupsState( + backups: const [], + isInitialized: true, + preventActions: false, + progress: 0, + status: status.status, + refreshTimer: const Duration(seconds: 10), + refreshing: false, + ), + ); break; case BackupStatusEnum.initialized: case BackupStatusEnum.error: final List backups = await api.getBackups(); - emit(BackupsState( - backups: backups, - isInitialized: true, - preventActions: false, - progress: status.progress, - status: status.status, - error: status.errorMessage ?? '', - refreshing: false, - ),); + emit( + BackupsState( + backups: backups, + isInitialized: true, + preventActions: false, + progress: status.progress, + status: status.status, + error: status.errorMessage ?? '', + refreshing: false, + ), + ); break; case BackupStatusEnum.backingUp: case BackupStatusEnum.restoring: final List backups = await api.getBackups(); - emit(BackupsState( - backups: backups, - isInitialized: true, - preventActions: true, - progress: status.progress, - status: status.status, - error: status.errorMessage ?? '', - refreshTimer: const Duration(seconds: 5), - refreshing: false, - ),); + emit( + BackupsState( + backups: backups, + isInitialized: true, + preventActions: true, + progress: status.progress, + status: status.status, + error: status.errorMessage ?? '', + refreshTimer: const Duration(seconds: 5), + refreshing: false, + ), + ); break; default: emit(const BackupsState()); @@ -101,10 +114,11 @@ class BackupsCubit extends ServerInstallationDependendCubit { final BackblazeApplicationKey key = await backblaze.createKey(bucketId); final BackblazeBucket bucket = BackblazeBucket( - bucketId: bucketId, - bucketName: bucketName, - applicationKey: key.applicationKey, - applicationKeyId: key.applicationKeyId,); + bucketId: bucketId, + bucketName: bucketName, + applicationKey: key.applicationKey, + applicationKeyId: key.applicationKeyId, + ); await getIt().storeBackblazeBucket(bucket); await api.uploadBackblazeConfig(bucket); @@ -141,14 +155,16 @@ class BackupsCubit extends ServerInstallationDependendCubit { emit(state.copyWith(refreshing: true)); final List backups = await api.getBackups(); final BackupStatus status = await api.getBackupStatus(); - emit(state.copyWith( - backups: backups, - progress: status.progress, - status: status.status, - error: status.errorMessage, - refreshTimer: refreshTimeFromState(status.status), - refreshing: false, - ),); + emit( + state.copyWith( + backups: backups, + progress: status.progress, + status: status.status, + error: status.errorMessage, + refreshTimer: refreshTimeFromState(status.status), + refreshing: false, + ), + ); if (useTimer) { Timer(state.refreshTimer, () => updateBackups(useTimer: true)); } diff --git a/lib/logic/cubit/backups/backups_state.dart b/lib/logic/cubit/backups/backups_state.dart index 3600c7a2..33ec52c8 100644 --- a/lib/logic/cubit/backups/backups_state.dart +++ b/lib/logic/cubit/backups/backups_state.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - part of 'backups_cubit.dart'; class BackupsState extends ServerInstallationDependendState { diff --git a/lib/logic/cubit/devices/devices_cubit.dart b/lib/logic/cubit/devices/devices_cubit.dart index ec302477..01f17a7d 100644 --- a/lib/logic/cubit/devices/devices_cubit.dart +++ b/lib/logic/cubit/devices/devices_cubit.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:selfprivacy/config/get_it_config.dart'; import 'package:selfprivacy/logic/api_maps/server.dart'; import 'package:selfprivacy/logic/common_enum/common_enum.dart'; @@ -50,9 +48,12 @@ class ApiDevicesCubit Future deleteDevice(final ApiToken device) async { final ApiResponse response = await api.deleteApiToken(device.name); if (response.isSuccess) { - emit(ApiDevicesState( + emit( + ApiDevicesState( state.devices.where((final d) => d.name != device.name).toList(), - LoadingStatus.success,),); + LoadingStatus.success, + ), + ); } else { getIt() .showSnackBar(response.errorMessage ?? 'Error deleting device'); @@ -65,7 +66,8 @@ class ApiDevicesCubit return response.data; } else { getIt().showSnackBar( - response.errorMessage ?? 'Error getting new device key',); + response.errorMessage ?? 'Error getting new device key', + ); return null; } } diff --git a/lib/logic/cubit/devices/devices_state.dart b/lib/logic/cubit/devices/devices_state.dart index ba7d7e90..86fd53c2 100644 --- a/lib/logic/cubit/devices/devices_state.dart +++ b/lib/logic/cubit/devices/devices_state.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - part of 'devices_cubit.dart'; class ApiDevicesState extends ServerInstallationDependendState { @@ -10,12 +8,14 @@ class ApiDevicesState extends ServerInstallationDependendState { final LoadingStatus status; List get devices => _devices; - ApiToken get thisDevice => _devices.firstWhere((final device) => device.isCaller, - orElse: () => ApiToken( - name: 'Error fetching device', - isCaller: true, - date: DateTime.now(), - ),); + ApiToken get thisDevice => _devices.firstWhere( + (final device) => device.isCaller, + orElse: () => ApiToken( + name: 'Error fetching device', + isCaller: true, + date: DateTime.now(), + ), + ); List get otherDevices => _devices.where((final device) => !device.isCaller).toList(); @@ -23,10 +23,11 @@ class ApiDevicesState extends ServerInstallationDependendState { ApiDevicesState copyWith({ final List? devices, final LoadingStatus? status, - }) => ApiDevicesState( - devices ?? _devices, - status ?? this.status, - ); + }) => + ApiDevicesState( + devices ?? _devices, + status ?? this.status, + ); @override List get props => [_devices]; diff --git a/lib/logic/cubit/dns_records/dns_records_cubit.dart b/lib/logic/cubit/dns_records/dns_records_cubit.dart index d6faba8e..0590b065 100644 --- a/lib/logic/cubit/dns_records/dns_records_cubit.dart +++ b/lib/logic/cubit/dns_records/dns_records_cubit.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:cubit_form/cubit_form.dart'; import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart'; import 'package:selfprivacy/logic/models/hive/server_domain.dart'; @@ -13,18 +11,26 @@ part 'dns_records_state.dart'; class DnsRecordsCubit extends ServerInstallationDependendCubit { DnsRecordsCubit(final ServerInstallationCubit serverInstallationCubit) - : super(serverInstallationCubit, - const DnsRecordsState(dnsState: DnsRecordsStatus.refreshing),); + : super( + serverInstallationCubit, + const DnsRecordsState(dnsState: DnsRecordsStatus.refreshing), + ); final ServerApi api = ServerApi(); final CloudflareApi cloudflare = CloudflareApi(); @override Future load() async { - emit(DnsRecordsState( + emit( + DnsRecordsState( dnsState: DnsRecordsStatus.refreshing, dnsRecords: _getDesiredDnsRecords( - serverInstallationCubit.state.serverDomain?.domainName, '', '',),),); + serverInstallationCubit.state.serverDomain?.domainName, + '', + '', + ), + ), + ); print('Loading DNS status'); if (serverInstallationCubit.state is ServerInstallationFinished) { final ServerDomain? domain = serverInstallationCubit.state.serverDomain; @@ -41,41 +47,48 @@ class DnsRecordsCubit if (record.description == 'providers.domain.record_description.dkim') { final DnsRecord foundRecord = records.firstWhere( - (final r) => r.name == record.name && r.type == record.type, - orElse: () => DnsRecord( - name: record.name, - type: record.type, - content: '', - ttl: 800, - proxied: false,),); + (final r) => r.name == record.name && r.type == record.type, + orElse: () => DnsRecord( + name: record.name, + type: record.type, + content: '', + ttl: 800, + proxied: false, + ), + ); // remove all spaces and tabulators from // the foundRecord.content and the record.content // to compare them final String? foundContent = foundRecord.content?.replaceAll(RegExp(r'\s+'), ''); - final String content = record.content.replaceAll(RegExp(r'\s+'), ''); + final String content = + record.content.replaceAll(RegExp(r'\s+'), ''); if (foundContent == content) { foundRecords.add(record.copyWith(isSatisfied: true)); } else { foundRecords.add(record.copyWith(isSatisfied: false)); } } else { - if (records.any((final r) => - r.name == record.name && - r.type == record.type && - r.content == record.content,)) { + if (records.any( + (final r) => + r.name == record.name && + r.type == record.type && + r.content == record.content, + )) { foundRecords.add(record.copyWith(isSatisfied: true)); } else { foundRecords.add(record.copyWith(isSatisfied: false)); } } } - emit(DnsRecordsState( - dnsRecords: foundRecords, - dnsState: foundRecords.any((final r) => r.isSatisfied == false) - ? DnsRecordsStatus.error - : DnsRecordsStatus.good, - ),); + emit( + DnsRecordsState( + dnsRecords: foundRecords, + dnsState: foundRecords.any((final r) => r.isSatisfied == false) + ? DnsRecordsStatus.error + : DnsRecordsStatus.good, + ), + ); } else { emit(const DnsRecordsState()); } @@ -105,13 +118,18 @@ class DnsRecordsCubit final String? dkimPublicKey = await api.getDkim(); await cloudflare.removeSimilarRecords(cloudFlareDomain: domain!); await cloudflare.createMultipleDnsRecords( - cloudFlareDomain: domain, ip4: ipAddress,); + cloudFlareDomain: domain, + ip4: ipAddress, + ); await cloudflare.setDkim(dkimPublicKey ?? '', domain); await load(); } List _getDesiredDnsRecords( - final String? domainName, final String? ipAddress, final String? dkimPublicKey,) { + final String? domainName, + final String? ipAddress, + final String? dkimPublicKey, + ) { if (domainName == null || ipAddress == null || dkimPublicKey == null) { return []; } diff --git a/lib/logic/cubit/dns_records/dns_records_state.dart b/lib/logic/cubit/dns_records/dns_records_state.dart index d6d0c67b..4b39d014 100644 --- a/lib/logic/cubit/dns_records/dns_records_state.dart +++ b/lib/logic/cubit/dns_records/dns_records_state.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - part of 'dns_records_cubit.dart'; enum DnsRecordsStatus { @@ -33,10 +31,11 @@ class DnsRecordsState extends ServerInstallationDependendState { DnsRecordsState copyWith({ final DnsRecordsStatus? dnsState, final List? dnsRecords, - }) => DnsRecordsState( - dnsState: dnsState ?? this.dnsState, - dnsRecords: dnsRecords ?? this.dnsRecords, - ); + }) => + DnsRecordsState( + dnsState: dnsState ?? this.dnsState, + dnsRecords: dnsRecords ?? this.dnsRecords, + ); } class DesiredDnsRecord { @@ -63,12 +62,13 @@ class DesiredDnsRecord { final String? description, final DnsRecordsCategory? category, final bool? isSatisfied, - }) => DesiredDnsRecord( - name: name ?? this.name, - type: type ?? this.type, - content: content ?? this.content, - description: description ?? this.description, - category: category ?? this.category, - isSatisfied: isSatisfied ?? this.isSatisfied, - ); + }) => + DesiredDnsRecord( + name: name ?? this.name, + type: type ?? this.type, + content: content ?? this.content, + description: description ?? this.description, + category: category ?? this.category, + isSatisfied: isSatisfied ?? this.isSatisfied, + ); } diff --git a/lib/logic/cubit/forms/factories/field_cubit_factory.dart b/lib/logic/cubit/forms/factories/field_cubit_factory.dart index d71f3a7b..62067cea 100644 --- a/lib/logic/cubit/forms/factories/field_cubit_factory.dart +++ b/lib/logic/cubit/forms/factories/field_cubit_factory.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:flutter/material.dart'; import 'package:selfprivacy/logic/cubit/forms/validations/validations.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -24,15 +22,20 @@ class FieldCubitFactory { initalValue: '', validations: [ ValidationModel( - (final String s) => s.toLowerCase() == 'root', 'validations.root_name'.tr(),), + (final String s) => s.toLowerCase() == 'root', + 'validations.root_name'.tr(), + ), ValidationModel( - (final String login) => context.read().state.isLoginRegistered(login), + (final String login) => + context.read().state.isLoginRegistered(login), 'validations.user_already_exist'.tr(), ), RequiredStringValidation('validations.required'.tr()), LengthStringLongerValidation(userMaxLength), - ValidationModel((final String s) => !userAllowedRegExp.hasMatch(s), - 'validations.invalid_format'.tr(),), + ValidationModel( + (final String s) => !userAllowedRegExp.hasMatch(s), + 'validations.invalid_format'.tr(), + ), ], ); } @@ -48,18 +51,19 @@ class FieldCubitFactory { validations: [ RequiredStringValidation('validations.required'.tr()), ValidationModel( - passwordForbiddenRegExp.hasMatch, - 'validations.invalid_format'.tr(),), + passwordForbiddenRegExp.hasMatch, + 'validations.invalid_format'.tr(), + ), ], ); } FieldCubit createRequiredStringField() => FieldCubit( - initalValue: '', - validations: [ - RequiredStringValidation('validations.required'.tr()), - ], - ); + initalValue: '', + validations: [ + RequiredStringValidation('validations.required'.tr()), + ], + ); final BuildContext context; } diff --git a/lib/logic/cubit/forms/setup/initializing/backblaze_form_cubit.dart b/lib/logic/cubit/forms/setup/initializing/backblaze_form_cubit.dart index 0ac87e30..4769286d 100644 --- a/lib/logic/cubit/forms/setup/initializing/backblaze_form_cubit.dart +++ b/lib/logic/cubit/forms/setup/initializing/backblaze_form_cubit.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'dart:async'; import 'package:cubit_form/cubit_form.dart'; import 'package:selfprivacy/logic/api_maps/backblaze.dart'; diff --git a/lib/logic/cubit/forms/setup/initializing/cloudflare_form_cubit.dart b/lib/logic/cubit/forms/setup/initializing/cloudflare_form_cubit.dart index c8dc14d1..01d26835 100644 --- a/lib/logic/cubit/forms/setup/initializing/cloudflare_form_cubit.dart +++ b/lib/logic/cubit/forms/setup/initializing/cloudflare_form_cubit.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'dart:async'; import 'package:cubit_form/cubit_form.dart'; @@ -16,7 +14,9 @@ class CloudFlareFormCubit extends FormCubit { validations: [ RequiredStringValidation('validations.required'.tr()), ValidationModel( - regExp.hasMatch, 'validations.key_format'.tr(),), + regExp.hasMatch, + 'validations.key_format'.tr(), + ), LengthStringNotEqualValidation(40) ], ); diff --git a/lib/logic/cubit/forms/setup/initializing/hetzner_form_cubit.dart b/lib/logic/cubit/forms/setup/initializing/hetzner_form_cubit.dart index a7e2bb1d..b8f47e10 100644 --- a/lib/logic/cubit/forms/setup/initializing/hetzner_form_cubit.dart +++ b/lib/logic/cubit/forms/setup/initializing/hetzner_form_cubit.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'dart:async'; import 'package:cubit_form/cubit_form.dart'; @@ -16,7 +14,9 @@ class HetznerFormCubit extends FormCubit { validations: [ RequiredStringValidation('validations.required'.tr()), ValidationModel( - regExp.hasMatch, 'validations.key_format'.tr(),), + regExp.hasMatch, + 'validations.key_format'.tr(), + ), LengthStringNotEqualValidation(64) ], ); diff --git a/lib/logic/cubit/forms/setup/initializing/root_user_form_cubit.dart b/lib/logic/cubit/forms/setup/initializing/root_user_form_cubit.dart index 0914d86b..b3cf606f 100644 --- a/lib/logic/cubit/forms/setup/initializing/root_user_form_cubit.dart +++ b/lib/logic/cubit/forms/setup/initializing/root_user_form_cubit.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'dart:async'; import 'package:cubit_form/cubit_form.dart'; @@ -9,7 +7,9 @@ import 'package:selfprivacy/logic/models/hive/user.dart'; class RootUserFormCubit extends FormCubit { RootUserFormCubit( - this.serverInstallationCubit, final FieldCubitFactory fieldFactory,) { + this.serverInstallationCubit, + final FieldCubitFactory fieldFactory, + ) { userName = fieldFactory.createUserLoginField(); password = fieldFactory.createUserPasswordField(); diff --git a/lib/logic/cubit/forms/setup/recovering/recovery_device_form_cubit.dart b/lib/logic/cubit/forms/setup/recovering/recovery_device_form_cubit.dart index 00f5b685..ad93871c 100644 --- a/lib/logic/cubit/forms/setup/recovering/recovery_device_form_cubit.dart +++ b/lib/logic/cubit/forms/setup/recovering/recovery_device_form_cubit.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'dart:async'; import 'package:cubit_form/cubit_form.dart'; @@ -7,8 +5,11 @@ import 'package:selfprivacy/logic/cubit/server_installation/server_installation_ import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart'; class RecoveryDeviceFormCubit extends FormCubit { - RecoveryDeviceFormCubit(this.installationCubit, - final FieldCubitFactory fieldFactory, this.recoveryMethod,) { + RecoveryDeviceFormCubit( + this.installationCubit, + final FieldCubitFactory fieldFactory, + this.recoveryMethod, + ) { tokenField = fieldFactory.createRequiredStringField(); super.addFields([tokenField]); diff --git a/lib/logic/cubit/forms/setup/recovering/recovery_domain_form_cubit.dart b/lib/logic/cubit/forms/setup/recovering/recovery_domain_form_cubit.dart index d2bea806..664b87b8 100644 --- a/lib/logic/cubit/forms/setup/recovering/recovery_domain_form_cubit.dart +++ b/lib/logic/cubit/forms/setup/recovering/recovery_domain_form_cubit.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'dart:async'; import 'package:cubit_form/cubit_form.dart'; @@ -10,7 +8,9 @@ import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart class RecoveryDomainFormCubit extends FormCubit { RecoveryDomainFormCubit( - this.initializingCubit, final FieldCubitFactory fieldFactory,) { + this.initializingCubit, + final FieldCubitFactory fieldFactory, + ) { serverDomainField = fieldFactory.createRequiredStringField(); super.addFields([serverDomainField]); @@ -25,9 +25,10 @@ class RecoveryDomainFormCubit extends FormCubit { @override FutureOr asyncValidation() async { final ServerApi api = ServerApi( - hasLogger: false, - isWithToken: false, - overrideDomain: serverDomainField.state.value,); + hasLogger: false, + isWithToken: false, + overrideDomain: serverDomainField.state.value, + ); // API version doesn't require access token, // so if the entered domain is indeed valid diff --git a/lib/logic/cubit/forms/user/ssh_form_cubit.dart b/lib/logic/cubit/forms/user/ssh_form_cubit.dart index 4262939e..ba38a642 100644 --- a/lib/logic/cubit/forms/user/ssh_form_cubit.dart +++ b/lib/logic/cubit/forms/user/ssh_form_cubit.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'dart:async'; import 'package:cubit_form/cubit_form.dart'; @@ -14,21 +12,26 @@ class SshFormCubit extends FormCubit { required this.user, }) { final RegExp keyRegExp = RegExp( - r'^(ssh-rsa AAAAB3NzaC1yc2|ssh-ed25519 AAAAC3NzaC1lZDI1NTE5)[0-9A-Za-z+/]+[=]{0,3}( .*)?$',); + r'^(ssh-rsa AAAAB3NzaC1yc2|ssh-ed25519 AAAAC3NzaC1lZDI1NTE5)[0-9A-Za-z+/]+[=]{0,3}( .*)?$', + ); key = FieldCubit( initalValue: '', validations: [ ValidationModel( - (final String newKey) => user.sshKeys.any((final String key) => key == newKey), + (final String newKey) => + user.sshKeys.any((final String key) => key == newKey), 'validations.key_already_exists'.tr(), ), RequiredStringValidation('validations.required'.tr()), - ValidationModel((final String s) { - print(s); - print(keyRegExp.hasMatch(s)); - return !keyRegExp.hasMatch(s); - }, 'validations.invalid_format'.tr(),), + ValidationModel( + (final String s) { + print(s); + print(keyRegExp.hasMatch(s)); + return !keyRegExp.hasMatch(s); + }, + 'validations.invalid_format'.tr(), + ), ], ); diff --git a/lib/logic/cubit/forms/user/user_form_cubit.dart b/lib/logic/cubit/forms/user/user_form_cubit.dart index 30d83e26..a385befb 100644 --- a/lib/logic/cubit/forms/user/user_form_cubit.dart +++ b/lib/logic/cubit/forms/user/user_form_cubit.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'dart:async'; import 'package:cubit_form/cubit_form.dart'; @@ -21,7 +19,8 @@ class UserFormCubit extends FormCubit { login.setValue(isEdit ? user.login : ''); password = fieldFactory.createUserPasswordField(); password.setValue( - isEdit ? (user.password ?? '') : StringGenerators.userPassword(),); + isEdit ? (user.password ?? '') : StringGenerators.userPassword(), + ); super.addFields([login, password]); } diff --git a/lib/logic/cubit/forms/validations/validations.dart b/lib/logic/cubit/forms/validations/validations.dart index dd2e653b..f233bded 100644 --- a/lib/logic/cubit/forms/validations/validations.dart +++ b/lib/logic/cubit/forms/validations/validations.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:cubit_form/cubit_form.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -9,7 +7,8 @@ abstract class LengthStringValidation extends ValidationModel { @override String? check(final String val) { final int length = val.length; - final String errorMessage = errorMassage.replaceAll('[]', length.toString()); + final String errorMessage = + errorMassage.replaceAll('[]', length.toString()); return test(val) ? errorMessage : null; } } @@ -17,13 +16,17 @@ abstract class LengthStringValidation extends ValidationModel { class LengthStringNotEqualValidation extends LengthStringValidation { /// String must be equal to [length] LengthStringNotEqualValidation(final int length) - : super((final n) => n.length != length, - 'validations.length_not_equal'.tr(args: [length.toString()]),); + : super( + (final n) => n.length != length, + 'validations.length_not_equal'.tr(args: [length.toString()]), + ); } class LengthStringLongerValidation extends LengthStringValidation { /// String must be shorter than or equal to [length] LengthStringLongerValidation(final int length) - : super((final n) => n.length > length, - 'validations.length_longer'.tr(args: [length.toString()]),); + : super( + (final n) => n.length > length, + 'validations.length_longer'.tr(args: [length.toString()]), + ); } diff --git a/lib/logic/cubit/hetzner_metrics/hetzner_metrics_repository.dart b/lib/logic/cubit/hetzner_metrics/hetzner_metrics_repository.dart index f9bcf15f..de7f3d43 100644 --- a/lib/logic/cubit/hetzner_metrics/hetzner_metrics_repository.dart +++ b/lib/logic/cubit/hetzner_metrics/hetzner_metrics_repository.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:selfprivacy/logic/api_maps/hetzner.dart'; import 'package:selfprivacy/logic/common_enum/common_enum.dart'; import 'package:selfprivacy/logic/models/hetzner_metrics.dart'; @@ -52,7 +50,11 @@ class HetznerMetricsRepository { } List timeSeriesSerializer( - final Map json, final String type,) { + final Map json, + final String type, +) { final List list = json['time_series'][type]['values']; - return list.map((final el) => TimeSeriesData(el[0], double.parse(el[1]))).toList(); + return list + .map((final el) => TimeSeriesData(el[0], double.parse(el[1]))) + .toList(); } diff --git a/lib/logic/cubit/hetzner_metrics/hetzner_metrics_state.dart b/lib/logic/cubit/hetzner_metrics/hetzner_metrics_state.dart index 793bfdfc..b6204db9 100644 --- a/lib/logic/cubit/hetzner_metrics/hetzner_metrics_state.dart +++ b/lib/logic/cubit/hetzner_metrics/hetzner_metrics_state.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - part of 'hetzner_metrics_cubit.dart'; abstract class HetznerMetricsState extends Equatable { diff --git a/lib/logic/cubit/jobs/jobs_cubit.dart b/lib/logic/cubit/jobs/jobs_cubit.dart index 7f116f1d..6de64677 100644 --- a/lib/logic/cubit/jobs/jobs_cubit.dart +++ b/lib/logic/cubit/jobs/jobs_cubit.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:easy_localization/easy_localization.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -43,11 +41,12 @@ class JobsCubit extends Cubit { if (state is JobsStateWithJobs) { newJobsList.addAll((state as JobsStateWithJobs).jobList); } - final bool needToRemoveJob = - newJobsList.any((final el) => el is ServiceToggleJob && el.type == job.type); + final bool needToRemoveJob = newJobsList + .any((final el) => el is ServiceToggleJob && el.type == job.type); if (needToRemoveJob) { - final Job removingJob = newJobsList - .firstWhere((final el) => el is ServiceToggleJob && el.type == job.type); + final Job removingJob = newJobsList.firstWhere( + (final el) => el is ServiceToggleJob && el.type == job.type, + ); removeJob(removingJob.id); } else { newJobsList.add(job); @@ -61,7 +60,8 @@ class JobsCubit extends Cubit { if (state is JobsStateWithJobs) { newJobsList.addAll((state as JobsStateWithJobs).jobList); } - final bool isExistInJobList = newJobsList.any((final el) => el is CreateSSHKeyJob); + final bool isExistInJobList = + newJobsList.any((final el) => el is CreateSSHKeyJob); if (!isExistInJobList) { newJobsList.add(job); getIt().showSnackBar('jobs.jobAdded'.tr()); diff --git a/lib/logic/cubit/jobs/jobs_state.dart b/lib/logic/cubit/jobs/jobs_state.dart index 0817dfbf..dbcf968e 100644 --- a/lib/logic/cubit/jobs/jobs_state.dart +++ b/lib/logic/cubit/jobs/jobs_state.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - part of 'jobs_cubit.dart'; abstract class JobsState extends Equatable { @@ -16,7 +14,8 @@ class JobsStateWithJobs extends JobsState { final List jobList; JobsState removeById(final String id) { - final List newJobsList = jobList.where((final element) => element.id != id).toList(); + final List newJobsList = + jobList.where((final element) => element.id != id).toList(); if (newJobsList.isEmpty) { return JobsStateEmpty(); diff --git a/lib/logic/cubit/providers/providers_state.dart b/lib/logic/cubit/providers/providers_state.dart index 89951b60..04146b5d 100644 --- a/lib/logic/cubit/providers/providers_state.dart +++ b/lib/logic/cubit/providers/providers_state.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - part of 'providers_cubit.dart'; class ProvidersState extends Equatable { @@ -7,18 +5,23 @@ class ProvidersState extends Equatable { final List all; - ProvidersState updateElement(final ProviderModel provider, final StateType newState) { + ProvidersState updateElement( + final ProviderModel provider, + final StateType newState, + ) { final List newList = [...all]; final int index = newList.indexOf(provider); newList[index] = provider.updateState(newState); return ProvidersState(newList); } - List get connected => - all.where((final service) => service.state != StateType.uninitialized).toList(); + List get connected => all + .where((final service) => service.state != StateType.uninitialized) + .toList(); - List get uninitialized => - all.where((final service) => service.state == StateType.uninitialized).toList(); + List get uninitialized => all + .where((final service) => service.state == StateType.uninitialized) + .toList(); bool get isFullyInitialized => uninitialized.isEmpty; diff --git a/lib/logic/cubit/recovery_key/recovery_key_state.dart b/lib/logic/cubit/recovery_key/recovery_key_state.dart index bd6664ef..1b764298 100644 --- a/lib/logic/cubit/recovery_key/recovery_key_state.dart +++ b/lib/logic/cubit/recovery_key/recovery_key_state.dart @@ -1,13 +1,13 @@ -// ignore_for_file: always_specify_types - part of 'recovery_key_cubit.dart'; class RecoveryKeyState extends ServerInstallationDependendState { const RecoveryKeyState(this._status, this.loadingStatus); const RecoveryKeyState.initial() - : this(const RecoveryKeyStatus(exists: false, valid: false), - LoadingStatus.refreshing,); + : this( + const RecoveryKeyStatus(exists: false, valid: false), + LoadingStatus.refreshing, + ); final RecoveryKeyStatus _status; final LoadingStatus loadingStatus; @@ -23,8 +23,9 @@ class RecoveryKeyState extends ServerInstallationDependendState { RecoveryKeyState copyWith({ final RecoveryKeyStatus? status, final LoadingStatus? loadingStatus, - }) => RecoveryKeyState( - status ?? _status, - loadingStatus ?? this.loadingStatus, - ); + }) => + RecoveryKeyState( + status ?? _status, + loadingStatus ?? this.loadingStatus, + ); } diff --git a/lib/logic/cubit/server_detailed_info/server_detailed_info_state.dart b/lib/logic/cubit/server_detailed_info/server_detailed_info_state.dart index 6a984328..ef226c1e 100644 --- a/lib/logic/cubit/server_detailed_info/server_detailed_info_state.dart +++ b/lib/logic/cubit/server_detailed_info/server_detailed_info_state.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - part of 'server_detailed_info_cubit.dart'; abstract class ServerDetailsState extends Equatable { @@ -18,7 +16,6 @@ class ServerDetailsNotReady extends ServerDetailsState {} class Loading extends ServerDetailsState {} class Loaded extends ServerDetailsState { - const Loaded({ required this.serverInfo, required this.serverTimezone, diff --git a/lib/logic/cubit/server_installation/server_installation_repository.dart b/lib/logic/cubit/server_installation/server_installation_repository.dart index 075e357b..ea6948ec 100644 --- a/lib/logic/cubit/server_installation/server_installation_repository.dart +++ b/lib/logic/cubit/server_installation/server_installation_repository.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'dart:io'; import 'package:basic_utils/basic_utils.dart'; @@ -29,13 +27,11 @@ import 'package:selfprivacy/ui/components/brand_alert/brand_alert.dart'; import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart'; class IpNotFoundException implements Exception { - IpNotFoundException(this.message); final String message; } class ServerAuthorizationException implements Exception { - ServerAuthorizationException(this.message); final String message; } @@ -47,8 +43,10 @@ class ServerInstallationRepository { final String? hetznerToken = getIt().hetznerKey; final String? cloudflareToken = getIt().cloudFlareKey; final ServerDomain? serverDomain = getIt().serverDomain; - final BackblazeCredential? backblazeCredential = getIt().backblazeCredential; - final ServerHostingDetails? serverDetails = getIt().serverDetails; + final BackblazeCredential? backblazeCredential = + getIt().backblazeCredential; + final ServerHostingDetails? serverDetails = + getIt().serverDetails; if (box.get(BNames.hasFinalChecked, defaultValue: false)) { return ServerInstallationFinished( @@ -76,7 +74,11 @@ class ServerInstallationRepository { serverDetails: serverDetails, rootUser: box.get(BNames.rootUser), currentStep: _getCurrentRecoveryStep( - hetznerToken, cloudflareToken, serverDomain, serverDetails,), + hetznerToken, + cloudflareToken, + serverDomain, + serverDetails, + ), recoveryCapabilities: await getRecoveryCapabilities(serverDomain), ); } @@ -146,8 +148,11 @@ class ServerInstallationRepository { } } - Future> isDnsAddressesMatch(final String? domainName, final String? ip4, - final Map? skippedMatches,) async { + Future> isDnsAddressesMatch( + final String? domainName, + final String? ip4, + final Map? skippedMatches, + ) async { final List addresses = [ '$domainName', 'api.$domainName', @@ -228,9 +233,11 @@ class ServerInstallationRepository { isRed: true, onPressed: () async { await hetznerApi.deleteSelfprivacyServerAndAllVolumes( - domainName: domainName,); + domainName: domainName, + ); - final ServerHostingDetails serverDetails = await hetznerApi.createServer( + final ServerHostingDetails serverDetails = + await hetznerApi.createServer( cloudFlareKey: cloudFlareKey, rootUser: rootUser, domainName: domainName, @@ -284,7 +291,8 @@ class ServerInstallationRepository { isRed: true, onPressed: () async { await hetznerApi.deleteSelfprivacyServerAndAllVolumes( - domainName: cloudFlareDomain.domainName,); + domainName: cloudFlareDomain.domainName, + ); onCancel(); }, @@ -358,8 +366,10 @@ class ServerInstallationRepository { Future getServerIpFromDomain(final ServerDomain serverDomain) async { final List? lookup = await DnsUtils.lookupRecord( - serverDomain.domainName, RRecordType.A, - provider: DnsApiProvider.CLOUDFLARE,); + serverDomain.domainName, + RRecordType.A, + provider: DnsApiProvider.CLOUDFLARE, + ); if (lookup == null || lookup.isEmpty) { throw IpNotFoundException('No IP found for domain $serverDomain'); } @@ -369,22 +379,32 @@ class ServerInstallationRepository { Future getDeviceName() async { final DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); if (kIsWeb) { - return deviceInfo.webBrowserInfo - .then((final WebBrowserInfo value) => '${value.browserName} ${value.platform}'); + return deviceInfo.webBrowserInfo.then( + (final WebBrowserInfo value) => + '${value.browserName} ${value.platform}', + ); } else { if (Platform.isAndroid) { - return deviceInfo.androidInfo - .then((final AndroidDeviceInfo value) => '${value.model} ${value.version.release}'); + return deviceInfo.androidInfo.then( + (final AndroidDeviceInfo value) => + '${value.model} ${value.version.release}', + ); } else if (Platform.isIOS) { - return deviceInfo.iosInfo.then((final IosDeviceInfo value) => - '${value.utsname.machine} ${value.systemName} ${value.systemVersion}',); + return deviceInfo.iosInfo.then( + (final IosDeviceInfo value) => + '${value.utsname.machine} ${value.systemName} ${value.systemVersion}', + ); } else if (Platform.isLinux) { - return deviceInfo.linuxInfo.then((final LinuxDeviceInfo value) => value.prettyName); + return deviceInfo.linuxInfo + .then((final LinuxDeviceInfo value) => value.prettyName); } else if (Platform.isMacOS) { - return deviceInfo.macOsInfo - .then((final MacOsDeviceInfo value) => '${value.hostName} ${value.computerName}'); + return deviceInfo.macOsInfo.then( + (final MacOsDeviceInfo value) => + '${value.hostName} ${value.computerName}', + ); } else if (Platform.isWindows) { - return deviceInfo.windowsInfo.then((final WindowsDeviceInfo value) => value.computerName); + return deviceInfo.windowsInfo + .then((final WindowsDeviceInfo value) => value.computerName); } } return 'Unidentified'; @@ -401,7 +421,8 @@ class ServerInstallationRepository { ); final String serverIp = await getServerIpFromDomain(serverDomain); final ApiResponse apiResponse = await serverApi.authorizeDevice( - DeviceToken(device: await getDeviceName(), token: newDeviceKey),); + DeviceToken(device: await getDeviceName(), token: newDeviceKey), + ); if (apiResponse.isSuccess) { return ServerHostingDetails( @@ -434,7 +455,8 @@ class ServerInstallationRepository { ); final String serverIp = await getServerIpFromDomain(serverDomain); final ApiResponse apiResponse = await serverApi.useRecoveryToken( - DeviceToken(device: await getDeviceName(), token: recoveryKey),); + DeviceToken(device: await getDeviceName(), token: recoveryKey), + ); if (apiResponse.isSuccess) { return ServerHostingDetails( @@ -468,7 +490,8 @@ class ServerInstallationRepository { ); final String serverIp = await getServerIpFromDomain(serverDomain); if (recoveryCapabilities == ServerRecoveryCapabilities.legacy) { - final Map apiResponse = await serverApi.servicesPowerCheck(); + final Map apiResponse = + await serverApi.servicesPowerCheck(); if (apiResponse.isNotEmpty) { return ServerHostingDetails( apiToken: apiToken, @@ -488,9 +511,11 @@ class ServerInstallationRepository { ); } } - final ApiResponse deviceAuthKey = await serverApi.createDeviceToken(); + final ApiResponse deviceAuthKey = + await serverApi.createDeviceToken(); final ApiResponse apiResponse = await serverApi.authorizeDevice( - DeviceToken(device: await getDeviceName(), token: deviceAuthKey.data),); + DeviceToken(device: await getDeviceName(), token: deviceAuthKey.data), + ); if (apiResponse.isSuccess) { return ServerHostingDetails( @@ -522,7 +547,8 @@ class ServerInstallationRepository { ); final String? serverApiVersion = await serverApi.getApiVersion(); - final ApiResponse> users = await serverApi.getUsersList(withMainUser: true); + final ApiResponse> users = + await serverApi.getUsersList(withMainUser: true); if (serverApiVersion == null || !users.isSuccess) { return fallbackUser; } @@ -544,18 +570,22 @@ class ServerInstallationRepository { final HetznerApi hetznerApi = HetznerApi(); final List servers = await hetznerApi.getServers(); return servers - .map((final HetznerServerInfo server) => ServerBasicInfo( - id: server.id, - name: server.name, - ip: server.publicNet.ipv4.ip, - reverseDns: server.publicNet.ipv4.reverseDns, - created: server.created, - volumeId: server.volumes.isNotEmpty ? server.volumes[0] : 0, - ),) + .map( + (final HetznerServerInfo server) => ServerBasicInfo( + id: server.id, + name: server.name, + ip: server.publicNet.ipv4.ip, + reverseDns: server.publicNet.ipv4.reverseDns, + created: server.created, + volumeId: server.volumes.isNotEmpty ? server.volumes[0] : 0, + ), + ) .toList(); } - Future saveServerDetails(final ServerHostingDetails serverDetails) async { + Future saveServerDetails( + final ServerHostingDetails serverDetails, + ) async { await getIt().storeServerDetails(serverDetails); } @@ -569,7 +599,9 @@ class ServerInstallationRepository { getIt().init(); } - Future saveBackblazeKey(final BackblazeCredential backblazeCredential) async { + Future saveBackblazeKey( + final BackblazeCredential backblazeCredential, + ) async { await getIt().storeBackblazeCredential(backblazeCredential); } diff --git a/lib/logic/cubit/server_installation/server_installation_state.dart b/lib/logic/cubit/server_installation/server_installation_state.dart index 8cd0c2e1..b3128e71 100644 --- a/lib/logic/cubit/server_installation/server_installation_state.dart +++ b/lib/logic/cubit/server_installation/server_installation_state.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - part of '../server_installation/server_installation_cubit.dart'; abstract class ServerInstallationState extends Equatable { @@ -45,8 +43,8 @@ abstract class ServerInstallationState extends Equatable { bool get isServerCreated => serverDetails != null; bool get isFullyInitilized => _fulfilementList.every((final el) => el!); - ServerSetupProgress get progress => - ServerSetupProgress.values[_fulfilementList.where((final el) => el!).length]; + ServerSetupProgress get progress => ServerSetupProgress + .values[_fulfilementList.where((final el) => el!).length]; int get porgressBar { if (progress.index < 6) { @@ -120,7 +118,6 @@ enum ServerSetupProgress { } class ServerInstallationNotFinished extends ServerInstallationState { - const ServerInstallationNotFinished({ required final super.isServerStarted, required final super.isServerResetedFirstTime, @@ -260,7 +257,6 @@ enum ServerRecoveryMethods { } class ServerInstallationRecovery extends ServerInstallationState { - const ServerInstallationRecovery({ required this.currentStep, required this.recoveryCapabilities, @@ -313,14 +309,14 @@ class ServerInstallationRecovery extends ServerInstallationState { ); ServerInstallationFinished finish() => ServerInstallationFinished( - hetznerKey: hetznerKey!, - cloudFlareKey: cloudFlareKey!, - backblazeCredential: backblazeCredential!, - serverDomain: serverDomain!, - rootUser: rootUser!, - serverDetails: serverDetails!, - isServerStarted: true, - isServerResetedFirstTime: true, - isServerResetedSecondTime: true, - ); + hetznerKey: hetznerKey!, + cloudFlareKey: cloudFlareKey!, + backblazeCredential: backblazeCredential!, + serverDomain: serverDomain!, + rootUser: rootUser!, + serverDetails: serverDetails!, + isServerStarted: true, + isServerResetedFirstTime: true, + isServerResetedSecondTime: true, + ); } diff --git a/lib/logic/cubit/services/services_state.dart b/lib/logic/cubit/services/services_state.dart index bec81fe1..ffe90aee 100644 --- a/lib/logic/cubit/services/services_state.dart +++ b/lib/logic/cubit/services/services_state.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - part of 'services_cubit.dart'; class ServicesState extends ServerInstallationDependendState { diff --git a/lib/logic/cubit/users/users_cubit.dart b/lib/logic/cubit/users/users_cubit.dart index b96c5683..9b86c109 100644 --- a/lib/logic/cubit/users/users_cubit.dart +++ b/lib/logic/cubit/users/users_cubit.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:hive/hive.dart'; import 'package:selfprivacy/config/hive_config.dart'; import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart'; @@ -14,9 +12,13 @@ part 'users_state.dart'; class UsersCubit extends ServerInstallationDependendCubit { UsersCubit(final ServerInstallationCubit serverInstallationCubit) : super( - serverInstallationCubit, - const UsersState( - [], User(login: 'root'), User(login: 'loading...'),),); + serverInstallationCubit, + const UsersState( + [], + User(login: 'root'), + User(login: 'loading...'), + ), + ); Box box = Hive.box(BNames.usersBox); Box serverInstallationBox = Hive.box(BNames.serverInstallationBox); @@ -26,22 +28,35 @@ class UsersCubit extends ServerInstallationDependendCubit { Future load() async { if (serverInstallationCubit.state is ServerInstallationFinished) { final List loadedUsers = box.values.toList(); - final primaryUser = serverInstallationBox.get(BNames.rootUser, - defaultValue: const User(login: 'loading...'),); + final primaryUser = serverInstallationBox.get( + BNames.rootUser, + defaultValue: const User(login: 'loading...'), + ); final List rootKeys = [ ...serverInstallationBox.get(BNames.rootKeys, defaultValue: []) ]; if (loadedUsers.isNotEmpty) { - emit(UsersState( - loadedUsers, User(login: 'root', sshKeys: rootKeys), primaryUser,),); + emit( + UsersState( + loadedUsers, + User(login: 'root', sshKeys: rootKeys), + primaryUser, + ), + ); } - final ApiResponse> usersFromServer = await api.getUsersList(); + final ApiResponse> usersFromServer = + await api.getUsersList(); if (usersFromServer.isSuccess) { final List updatedList = mergeLocalAndServerUsers(loadedUsers, usersFromServer.data); - emit(UsersState( - updatedList, User(login: 'root', sshKeys: rootKeys), primaryUser,),); + emit( + UsersState( + updatedList, + User(login: 'root', sshKeys: rootKeys), + primaryUser, + ), + ); } final List usersWithSshKeys = await loadSshKeys(state.users); @@ -49,18 +64,26 @@ class UsersCubit extends ServerInstallationDependendCubit { box.clear(); box.addAll(usersWithSshKeys); - final User rootUserWithSshKeys = (await loadSshKeys([state.rootUser])).first; + final User rootUserWithSshKeys = + (await loadSshKeys([state.rootUser])).first; serverInstallationBox.put(BNames.rootKeys, rootUserWithSshKeys.sshKeys); final User primaryUserWithSshKeys = (await loadSshKeys([state.primaryUser])).first; serverInstallationBox.put(BNames.rootUser, primaryUserWithSshKeys); - emit(UsersState( - usersWithSshKeys, rootUserWithSshKeys, primaryUserWithSshKeys,),); + emit( + UsersState( + usersWithSshKeys, + rootUserWithSshKeys, + primaryUserWithSshKeys, + ), + ); } } List mergeLocalAndServerUsers( - final List localUsers, final List serverUsers,) { + final List localUsers, + final List serverUsers, + ) { // If local user not exists on server, add it with isFoundOnServer = false // If server user not exists on local, add it @@ -69,28 +92,34 @@ class UsersCubit extends ServerInstallationDependendCubit { for (final User localUser in localUsers) { if (serverUsersCopy.contains(localUser.login)) { - mergedUsers.add(User( - login: localUser.login, - isFoundOnServer: true, - password: localUser.password, - sshKeys: localUser.sshKeys, - ),); + mergedUsers.add( + User( + login: localUser.login, + isFoundOnServer: true, + password: localUser.password, + sshKeys: localUser.sshKeys, + ), + ); serverUsersCopy.remove(localUser.login); } else { - mergedUsers.add(User( - login: localUser.login, - isFoundOnServer: false, - password: localUser.password, - note: localUser.note, - ),); + mergedUsers.add( + User( + login: localUser.login, + isFoundOnServer: false, + password: localUser.password, + note: localUser.note, + ), + ); } } for (final String serverUser in serverUsersCopy) { - mergedUsers.add(User( - login: serverUser, - isFoundOnServer: true, - ),); + mergedUsers.add( + User( + login: serverUser, + isFoundOnServer: true, + ), + ); } return mergedUsers; @@ -103,31 +132,38 @@ class UsersCubit extends ServerInstallationDependendCubit { if (user.isFoundOnServer || user.login == 'root' || user.login == state.primaryUser.login) { - final ApiResponse> sshKeys = await api.getUserSshKeys(user); + final ApiResponse> sshKeys = + await api.getUserSshKeys(user); print('sshKeys for $user: ${sshKeys.data}'); if (sshKeys.isSuccess) { - updatedUsers.add(User( - login: user.login, - isFoundOnServer: true, - password: user.password, - sshKeys: sshKeys.data, - note: user.note, - ),); + updatedUsers.add( + User( + login: user.login, + isFoundOnServer: true, + password: user.password, + sshKeys: sshKeys.data, + note: user.note, + ), + ); } else { - updatedUsers.add(User( - login: user.login, - isFoundOnServer: true, - password: user.password, - note: user.note, - ),); + updatedUsers.add( + User( + login: user.login, + isFoundOnServer: true, + password: user.password, + note: user.note, + ), + ); } } else { - updatedUsers.add(User( - login: user.login, - isFoundOnServer: false, - password: user.password, - note: user.note, - ),); + updatedUsers.add( + User( + login: user.login, + isFoundOnServer: false, + password: user.password, + note: user.note, + ), + ); } } return updatedUsers; @@ -143,19 +179,26 @@ class UsersCubit extends ServerInstallationDependendCubit { final List usersWithSshKeys = await loadSshKeys(updatedUsers); box.clear(); box.addAll(usersWithSshKeys); - final User rootUserWithSshKeys = (await loadSshKeys([state.rootUser])).first; + final User rootUserWithSshKeys = + (await loadSshKeys([state.rootUser])).first; serverInstallationBox.put(BNames.rootKeys, rootUserWithSshKeys.sshKeys); final User primaryUserWithSshKeys = (await loadSshKeys([state.primaryUser])).first; serverInstallationBox.put(BNames.rootUser, primaryUserWithSshKeys); - emit(UsersState( - usersWithSshKeys, rootUserWithSshKeys, primaryUserWithSshKeys,),); + emit( + UsersState( + usersWithSshKeys, + rootUserWithSshKeys, + primaryUserWithSshKeys, + ), + ); return; } Future createUser(final User user) async { // If user exists on server, do nothing - if (state.users.any((final User u) => u.login == user.login && u.isFoundOnServer)) { + if (state.users + .any((final User u) => u.login == user.login && u.isFoundOnServer)) { return; } // If user is root or primary user, do nothing @@ -201,15 +244,17 @@ class UsersCubit extends ServerInstallationDependendCubit { .get(BNames.rootKeys, defaultValue: []) as List; rootKeys.add(publicKey); serverInstallationBox.put(BNames.rootKeys, rootKeys); - emit(state.copyWith( - rootUser: User( - login: state.rootUser.login, - isFoundOnServer: true, - password: state.rootUser.password, - sshKeys: rootKeys, - note: state.rootUser.note, + emit( + state.copyWith( + rootUser: User( + login: state.rootUser.login, + isFoundOnServer: true, + password: state.rootUser.password, + sshKeys: rootKeys, + note: state.rootUser.note, + ), ), - ),); + ); } } else { final ApiResponse result = await api.addUserSshKey(user, publicKey); @@ -227,9 +272,11 @@ class UsersCubit extends ServerInstallationDependendCubit { note: state.primaryUser.note, ); serverInstallationBox.put(BNames.rootUser, updatedUser); - emit(state.copyWith( - primaryUser: updatedUser, - ),); + emit( + state.copyWith( + primaryUser: updatedUser, + ), + ); } else { // If it is not primary user, update user final List userKeys = List.from(user.sshKeys); @@ -242,9 +289,11 @@ class UsersCubit extends ServerInstallationDependendCubit { note: user.note, ); await box.putAt(box.values.toList().indexOf(user), updatedUser); - emit(state.copyWith( - users: box.values.toList(), - ),); + emit( + state.copyWith( + users: box.values.toList(), + ), + ); } } } @@ -253,7 +302,8 @@ class UsersCubit extends ServerInstallationDependendCubit { Future deleteSshKey(final User user, final String publicKey) async { // All keys are deleted via api.deleteUserSshKey - final ApiResponse result = await api.deleteUserSshKey(user, publicKey); + final ApiResponse result = + await api.deleteUserSshKey(user, publicKey); if (result.isSuccess) { // If it is root user, delete key from root keys // If it is primary user, update primary user @@ -264,15 +314,17 @@ class UsersCubit extends ServerInstallationDependendCubit { .get(BNames.rootKeys, defaultValue: []) as List; rootKeys.remove(publicKey); serverInstallationBox.put(BNames.rootKeys, rootKeys); - emit(state.copyWith( - rootUser: User( - login: state.rootUser.login, - isFoundOnServer: true, - password: state.rootUser.password, - sshKeys: rootKeys, - note: state.rootUser.note, + emit( + state.copyWith( + rootUser: User( + login: state.rootUser.login, + isFoundOnServer: true, + password: state.rootUser.password, + sshKeys: rootKeys, + note: state.rootUser.note, + ), ), - ),); + ); return; } if (user.login == state.primaryUser.login) { @@ -287,9 +339,11 @@ class UsersCubit extends ServerInstallationDependendCubit { note: state.primaryUser.note, ); serverInstallationBox.put(BNames.rootUser, updatedUser); - emit(state.copyWith( - primaryUser: updatedUser, - ),); + emit( + state.copyWith( + primaryUser: updatedUser, + ), + ); return; } final List userKeys = List.from(user.sshKeys); @@ -302,15 +356,22 @@ class UsersCubit extends ServerInstallationDependendCubit { note: user.note, ); await box.putAt(box.values.toList().indexOf(user), updatedUser); - emit(state.copyWith( - users: box.values.toList(), - ),); + emit( + state.copyWith( + users: box.values.toList(), + ), + ); } } @override void clear() async { - emit(const UsersState( - [], User(login: 'root'), User(login: 'loading...'),),); + emit( + const UsersState( + [], + User(login: 'root'), + User(login: 'loading...'), + ), + ); } } diff --git a/lib/logic/cubit/users/users_state.dart b/lib/logic/cubit/users/users_state.dart index a02eb2c1..fa4ed1cd 100644 --- a/lib/logic/cubit/users/users_state.dart +++ b/lib/logic/cubit/users/users_state.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - part of 'users_cubit.dart'; class UsersState extends ServerInstallationDependendState { @@ -16,15 +14,17 @@ class UsersState extends ServerInstallationDependendState { final List? users, final User? rootUser, final User? primaryUser, - }) => UsersState( - users ?? this.users, - rootUser ?? this.rootUser, - primaryUser ?? this.primaryUser, - ); + }) => + UsersState( + users ?? this.users, + rootUser ?? this.rootUser, + primaryUser ?? this.primaryUser, + ); - bool isLoginRegistered(final String login) => users.any((final User user) => user.login == login) || - login == rootUser.login || - login == primaryUser.login; + bool isLoginRegistered(final String login) => + users.any((final User user) => user.login == login) || + login == rootUser.login || + login == primaryUser.login; bool get isEmpty => users.isEmpty; } diff --git a/lib/logic/get_it/api_config.dart b/lib/logic/get_it/api_config.dart index 6a03e2ef..3f3e5ac0 100644 --- a/lib/logic/get_it/api_config.dart +++ b/lib/logic/get_it/api_config.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:hive/hive.dart'; import 'package:selfprivacy/config/hive_config.dart'; import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart'; diff --git a/lib/logic/get_it/console.dart b/lib/logic/get_it/console.dart index 2fc67b7d..290f31ab 100644 --- a/lib/logic/get_it/console.dart +++ b/lib/logic/get_it/console.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:flutter/material.dart'; import 'package:selfprivacy/logic/models/message.dart'; diff --git a/lib/logic/models/hive/user.dart b/lib/logic/models/hive/user.dart index 74809f7e..942ce9fe 100644 --- a/lib/logic/models/hive/user.dart +++ b/lib/logic/models/hive/user.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'dart:ui'; import 'package:equatable/equatable.dart'; @@ -39,5 +37,6 @@ class User extends Equatable { Color get color => stringToColor(login); @override - String toString() => '$login, ${isFoundOnServer ? 'found' : 'not found'}, ${sshKeys.length} ssh keys, note: $note'; + String toString() => + '$login, ${isFoundOnServer ? 'found' : 'not found'}, ${sshKeys.length} ssh keys, note: $note'; } diff --git a/lib/logic/models/hive/user.g.dart b/lib/logic/models/hive/user.g.dart index 57c08555..d9b28d65 100644 --- a/lib/logic/models/hive/user.g.dart +++ b/lib/logic/models/hive/user.g.dart @@ -1,7 +1,5 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: always_specify_types - part of 'user.dart'; // ************************************************************************** diff --git a/lib/logic/models/job.dart b/lib/logic/models/job.dart index d64b79e2..b04d7d05 100644 --- a/lib/logic/models/job.dart +++ b/lib/logic/models/job.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:easy_localization/easy_localization.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; diff --git a/lib/logic/models/json/auto_upgrade_settings.dart b/lib/logic/models/json/auto_upgrade_settings.dart index 848c6437..421f9b88 100644 --- a/lib/logic/models/json/auto_upgrade_settings.dart +++ b/lib/logic/models/json/auto_upgrade_settings.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:equatable/equatable.dart'; import 'package:json_annotation/json_annotation.dart'; diff --git a/lib/logic/models/json/hetzner_server_info.dart b/lib/logic/models/json/hetzner_server_info.dart index b7e19346..ccf036a1 100644 --- a/lib/logic/models/json/hetzner_server_info.dart +++ b/lib/logic/models/json/hetzner_server_info.dart @@ -1,12 +1,9 @@ -// ignore_for_file: always_specify_types - import 'package:json_annotation/json_annotation.dart'; part 'hetzner_server_info.g.dart'; @JsonSerializable() class HetznerServerInfo { - HetznerServerInfo( this.id, this.name, @@ -41,7 +38,6 @@ class HetznerServerInfo { @JsonSerializable() class HetznerPublicNetInfo { - HetznerPublicNetInfo(this.ipv4); final HetznerIp4 ipv4; @@ -51,7 +47,6 @@ class HetznerPublicNetInfo { @JsonSerializable() class HetznerIp4 { - HetznerIp4(this.id, this.ip, this.blocked, this.reverseDns); final bool blocked; @JsonKey(name: 'dns_ptr') @@ -77,7 +72,6 @@ enum ServerStatus { @JsonSerializable() class HetznerServerTypeInfo { - HetznerServerTypeInfo(this.cores, this.memory, this.disk, this.prices); final int cores; final num memory; @@ -102,12 +96,12 @@ class HetznerPriceInfo { static HetznerPriceInfo fromJson(final Map json) => _$HetznerPriceInfoFromJson(json); - static double getPrice(final Map json) => double.parse(json['gross'] as String); + static double getPrice(final Map json) => + double.parse(json['gross'] as String); } @JsonSerializable() class HetznerLocation { - HetznerLocation(this.country, this.city, this.description, this.zone); final String country; final String city; diff --git a/lib/logic/models/json/recovery_token_status.dart b/lib/logic/models/json/recovery_token_status.dart index 2c455480..6e59b57d 100644 --- a/lib/logic/models/json/recovery_token_status.dart +++ b/lib/logic/models/json/recovery_token_status.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:equatable/equatable.dart'; import 'package:json_annotation/json_annotation.dart'; @@ -7,7 +5,6 @@ part 'recovery_token_status.g.dart'; @JsonSerializable() class RecoveryKeyStatus extends Equatable { - factory RecoveryKeyStatus.fromJson(final Map json) => _$RecoveryKeyStatusFromJson(json); const RecoveryKeyStatus({ diff --git a/lib/logic/models/json/server_configurations.dart b/lib/logic/models/json/server_configurations.dart index 91f5f65d..8b4029ab 100644 --- a/lib/logic/models/json/server_configurations.dart +++ b/lib/logic/models/json/server_configurations.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:equatable/equatable.dart'; import 'package:json_annotation/json_annotation.dart'; @@ -7,7 +5,6 @@ part 'server_configurations.g.dart'; @JsonSerializable(createToJson: true) class AutoUpgradeConfigurations extends Equatable { - factory AutoUpgradeConfigurations.fromJson(final Map json) => _$AutoUpgradeConfigurationsFromJson(json); const AutoUpgradeConfigurations({ diff --git a/lib/logic/models/message.dart b/lib/logic/models/message.dart index 44f30b4d..8bbc6dfd 100644 --- a/lib/logic/models/message.dart +++ b/lib/logic/models/message.dart @@ -4,16 +4,14 @@ final DateFormat formatter = DateFormat('hh:mm'); class Message { Message({this.text, this.type = MessageType.normal}) : time = DateTime.now(); + Message.warn({this.text}) + : type = MessageType.warning, + time = DateTime.now(); final String? text; final DateTime time; final MessageType type; String get timeString => formatter.format(time); - - static Message warn({final String? text}) => Message( - text: text, - type: MessageType.warning, - ); } enum MessageType { diff --git a/lib/logic/models/provider.dart b/lib/logic/models/provider.dart index 4e3191eb..6feb175b 100644 --- a/lib/logic/models/provider.dart +++ b/lib/logic/models/provider.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:equatable/equatable.dart'; import 'package:flutter/widgets.dart'; import 'package:selfprivacy/logic/models/state_types.dart'; diff --git a/lib/logic/models/server_basic_info.dart b/lib/logic/models/server_basic_info.dart index 7f0f2e1b..8670dc8c 100644 --- a/lib/logic/models/server_basic_info.dart +++ b/lib/logic/models/server_basic_info.dart @@ -1,7 +1,4 @@ -// ignore_for_file: always_specify_types - class ServerBasicInfo { - ServerBasicInfo({ required this.id, required this.name, @@ -19,7 +16,6 @@ class ServerBasicInfo { } class ServerBasicInfoWithValidators extends ServerBasicInfo { - ServerBasicInfoWithValidators.fromServerBasicInfo({ required final ServerBasicInfo serverBasicInfo, required final isIpValid, diff --git a/lib/logic/models/timezone_settings.dart b/lib/logic/models/timezone_settings.dart index 45348b64..22c84b44 100644 --- a/lib/logic/models/timezone_settings.dart +++ b/lib/logic/models/timezone_settings.dart @@ -1,9 +1,6 @@ -// ignore_for_file: always_specify_types - import 'package:timezone/timezone.dart'; class TimeZoneSettings { - factory TimeZoneSettings.fromString(final String string) { final Location location = timeZoneDatabase.locations[string]!; return TimeZoneSettings(location); @@ -13,6 +10,6 @@ class TimeZoneSettings { final Location timezone; Map toJson() => { - 'timezone': timezone.name, - }; + 'timezone': timezone.name, + }; } diff --git a/lib/main.dart b/lib/main.dart index f7234d26..f2c36392 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -46,11 +44,14 @@ void main() async { ); BlocOverrides.runZoned( - () => runApp(Localization( + () => runApp( + Localization( child: MyApp( - lightThemeData: lightThemeData, - darkThemeData: darkThemeData, - ),),), + lightThemeData: lightThemeData, + darkThemeData: darkThemeData, + ), + ), + ), blocObserver: SimpleBlocObserver(), ); } @@ -67,11 +68,15 @@ class MyApp extends StatelessWidget { @override Widget build(final BuildContext context) => Localization( - child: AnnotatedRegion( - value: SystemUiOverlayStyle.light, // Manually changing appbar color - child: BlocAndProviderConfig( - child: BlocBuilder( - builder: (final BuildContext context, final AppSettingsState appSettings) => MaterialApp( + child: AnnotatedRegion( + value: SystemUiOverlayStyle.light, // Manually changing appbar color + child: BlocAndProviderConfig( + child: BlocBuilder( + builder: ( + final BuildContext context, + final AppSettingsState appSettings, + ) => + MaterialApp( scaffoldMessengerKey: getIt.get().scaffoldMessengerKey, navigatorKey: getIt.get().navigatorKey, @@ -97,8 +102,8 @@ class MyApp extends StatelessWidget { return widget!; }, ), + ), ), ), - ), - ); + ); } diff --git a/lib/theming/factory/app_theme_factory.dart b/lib/theming/factory/app_theme_factory.dart index 92979267..48f4b086 100644 --- a/lib/theming/factory/app_theme_factory.dart +++ b/lib/theming/factory/app_theme_factory.dart @@ -1,22 +1,22 @@ -// ignore_for_file: always_specify_types - import 'dart:io'; import 'package:dynamic_color/dynamic_color.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:material_color_utilities/palettes/core_palette.dart'; import 'package:system_theme/system_theme.dart'; import 'package:gtk_theme_fl/gtk_theme_fl.dart'; abstract class AppThemeFactory { AppThemeFactory._(); - static Future create( - {required final bool isDark, required final Color fallbackColor,}) => _createAppTheme( - isDark: isDark, - fallbackColor: fallbackColor, - ); + static Future create({ + required final bool isDark, + required final Color fallbackColor, + }) => + _createAppTheme( + isDark: isDark, + fallbackColor: fallbackColor, + ); static Future _createAppTheme({ required final Color fallbackColor, @@ -25,7 +25,8 @@ abstract class AppThemeFactory { ColorScheme? gtkColorsScheme; final Brightness brightness = isDark ? Brightness.dark : Brightness.light; - final ColorScheme? dynamicColorsScheme = await _getDynamicColors(brightness); + final ColorScheme? dynamicColorsScheme = + await _getDynamicColors(brightness); if (Platform.isLinux) { final GtkThemeData themeData = await GtkThemeData.initialize(); @@ -77,7 +78,8 @@ abstract class AppThemeFactory { static Future _getDynamicColors(final Brightness brightness) { try { return DynamicColorPlugin.getCorePalette().then( - (final CorePalette? corePallet) => corePallet?.toColorScheme(brightness: brightness),); + (final corePallet) => corePallet?.toColorScheme(brightness: brightness), + ); } on PlatformException { return Future.value(null); } diff --git a/lib/ui/components/action_button/action_button.dart b/lib/ui/components/action_button/action_button.dart index 580a69fb..3a518496 100644 --- a/lib/ui/components/action_button/action_button.dart +++ b/lib/ui/components/action_button/action_button.dart @@ -24,7 +24,7 @@ class ActionButton extends StatelessWidget { ), onPressed: () { navigator.pop(); - if (onPressed != null) onPressed!(); + onPressed?.call(); }, ); } diff --git a/lib/ui/components/brand_bottom_sheet/brand_bottom_sheet.dart b/lib/ui/components/brand_bottom_sheet/brand_bottom_sheet.dart index d5c6afbe..de322b05 100644 --- a/lib/ui/components/brand_bottom_sheet/brand_bottom_sheet.dart +++ b/lib/ui/components/brand_bottom_sheet/brand_bottom_sheet.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:flutter/material.dart'; import 'package:selfprivacy/config/brand_colors.dart'; diff --git a/lib/ui/components/brand_button/brand_button.dart b/lib/ui/components/brand_button/brand_button.dart index 55d7fddc..8951b70f 100644 --- a/lib/ui/components/brand_button/brand_button.dart +++ b/lib/ui/components/brand_button/brand_button.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:flutter/material.dart'; import 'package:selfprivacy/ui/components/brand_button/filled_button.dart'; import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; @@ -42,13 +40,13 @@ class BrandButton { child: TextButton(onPressed: onPressed, child: Text(title)), ); - static _IconTextButton emptyWithIconText({ + static IconTextButton emptyWithIconText({ required final VoidCallback onPressed, required final String title, required final Icon icon, final Key? key, }) => - _IconTextButton( + IconTextButton( key: key, title: title, onPressed: onPressed, @@ -56,8 +54,13 @@ class BrandButton { ); } -class _IconTextButton extends StatelessWidget { - const _IconTextButton({final super.key, this.onPressed, this.title, this.icon}); +class IconTextButton extends StatelessWidget { + const IconTextButton({ + final super.key, + this.onPressed, + this.title, + this.icon, + }); final VoidCallback? onPressed; final String? title; @@ -65,24 +68,24 @@ class _IconTextButton extends StatelessWidget { @override Widget build(final BuildContext context) => Material( - color: Colors.transparent, - child: InkWell( - onTap: onPressed, - child: Container( - height: 48, - width: double.infinity, - alignment: Alignment.center, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - BrandText.body1(title), - Padding( - padding: const EdgeInsets.all(12.0), - child: icon, - ) - ], + color: Colors.transparent, + child: InkWell( + onTap: onPressed, + child: Container( + height: 48, + width: double.infinity, + alignment: Alignment.center, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + BrandText.body1(title), + Padding( + padding: const EdgeInsets.all(12.0), + child: icon, + ) + ], + ), ), ), - ), - ); + ); } diff --git a/lib/ui/components/brand_cards/brand_cards.dart b/lib/ui/components/brand_cards/brand_cards.dart index 138a674a..d8f48088 100644 --- a/lib/ui/components/brand_cards/brand_cards.dart +++ b/lib/ui/components/brand_cards/brand_cards.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:flutter/material.dart'; class BrandCards { @@ -24,8 +22,10 @@ class BrandCards { static Widget outlined({required final Widget child}) => _OutlinedCard( child: child, ); - static Widget filled( - {required final Widget child, final bool tertiary = false,}) => + static Widget filled({ + required final Widget child, + final bool tertiary = false, + }) => _FilledCard( tertiary: tertiary, child: child, @@ -38,7 +38,6 @@ class _BrandCard extends StatelessWidget { required this.padding, required this.shadow, required this.borderRadius, - final super.key, }); final Widget child; @@ -60,7 +59,6 @@ class _BrandCard extends StatelessWidget { class _OutlinedCard extends StatelessWidget { const _OutlinedCard({ - final super.key, required this.child, }); @@ -83,7 +81,6 @@ class _FilledCard extends StatelessWidget { const _FilledCard({ required this.child, required this.tertiary, - final super.key, }); final Widget child; diff --git a/lib/ui/components/brand_divider/brand_divider.dart b/lib/ui/components/brand_divider/brand_divider.dart index c3a3b5a3..03e44653 100644 --- a/lib/ui/components/brand_divider/brand_divider.dart +++ b/lib/ui/components/brand_divider/brand_divider.dart @@ -2,12 +2,12 @@ import 'package:flutter/material.dart'; import 'package:selfprivacy/config/brand_colors.dart'; class BrandDivider extends StatelessWidget { - const BrandDivider({super.key}); + const BrandDivider({final super.key}); @override Widget build(final BuildContext context) => Container( - width: double.infinity, - height: 1, - color: BrandColors.dividerColor, - ); + width: double.infinity, + height: 1, + color: BrandColors.dividerColor, + ); } diff --git a/lib/ui/components/brand_header/brand_header.dart b/lib/ui/components/brand_header/brand_header.dart index 7e0bd3e8..7366298b 100644 --- a/lib/ui/components/brand_header/brand_header.dart +++ b/lib/ui/components/brand_header/brand_header.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:flutter/material.dart'; import 'package:selfprivacy/ui/components/brand_icons/brand_icons.dart'; import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; @@ -18,24 +16,24 @@ class BrandHeader extends StatelessWidget { @override Widget build(final BuildContext context) => Container( - height: 52, - alignment: Alignment.centerLeft, - padding: EdgeInsets.only( - left: hasBackButton ? 1 : 15, - ), - child: Row( - children: [ - if (hasBackButton) ...[ - IconButton( - icon: const Icon(BrandIcons.arrowLeft), - onPressed: - onBackButtonPressed ?? () => Navigator.of(context).pop(), - ), - const SizedBox(width: 10), + height: 52, + alignment: Alignment.centerLeft, + padding: EdgeInsets.only( + left: hasBackButton ? 1 : 15, + ), + child: Row( + children: [ + if (hasBackButton) ...[ + IconButton( + icon: const Icon(BrandIcons.arrowLeft), + onPressed: + onBackButtonPressed ?? () => Navigator.of(context).pop(), + ), + const SizedBox(width: 10), + ], + BrandText.h4(title), + const Spacer(), ], - BrandText.h4(title), - const Spacer(), - ], - ), - ); + ), + ); } diff --git a/lib/ui/components/brand_hero_screen/brand_hero_screen.dart b/lib/ui/components/brand_hero_screen/brand_hero_screen.dart index 5061ec63..cdccc8d2 100644 --- a/lib/ui/components/brand_hero_screen/brand_hero_screen.dart +++ b/lib/ui/components/brand_hero_screen/brand_hero_screen.dart @@ -25,48 +25,50 @@ class BrandHeroScreen extends StatelessWidget { final VoidCallback? onBackButtonPressed; @override - Widget build(BuildContext context) => SafeArea( - child: Scaffold( - appBar: PreferredSize( - preferredSize: const Size.fromHeight(52.0), - child: BrandHeader( - title: headerTitle, - hasBackButton: hasBackButton, - onBackButtonPressed: onBackButtonPressed, + Widget build(final BuildContext context) => SafeArea( + child: Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(52.0), + child: BrandHeader( + title: headerTitle, + hasBackButton: hasBackButton, + onBackButtonPressed: onBackButtonPressed, + ), ), - ), - floatingActionButton: hasFlashButton ? const BrandFab() : null, - body: ListView( - padding: const EdgeInsets.all(16.0), - children: [ - if (heroIcon != null) - Container( - alignment: Alignment.bottomLeft, - child: Icon( - heroIcon, - size: 48.0, + floatingActionButton: hasFlashButton ? const BrandFab() : null, + body: ListView( + padding: const EdgeInsets.all(16.0), + children: [ + if (heroIcon != null) + Container( + alignment: Alignment.bottomLeft, + child: Icon( + heroIcon, + size: 48.0, + ), ), - ), - const SizedBox(height: 8.0), - if (heroTitle != null) - Text( - heroTitle!, - style: Theme.of(context).textTheme.headlineMedium!.copyWith( - color: Theme.of(context).colorScheme.onBackground, - ), - textAlign: TextAlign.start, - ), - const SizedBox(height: 8.0), - if (heroSubtitle != null) - Text(heroSubtitle!, + const SizedBox(height: 8.0), + if (heroTitle != null) + Text( + heroTitle!, + style: Theme.of(context).textTheme.headlineMedium!.copyWith( + color: Theme.of(context).colorScheme.onBackground, + ), + textAlign: TextAlign.start, + ), + const SizedBox(height: 8.0), + if (heroSubtitle != null) + Text( + heroSubtitle!, style: Theme.of(context).textTheme.bodyMedium!.copyWith( color: Theme.of(context).colorScheme.onBackground, ), - textAlign: TextAlign.start,), - const SizedBox(height: 16.0), - ...children, - ], + textAlign: TextAlign.start, + ), + const SizedBox(height: 16.0), + ...children, + ], + ), ), - ), - ); + ); } diff --git a/lib/ui/components/brand_loader/brand_loader.dart b/lib/ui/components/brand_loader/brand_loader.dart index 5dc6a6ea..59f1f177 100644 --- a/lib/ui/components/brand_loader/brand_loader.dart +++ b/lib/ui/components/brand_loader/brand_loader.dart @@ -2,17 +2,19 @@ import 'package:flutter/material.dart'; import 'package:easy_localization/easy_localization.dart'; class BrandLoader { - static _HorizontalLoader horizontal() => _HorizontalLoader(); + static HorizontalLoader horizontal() => const HorizontalLoader(); } -class _HorizontalLoader extends StatelessWidget { +class HorizontalLoader extends StatelessWidget { + const HorizontalLoader({final super.key}); + @override Widget build(final BuildContext context) => Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text('basis.wait'.tr()), - const SizedBox(height: 10), - const LinearProgressIndicator(minHeight: 3), - ], - ); + mainAxisSize: MainAxisSize.min, + children: [ + Text('basis.wait'.tr()), + const SizedBox(height: 10), + const LinearProgressIndicator(minHeight: 3), + ], + ); } diff --git a/lib/ui/components/brand_radio/brand_radio.dart b/lib/ui/components/brand_radio/brand_radio.dart index aca55505..60f41fb5 100644 --- a/lib/ui/components/brand_radio/brand_radio.dart +++ b/lib/ui/components/brand_radio/brand_radio.dart @@ -3,36 +3,36 @@ import 'package:selfprivacy/config/brand_colors.dart'; class BrandRadio extends StatelessWidget { const BrandRadio({ - super.key, required this.isChecked, + final super.key, }); final bool isChecked; @override Widget build(final BuildContext context) => Container( - height: 20, - width: 20, - alignment: Alignment.center, - padding: const EdgeInsets.all(2), - decoration: BoxDecoration( - shape: BoxShape.circle, - border: _getBorder(), - ), - child: isChecked - ? Container( - height: 10, - width: 10, - decoration: const BoxDecoration( - shape: BoxShape.circle, - color: BrandColors.primary, - ), - ) - : null, - ); + height: 20, + width: 20, + alignment: Alignment.center, + padding: const EdgeInsets.all(2), + decoration: BoxDecoration( + shape: BoxShape.circle, + border: _getBorder(), + ), + child: isChecked + ? Container( + height: 10, + width: 10, + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: BrandColors.primary, + ), + ) + : null, + ); BoxBorder? _getBorder() => Border.all( - color: isChecked ? BrandColors.primary : BrandColors.gray1, - width: 2, - ); + color: isChecked ? BrandColors.primary : BrandColors.gray1, + width: 2, + ); } diff --git a/lib/ui/components/brand_radio_tile/brand_radio_tile.dart b/lib/ui/components/brand_radio_tile/brand_radio_tile.dart index 17b3ccff..5b18247d 100644 --- a/lib/ui/components/brand_radio_tile/brand_radio_tile.dart +++ b/lib/ui/components/brand_radio_tile/brand_radio_tile.dart @@ -4,10 +4,10 @@ import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; class BrandRadioTile extends StatelessWidget { const BrandRadioTile({ - super.key, required this.isChecked, required this.text, required this.onPress, + final super.key, }); final bool isChecked; @@ -16,20 +16,20 @@ class BrandRadioTile extends StatelessWidget { final VoidCallback onPress; @override - Widget build(BuildContext context) => GestureDetector( - onTap: onPress, - behavior: HitTestBehavior.translucent, - child: Padding( - padding: const EdgeInsets.all(2), - child: Row( - children: [ - BrandRadio( - isChecked: isChecked, - ), - const SizedBox(width: 9), - BrandText.h5(text) - ], + Widget build(final BuildContext context) => GestureDetector( + onTap: onPress, + behavior: HitTestBehavior.translucent, + child: Padding( + padding: const EdgeInsets.all(2), + child: Row( + children: [ + BrandRadio( + isChecked: isChecked, + ), + const SizedBox(width: 9), + BrandText.h5(text) + ], + ), ), - ), - ); + ); } diff --git a/lib/ui/components/brand_span_button/brand_span_button.dart b/lib/ui/components/brand_span_button/brand_span_button.dart index da36ee02..de19730e 100644 --- a/lib/ui/components/brand_span_button/brand_span_button.dart +++ b/lib/ui/components/brand_span_button/brand_span_button.dart @@ -14,18 +14,18 @@ class BrandSpanButton extends TextSpan { style: (style ?? const TextStyle()).copyWith(color: BrandColors.blue), ); - static BrandSpanButton link({ + BrandSpanButton.link({ required final String text, final String? urlString, final TextStyle? style, - }) => - BrandSpanButton( - text: text, - style: style, - onTap: () => _launchURL(urlString ?? text), - ); + }) : super( + recognizer: TapGestureRecognizer() + ..onTap = () => _launchURL(urlString ?? text), + text: text, + style: (style ?? const TextStyle()).copyWith(color: BrandColors.blue), + ); - static _launchURL(final String link) async { + static Future _launchURL(final String link) async { if (await canLaunchUrl(Uri.parse(link))) { await launchUrl(Uri.parse(link)); } else { diff --git a/lib/ui/components/brand_switch/brand_switch.dart b/lib/ui/components/brand_switch/brand_switch.dart index deb595a4..89396acc 100644 --- a/lib/ui/components/brand_switch/brand_switch.dart +++ b/lib/ui/components/brand_switch/brand_switch.dart @@ -11,9 +11,9 @@ class BrandSwitch extends StatelessWidget { final bool value; @override - Widget build(BuildContext context) => Switch( - activeColor: Theme.of(context).colorScheme.primary, - value: value, - onChanged: onChanged, - ); + Widget build(final BuildContext context) => Switch( + activeColor: Theme.of(context).colorScheme.primary, + value: value, + onChanged: onChanged, + ); } diff --git a/lib/ui/components/brand_tab_bar/brand_tab_bar.dart b/lib/ui/components/brand_tab_bar/brand_tab_bar.dart index e1a03062..194c0ac1 100644 --- a/lib/ui/components/brand_tab_bar/brand_tab_bar.dart +++ b/lib/ui/components/brand_tab_bar/brand_tab_bar.dart @@ -19,7 +19,7 @@ class _BrandTabBarState extends State { super.initState(); } - _listener() { + void _listener() { if (currentIndex != widget.controller!.index) { setState(() { currentIndex = widget.controller!.index; @@ -35,21 +35,26 @@ class _BrandTabBarState extends State { @override Widget build(final BuildContext context) => NavigationBar( - destinations: [ - _getIconButton('basis.providers'.tr(), BrandIcons.server, 0), - _getIconButton('basis.services'.tr(), BrandIcons.box, 1), - _getIconButton('basis.users'.tr(), BrandIcons.users, 2), - _getIconButton('basis.more'.tr(), Icons.menu_rounded, 3), - ], - onDestinationSelected: (final index) { - widget.controller!.animateTo(index); - }, - selectedIndex: currentIndex ?? 0, - labelBehavior: NavigationDestinationLabelBehavior.onlyShowSelected, - ); + destinations: [ + _getIconButton('basis.providers'.tr(), BrandIcons.server, 0), + _getIconButton('basis.services'.tr(), BrandIcons.box, 1), + _getIconButton('basis.users'.tr(), BrandIcons.users, 2), + _getIconButton('basis.more'.tr(), Icons.menu_rounded, 3), + ], + onDestinationSelected: (final index) { + widget.controller!.animateTo(index); + }, + selectedIndex: currentIndex ?? 0, + labelBehavior: NavigationDestinationLabelBehavior.onlyShowSelected, + ); - NavigationDestination _getIconButton(final String label, final IconData iconData, final int index) => NavigationDestination( - icon: Icon(iconData), - label: label, - ); + NavigationDestination _getIconButton( + final String label, + final IconData iconData, + final int index, + ) => + NavigationDestination( + icon: Icon(iconData), + label: label, + ); } diff --git a/lib/ui/components/brand_text/brand_text.dart b/lib/ui/components/brand_text/brand_text.dart index b64ed1c4..544ffcec 100644 --- a/lib/ui/components/brand_text/brand_text.dart +++ b/lib/ui/components/brand_text/brand_text.dart @@ -33,13 +33,20 @@ class BrandText extends StatelessWidget { textAlign: textAlign, ); - factory BrandText.onboardingTitle(final String text, {final TextStyle? style}) => + factory BrandText.onboardingTitle( + final String text, { + final TextStyle? style, + }) => BrandText( text, type: TextType.onboardingTitle, style: style, ); - factory BrandText.h3(final String text, {final TextStyle? style, final TextAlign? textAlign}) => + factory BrandText.h3( + final String text, { + final TextStyle? style, + final TextAlign? textAlign, + }) => BrandText( text, type: TextType.h3, @@ -85,22 +92,28 @@ class BrandText extends StatelessWidget { style: style, textAlign: textAlign, ); - factory BrandText.body1(final String? text, {final TextStyle? style}) => BrandText( + factory BrandText.body1(final String? text, {final TextStyle? style}) => + BrandText( text, type: TextType.body1, style: style, ); - factory BrandText.small(final String text, {final TextStyle? style}) => BrandText( + factory BrandText.small(final String text, {final TextStyle? style}) => + BrandText( text, type: TextType.small, style: style, ); - factory BrandText.body2(final String? text, {final TextStyle? style}) => BrandText( + factory BrandText.body2(final String? text, {final TextStyle? style}) => + BrandText( text, type: TextType.body2, style: style, ); - factory BrandText.buttonTitleText(final String? text, {final TextStyle? style}) => + factory BrandText.buttonTitleText( + final String? text, { + final TextStyle? style, + }) => BrandText( text, type: TextType.buttonTitleText, @@ -118,8 +131,11 @@ class BrandText extends StatelessWidget { style: style, textAlign: textAlign, ); - factory BrandText.medium(final String? text, - {final TextStyle? style, final TextAlign? textAlign}) => + factory BrandText.medium( + final String? text, { + final TextStyle? style, + final TextAlign? textAlign, + }) => BrandText( text, type: TextType.medium, @@ -128,9 +144,9 @@ class BrandText extends StatelessWidget { ); const BrandText( this.text, { - super.key, - this.style, required this.type, + final super.key, + this.style, this.overflow, this.softWrap, this.textAlign, diff --git a/lib/ui/components/brand_timer/brand_timer.dart b/lib/ui/components/brand_timer/brand_timer.dart index b2ed1406..5d76d57d 100644 --- a/lib/ui/components/brand_timer/brand_timer.dart +++ b/lib/ui/components/brand_timer/brand_timer.dart @@ -7,9 +7,9 @@ import 'package:selfprivacy/utils/named_font_weight.dart'; class BrandTimer extends StatefulWidget { const BrandTimer({ - super.key, required this.startDateTime, required this.duration, + final super.key, }); final DateTime startDateTime; @@ -29,10 +29,11 @@ class _BrandTimerState extends State { super.initState(); } - _timerStart() { + void _timerStart() { _timeString = differenceFromStart; timer = Timer.periodic(const Duration(seconds: 1), (final Timer t) { - final Duration timePassed = DateTime.now().difference(widget.startDateTime); + final Duration timePassed = + DateTime.now().difference(widget.startDateTime); if (timePassed > widget.duration) { t.cancel(); } else { @@ -52,11 +53,11 @@ class _BrandTimerState extends State { @override Widget build(final BuildContext context) => BrandText.medium( - _timeString, - style: const TextStyle( - fontWeight: NamedFontWeight.demiBold, - ), - ); + _timeString, + style: const TextStyle( + fontWeight: NamedFontWeight.demiBold, + ), + ); void _getTime() { setState(() { diff --git a/lib/ui/components/icon_status_mask/icon_status_mask.dart b/lib/ui/components/icon_status_mask/icon_status_mask.dart index b781c3d1..0c507ede 100644 --- a/lib/ui/components/icon_status_mask/icon_status_mask.dart +++ b/lib/ui/components/icon_status_mask/icon_status_mask.dart @@ -4,9 +4,9 @@ import 'package:selfprivacy/logic/models/state_types.dart'; class IconStatusMask extends StatelessWidget { const IconStatusMask({ - super.key, required this.child, required this.status, + final super.key, }); final Icon child; diff --git a/lib/ui/components/jobs_content/jobs_content.dart b/lib/ui/components/jobs_content/jobs_content.dart index e15fad3a..bd8166de 100644 --- a/lib/ui/components/jobs_content/jobs_content.dart +++ b/lib/ui/components/jobs_content/jobs_content.dart @@ -13,106 +13,113 @@ import 'package:selfprivacy/ui/components/brand_loader/brand_loader.dart'; import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; class JobsContent extends StatelessWidget { - const JobsContent({super.key}); + const JobsContent({final super.key}); @override Widget build(final BuildContext context) => BlocBuilder( - builder: (final context, final state) { - late List widgets; - final ServerInstallationState installationState = context.read().state; - if (state is JobsStateEmpty) { - widgets = [ - const SizedBox(height: 80), - Center(child: BrandText.body1('jobs.empty'.tr())), - ]; - - if (installationState is ServerInstallationFinished) { + builder: (final context, final state) { + late List widgets; + final ServerInstallationState installationState = + context.read().state; + if (state is JobsStateEmpty) { widgets = [ - ...widgets, const SizedBox(height: 80), - BrandButton.rised( - onPressed: () => context.read().upgradeServer(), - text: 'jobs.upgradeServer'.tr(), - ), - const SizedBox(height: 10), - BrandButton.text( - onPressed: () { - final NavigationService nav = getIt(); - nav.showPopUpDialog(BrandAlert( - title: 'jobs.rebootServer'.tr(), - contentText: 'modals.3'.tr(), - actions: [ - ActionButton( - text: 'basis.cancel'.tr(), + Center(child: BrandText.body1('jobs.empty'.tr())), + ]; + + if (installationState is ServerInstallationFinished) { + widgets = [ + ...widgets, + const SizedBox(height: 80), + BrandButton.rised( + onPressed: () => context.read().upgradeServer(), + text: 'jobs.upgradeServer'.tr(), + ), + const SizedBox(height: 10), + BrandButton.text( + onPressed: () { + final NavigationService nav = getIt(); + nav.showPopUpDialog( + BrandAlert( + title: 'jobs.rebootServer'.tr(), + contentText: 'modals.3'.tr(), + actions: [ + ActionButton( + text: 'basis.cancel'.tr(), + ), + ActionButton( + onPressed: () => + {context.read().rebootServer()}, + text: 'modals.9'.tr(), + ) + ], ), - ActionButton( - onPressed: () => - {context.read().rebootServer()}, - text: 'modals.9'.tr(), - ) - ], - ),); - }, - title: 'jobs.rebootServer'.tr(), + ); + }, + title: 'jobs.rebootServer'.tr(), + ), + ]; + } + } else if (state is JobsStateLoading) { + widgets = [ + const SizedBox(height: 80), + BrandLoader.horizontal(), + ]; + } else if (state is JobsStateWithJobs) { + widgets = [ + ...state.jobList + .map( + (final j) => Row( + children: [ + Expanded( + child: BrandCards.small( + child: Text(j.title), + ), + ), + const SizedBox(width: 10), + ElevatedButton( + style: ElevatedButton.styleFrom( + primary: + Theme.of(context).colorScheme.errorContainer, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + onPressed: () => + context.read().removeJob(j.id), + child: Text( + 'basis.remove'.tr(), + style: TextStyle( + color: Theme.of(context) + .colorScheme + .onErrorContainer, + ), + ), + ), + ], + ), + ) + .toList(), + const SizedBox(height: 20), + BrandButton.rised( + onPressed: () => context.read().applyAll(), + text: 'jobs.start'.tr(), ), ]; } - } else if (state is JobsStateLoading) { - widgets = [ - const SizedBox(height: 80), - BrandLoader.horizontal(), - ]; - } else if (state is JobsStateWithJobs) { - widgets = [ - ...state.jobList - .map( - (final j) => Row( - children: [ - Expanded( - child: BrandCards.small( - child: Text(j.title), - ), - ), - const SizedBox(width: 10), - ElevatedButton( - style: ElevatedButton.styleFrom( - primary: Theme.of(context).colorScheme.errorContainer, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - ), - onPressed: () => - context.read().removeJob(j.id), - child: Text('basis.remove'.tr(), - style: TextStyle( - color: Theme.of(context) - .colorScheme - .onErrorContainer,),), - ), - ], - ), - ) - .toList(), - const SizedBox(height: 20), - BrandButton.rised( - onPressed: () => context.read().applyAll(), - text: 'jobs.start'.tr(), - ), - ]; - } - return ListView( - padding: paddingH15V0, - children: [ - const SizedBox(height: 15), - Center( - child: BrandText.h2( - 'jobs.title'.tr(), + return ListView( + padding: paddingH15V0, + children: [ + const SizedBox(height: 15), + Center( + child: BrandText.h2( + 'jobs.title'.tr(), + ), ), - ), - const SizedBox(height: 20), - ...widgets - ], - ); - }, - ); + const SizedBox(height: 20), + ...widgets + ], + ); + }, + ); } diff --git a/lib/ui/components/not_ready_card/not_ready_card.dart b/lib/ui/components/not_ready_card/not_ready_card.dart index dd91f4ab..49947c1b 100644 --- a/lib/ui/components/not_ready_card/not_ready_card.dart +++ b/lib/ui/components/not_ready_card/not_ready_card.dart @@ -6,47 +6,49 @@ import 'package:selfprivacy/utils/route_transitions/basic.dart'; import 'package:easy_localization/easy_localization.dart'; class NotReadyCard extends StatelessWidget { - const NotReadyCard({super.key}); + const NotReadyCard({final super.key}); @override Widget build(final BuildContext context) => Container( - padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), color: BrandColors.gray6,), - child: RichText( - text: TextSpan( - children: [ - TextSpan( - text: 'not_ready_card.1'.tr(), - style: const TextStyle(color: BrandColors.white), - ), - WidgetSpan( - child: Padding( - padding: const EdgeInsets.only(bottom: 0.5), - child: GestureDetector( - onTap: () => Navigator.of(context).push( - materialRoute( - const InitializingPage(), + padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + color: BrandColors.gray6, + ), + child: RichText( + text: TextSpan( + children: [ + TextSpan( + text: 'not_ready_card.1'.tr(), + style: const TextStyle(color: BrandColors.white), + ), + WidgetSpan( + child: Padding( + padding: const EdgeInsets.only(bottom: 0.5), + child: GestureDetector( + onTap: () => Navigator.of(context).push( + materialRoute( + const InitializingPage(), + ), ), - ), - child: Text( - 'not_ready_card.2'.tr(), - style: body1Style.copyWith( - color: Colors.white, - fontWeight: FontWeight.bold, - decoration: TextDecoration.underline, - // height: 1.1, + child: Text( + 'not_ready_card.2'.tr(), + style: body1Style.copyWith( + color: Colors.white, + fontWeight: FontWeight.bold, + decoration: TextDecoration.underline, + // height: 1.1, + ), ), ), ), ), - ), - TextSpan( - text: 'not_ready_card.3'.tr(), - style: const TextStyle(color: BrandColors.white), - ), - ], + TextSpan( + text: 'not_ready_card.3'.tr(), + style: const TextStyle(color: BrandColors.white), + ), + ], + ), ), - ), - ); + ); } diff --git a/lib/ui/components/one_page/one_page.dart b/lib/ui/components/one_page/one_page.dart index 66792716..d16dd5f3 100644 --- a/lib/ui/components/one_page/one_page.dart +++ b/lib/ui/components/one_page/one_page.dart @@ -6,9 +6,9 @@ import 'package:selfprivacy/ui/components/pre_styled_buttons/pre_styled_buttons. class OnePage extends StatelessWidget { const OnePage({ - super.key, required this.title, required this.child, + final super.key, }); final String title; @@ -16,32 +16,33 @@ class OnePage extends StatelessWidget { @override Widget build(final BuildContext context) => Scaffold( - appBar: PreferredSize( - preferredSize: const Size.fromHeight(52), - child: Column( - children: [ - Container( - height: 51, - alignment: Alignment.center, - padding: const EdgeInsets.symmetric(horizontal: 15), - child: BrandText.h4('basis.details'.tr()), - ), - const BrandDivider(), - ], - ), - ), - body: child, - bottomNavigationBar: SafeArea( - child: Container( - decoration: BoxDecoration(boxShadow: kElevationToShadow[3]), - height: kBottomNavigationBarHeight, - child: Container( - color: Theme.of(context).scaffoldBackgroundColor, - alignment: Alignment.center, - child: PreStyledButtons.close( - onPress: () => Navigator.of(context).pop(),), + appBar: PreferredSize( + preferredSize: const Size.fromHeight(52), + child: Column( + children: [ + Container( + height: 51, + alignment: Alignment.center, + padding: const EdgeInsets.symmetric(horizontal: 15), + child: BrandText.h4('basis.details'.tr()), + ), + const BrandDivider(), + ], ), ), - ), - ); + body: child, + bottomNavigationBar: SafeArea( + child: Container( + decoration: BoxDecoration(boxShadow: kElevationToShadow[3]), + height: kBottomNavigationBarHeight, + child: Container( + color: Theme.of(context).scaffoldBackgroundColor, + alignment: Alignment.center, + child: PreStyledButtons.close( + onPress: () => Navigator.of(context).pop(), + ), + ), + ), + ), + ); } diff --git a/lib/ui/components/pre_styled_buttons/close.dart b/lib/ui/components/pre_styled_buttons/close.dart index 3beb2eb4..48a1bddb 100644 --- a/lib/ui/components/pre_styled_buttons/close.dart +++ b/lib/ui/components/pre_styled_buttons/close.dart @@ -1,19 +1,19 @@ part of 'pre_styled_buttons.dart'; class _CloseButton extends StatelessWidget { - const _CloseButton({super.key, required this.onPress}); + const _CloseButton({required this.onPress}); final VoidCallback onPress; @override Widget build(final BuildContext context) => OutlinedButton( - onPressed: () => Navigator.of(context).pop(), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - BrandText.h4('basis.close'.tr()), - const Icon(Icons.close), - ], - ), - ); + onPressed: () => Navigator.of(context).pop(), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + BrandText.h4('basis.close'.tr()), + const Icon(Icons.close), + ], + ), + ); } diff --git a/lib/ui/components/pre_styled_buttons/flash.dart b/lib/ui/components/pre_styled_buttons/flash.dart index 5d70013d..3e780fd7 100644 --- a/lib/ui/components/pre_styled_buttons/flash.dart +++ b/lib/ui/components/pre_styled_buttons/flash.dart @@ -1,8 +1,6 @@ part of 'pre_styled_buttons.dart'; class _BrandFlashButton extends StatefulWidget { - const _BrandFlashButton({super.key}); - @override _BrandFlashButtonState createState() => _BrandFlashButtonState(); } @@ -15,7 +13,9 @@ class _BrandFlashButtonState extends State<_BrandFlashButton> @override void initState() { _animationController = AnimationController( - vsync: this, duration: const Duration(milliseconds: 800),); + vsync: this, + duration: const Duration(milliseconds: 800), + ); _colorTween = ColorTween( begin: BrandColors.black, end: BrandColors.primary, @@ -45,32 +45,34 @@ class _BrandFlashButtonState extends State<_BrandFlashButton> bool wasPrevStateIsEmpty = true; @override - Widget build(final BuildContext context) => BlocListener( - listener: (final context, final state) { - if (wasPrevStateIsEmpty && state is! JobsStateEmpty) { - wasPrevStateIsEmpty = false; - _animationController.forward(); - } else if (!wasPrevStateIsEmpty && state is JobsStateEmpty) { - wasPrevStateIsEmpty = true; + Widget build(final BuildContext context) => + BlocListener( + listener: (final context, final state) { + if (wasPrevStateIsEmpty && state is! JobsStateEmpty) { + wasPrevStateIsEmpty = false; + _animationController.forward(); + } else if (!wasPrevStateIsEmpty && state is JobsStateEmpty) { + wasPrevStateIsEmpty = true; - _animationController.reverse(); - } - }, - child: IconButton( - onPressed: () { - showBrandBottomSheet( - context: context, - builder: (final context) => const BrandBottomSheet( - isExpended: true, - child: JobsContent(), - ), - ); + _animationController.reverse(); + } }, - icon: AnimatedBuilder( + child: IconButton( + onPressed: () { + showBrandBottomSheet( + context: context, + builder: (final context) => const BrandBottomSheet( + isExpended: true, + child: JobsContent(), + ), + ); + }, + icon: AnimatedBuilder( animation: _colorTween, builder: (final context, final child) { final double v = _animationController.value; - final IconData icon = v > 0.5 ? Ionicons.flash : Ionicons.flash_outline; + final IconData icon = + v > 0.5 ? Ionicons.flash : Ionicons.flash_outline; return Transform.scale( scale: 1 + (v < 0.5 ? v : 1 - v) * 2, child: Icon( @@ -78,7 +80,8 @@ class _BrandFlashButtonState extends State<_BrandFlashButton> color: _colorTween.value, ), ); - },), - ), - ); + }, + ), + ), + ); } diff --git a/lib/ui/components/pre_styled_buttons/flash_fab.dart b/lib/ui/components/pre_styled_buttons/flash_fab.dart index 89f42e19..4ae29087 100644 --- a/lib/ui/components/pre_styled_buttons/flash_fab.dart +++ b/lib/ui/components/pre_styled_buttons/flash_fab.dart @@ -7,7 +7,7 @@ import 'package:selfprivacy/ui/components/jobs_content/jobs_content.dart'; import 'package:selfprivacy/ui/helpers/modals.dart'; class BrandFab extends StatefulWidget { - const BrandFab({super.key}); + const BrandFab({final super.key}); @override State createState() => _BrandFabState(); @@ -21,7 +21,9 @@ class _BrandFabState extends State @override void initState() { _animationController = AnimationController( - vsync: this, duration: const Duration(milliseconds: 800),); + vsync: this, + duration: const Duration(milliseconds: 800), + ); super.initState(); } @@ -62,18 +64,20 @@ class _BrandFabState extends State ); }, child: AnimatedBuilder( - animation: _colorTween, - builder: (final BuildContext context, final Widget? child) { - final double v = _animationController.value; - final IconData icon = v > 0.5 ? Ionicons.flash : Ionicons.flash_outline; - return Transform.scale( - scale: 1 + (v < 0.5 ? v : 1 - v) * 2, - child: Icon( - icon, - color: _colorTween.value, - ), - ); - },), + animation: _colorTween, + builder: (final BuildContext context, final Widget? child) { + final double v = _animationController.value; + final IconData icon = + v > 0.5 ? Ionicons.flash : Ionicons.flash_outline; + return Transform.scale( + scale: 1 + (v < 0.5 ? v : 1 - v) * 2, + child: Icon( + icon, + color: _colorTween.value, + ), + ); + }, + ), ), ); } diff --git a/lib/ui/components/pre_styled_buttons/pre_styled_buttons.dart b/lib/ui/components/pre_styled_buttons/pre_styled_buttons.dart index cb50e2f9..ad9105fb 100644 --- a/lib/ui/components/pre_styled_buttons/pre_styled_buttons.dart +++ b/lib/ui/components/pre_styled_buttons/pre_styled_buttons.dart @@ -18,5 +18,5 @@ class PreStyledButtons { }) => _CloseButton(onPress: onPress); - static Widget flash() => const _BrandFlashButton(); + static Widget flash() => _BrandFlashButton(); } diff --git a/lib/ui/components/progress_bar/progress_bar.dart b/lib/ui/components/progress_bar/progress_bar.dart index 6e8d80c3..4de729f7 100644 --- a/lib/ui/components/progress_bar/progress_bar.dart +++ b/lib/ui/components/progress_bar/progress_bar.dart @@ -7,9 +7,9 @@ import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; class ProgressBar extends StatefulWidget { const ProgressBar({ - super.key, required this.steps, required this.activeIndex, + final super.key, }); final int activeIndex; @@ -23,9 +23,11 @@ class ProgressBar extends StatefulWidget { class _ProgressBarState extends State { @override Widget build(final BuildContext context) { - final double progress = 1 / widget.steps.length * (widget.activeIndex + 0.3); + final double progress = + 1 / widget.steps.length * (widget.activeIndex + 0.3); final bool isDark = context.watch().state.isDarkModeOn; - final TextStyle style = isDark ? progressTextStyleDark : progressTextStyleLight; + final TextStyle style = + isDark ? progressTextStyleDark : progressTextStyleLight; final Iterable allSteps = widget.steps.asMap().map( (final i, final step) { @@ -77,20 +79,20 @@ class _ProgressBarState extends State { ), child: LayoutBuilder( builder: (final _, final constraints) => AnimatedContainer( - width: constraints.maxWidth * progress, - height: 5, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5), - gradient: const LinearGradient( - begin: Alignment.topLeft, - end: Alignment.bottomRight, - colors: BrandColors.stableGradientColors, - ), - ), - duration: const Duration( - milliseconds: 300, + width: constraints.maxWidth * progress, + height: 5, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + gradient: const LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: BrandColors.stableGradientColors, ), ), + duration: const Duration( + milliseconds: 300, + ), + ), ), ), const SizedBox(height: 5), @@ -120,11 +122,15 @@ class _ProgressBarState extends State { text: TextSpan( style: progressTextStyleLight, children: [ - if (checked) const WidgetSpan( - child: Padding( - padding: EdgeInsets.only(bottom: 2, right: 2), - child: Icon(BrandIcons.check, size: 11), - ),) else TextSpan(text: '${index + 1}.', style: style), + if (checked) + const WidgetSpan( + child: Padding( + padding: EdgeInsets.only(bottom: 2, right: 2), + child: Icon(BrandIcons.check, size: 11), + ), + ) + else + TextSpan(text: '${index + 1}.', style: style), TextSpan(text: step, style: style) ], ), diff --git a/lib/ui/components/switch_block/switch_bloc.dart b/lib/ui/components/switch_block/switch_bloc.dart index 3aa89a33..ae593f1e 100644 --- a/lib/ui/components/switch_block/switch_bloc.dart +++ b/lib/ui/components/switch_block/switch_bloc.dart @@ -3,10 +3,10 @@ import 'package:selfprivacy/config/brand_colors.dart'; class SwitcherBlock extends StatelessWidget { const SwitcherBlock({ - super.key, required this.child, required this.isActive, required this.onChange, + final super.key, }); final Widget child; @@ -15,24 +15,25 @@ class SwitcherBlock extends StatelessWidget { @override Widget build(final BuildContext context) => Container( - padding: const EdgeInsets.only(top: 20, bottom: 5), - decoration: const BoxDecoration( + padding: const EdgeInsets.only(top: 20, bottom: 5), + decoration: const BoxDecoration( border: Border( - bottom: BorderSide(width: 1, color: BrandColors.dividerColor), - ),), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Flexible(child: child), - const SizedBox(width: 5), - Switch( - activeColor: BrandColors.green1, - activeTrackColor: BrandColors.green2, - onChanged: onChange, - value: isActive, + bottom: BorderSide(width: 1, color: BrandColors.dividerColor), ), - ], - ), - ); + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible(child: child), + const SizedBox(width: 5), + Switch( + activeColor: BrandColors.green1, + activeTrackColor: BrandColors.green2, + onChanged: onChange, + value: isActive, + ), + ], + ), + ); } diff --git a/lib/ui/pages/backup_details/backup_details.dart b/lib/ui/pages/backup_details/backup_details.dart index f7784a18..55a8dd12 100644 --- a/lib/ui/pages/backup_details/backup_details.dart +++ b/lib/ui/pages/backup_details/backup_details.dart @@ -18,7 +18,7 @@ import 'package:selfprivacy/ui/components/brand_cards/brand_cards.dart'; GlobalKey navigatorKey = GlobalKey(); class BackupDetails extends StatefulWidget { - const BackupDetails({super.key}); + const BackupDetails({final super.key}); @override State createState() => _BackupDetailsState(); @@ -30,14 +30,17 @@ class _BackupDetailsState extends State Widget build(final BuildContext context) { final bool isReady = context.watch().state is ServerInstallationFinished; - final bool isBackupInitialized = context.watch().state.isInitialized; - final BackupStatusEnum backupStatus = context.watch().state.status; + final bool isBackupInitialized = + context.watch().state.isInitialized; + final BackupStatusEnum backupStatus = + context.watch().state.status; final StateType providerState = isReady && isBackupInitialized ? (backupStatus == BackupStatusEnum.error ? StateType.warning : StateType.stable) : StateType.uninitialized; - final bool preventActions = context.watch().state.preventActions; + final bool preventActions = + context.watch().state.preventActions; final double backupProgress = context.watch().state.progress; final String backupError = context.watch().state.error; final List backups = context.watch().state.backups; @@ -84,7 +87,8 @@ class _BackupDetailsState extends State ListTile( title: Text( 'providers.backup.creating'.tr( - args: [(backupProgress * 100).round().toString()],), + args: [(backupProgress * 100).round().toString()], + ), style: Theme.of(context).textTheme.headline6, ), subtitle: LinearProgressIndicator( @@ -96,7 +100,8 @@ class _BackupDetailsState extends State ListTile( title: Text( 'providers.backup.restoring'.tr( - args: [(backupProgress * 100).round().toString()],), + args: [(backupProgress * 100).round().toString()], + ), style: Theme.of(context).textTheme.headline6, ), subtitle: LinearProgressIndicator( @@ -148,34 +153,44 @@ class _BackupDetailsState extends State ), if (backups.isNotEmpty) Column( - children: backups.map((final Backup backup) => ListTile( - onTap: preventActions - ? null - : () { - final NavigationService nav = getIt(); - nav.showPopUpDialog(BrandAlert( - title: 'providers.backup.restoring'.tr(), - contentText: 'providers.backup.restore_alert' - .tr(args: [backup.time.toString()]), - actions: [ - ActionButton( - text: 'basis.cancel'.tr(), - ), - ActionButton( - onPressed: () => { - context - .read() - .restoreBackup(backup.id) - }, - text: 'modals.yes'.tr(), - ) - ], - ),); - }, - title: Text( - '${MaterialLocalizations.of(context).formatShortDate(backup.time)} ${TimeOfDay.fromDateTime(backup.time).format(context)}', - ), - ),).toList(), + children: backups + .map( + (final Backup backup) => ListTile( + onTap: preventActions + ? null + : () { + final NavigationService nav = + getIt(); + nav.showPopUpDialog( + BrandAlert( + title: + 'providers.backup.restoring'.tr(), + contentText: + 'providers.backup.restore_alert'.tr( + args: [backup.time.toString()], + ), + actions: [ + ActionButton( + text: 'basis.cancel'.tr(), + ), + ActionButton( + onPressed: () => { + context + .read() + .restoreBackup(backup.id) + }, + text: 'modals.yes'.tr(), + ) + ], + ), + ); + }, + title: Text( + '${MaterialLocalizations.of(context).formatShortDate(backup.time)} ${TimeOfDay.fromDateTime(backup.time).format(context)}', + ), + ), + ) + .toList(), ), ], ), diff --git a/lib/ui/pages/devices/devices.dart b/lib/ui/pages/devices/devices.dart index e14f5263..5883064c 100644 --- a/lib/ui/pages/devices/devices.dart +++ b/lib/ui/pages/devices/devices.dart @@ -9,7 +9,7 @@ import 'package:selfprivacy/ui/pages/devices/new_device.dart'; import 'package:selfprivacy/utils/route_transitions/basic.dart'; class DevicesScreen extends StatefulWidget { - const DevicesScreen({super.key}); + const DevicesScreen({final super.key}); @override State createState() => _DevicesScreenState(); @@ -18,7 +18,8 @@ class DevicesScreen extends StatefulWidget { class _DevicesScreenState extends State { @override Widget build(final BuildContext context) { - final ApiDevicesState devicesStatus = context.watch().state; + final ApiDevicesState devicesStatus = + context.watch().state; return RefreshIndicator( onRefresh: () async { @@ -79,61 +80,68 @@ class _DevicesScreenState extends State { } class _DeviceTile extends StatelessWidget { - const _DeviceTile({super.key, required this.device}); + const _DeviceTile({required this.device}); final ApiToken device; @override Widget build(final BuildContext context) => ListTile( - contentPadding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4), - title: Text(device.name), - subtitle: Text('devices.main_screen.access_granted_on' - .tr(args: [DateFormat.yMMMMd().format(device.date)]),), - onTap: device.isCaller - ? null - : () => _showConfirmationDialog(context, device), - ); + contentPadding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4), + title: Text(device.name), + subtitle: Text( + 'devices.main_screen.access_granted_on' + .tr(args: [DateFormat.yMMMMd().format(device.date)]), + ), + onTap: device.isCaller + ? null + : () => _showConfirmationDialog(context, device), + ); - Future _showConfirmationDialog(final BuildContext context, final ApiToken device) => showDialog( + Future _showConfirmationDialog( + final BuildContext context, + final ApiToken device, + ) => + showDialog( context: context, builder: (final context) => AlertDialog( - title: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const Icon(Icons.link_off_outlined), - const SizedBox(height: 16), - Text( - 'devices.revoke_device_alert.header'.tr(), - style: Theme.of(context).textTheme.headlineSmall, - textAlign: TextAlign.center, - ), - ], - ), - content: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'devices.revoke_device_alert.description' - .tr(args: [device.name]), - style: Theme.of(context).textTheme.bodyMedium,), - ], - ), - actions: [ - TextButton( - child: Text('devices.revoke_device_alert.no'.tr()), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - TextButton( - child: Text('devices.revoke_device_alert.yes'.tr()), - onPressed: () { - context.read().deleteDevice(device); - Navigator.of(context).pop(); - }, + title: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Icon(Icons.link_off_outlined), + const SizedBox(height: 16), + Text( + 'devices.revoke_device_alert.header'.tr(), + style: Theme.of(context).textTheme.headlineSmall, + textAlign: TextAlign.center, ), ], ), + content: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'devices.revoke_device_alert.description' + .tr(args: [device.name]), + style: Theme.of(context).textTheme.bodyMedium, + ), + ], + ), + actions: [ + TextButton( + child: Text('devices.revoke_device_alert.no'.tr()), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + TextButton( + child: Text('devices.revoke_device_alert.yes'.tr()), + onPressed: () { + context.read().deleteDevice(device); + Navigator.of(context).pop(); + }, + ), + ], + ), ); } diff --git a/lib/ui/pages/devices/new_device.dart b/lib/ui/pages/devices/new_device.dart index 4a152380..56f3d47f 100644 --- a/lib/ui/pages/devices/new_device.dart +++ b/lib/ui/pages/devices/new_device.dart @@ -7,74 +7,77 @@ import 'package:selfprivacy/ui/components/brand_button/filled_button.dart'; import 'package:selfprivacy/ui/components/brand_hero_screen/brand_hero_screen.dart'; class NewDeviceScreen extends StatelessWidget { - const NewDeviceScreen({super.key}); + const NewDeviceScreen({final super.key}); @override Widget build(final BuildContext context) => BrandHeroScreen( - heroTitle: 'devices.add_new_device_screen.header'.tr(), - heroSubtitle: 'devices.add_new_device_screen.description'.tr(), - hasBackButton: true, - hasFlashButton: false, - children: [ - FutureBuilder( - future: context.read().getNewDeviceKey(), - builder: (final BuildContext context, final AsyncSnapshot snapshot) { - if (snapshot.hasData) { - return _KeyDisplay( - newDeviceKey: snapshot.data.toString(), - ); - } else { - return const Center(child: CircularProgressIndicator()); - } - }, - ), - ], - ); + heroTitle: 'devices.add_new_device_screen.header'.tr(), + heroSubtitle: 'devices.add_new_device_screen.description'.tr(), + hasBackButton: true, + hasFlashButton: false, + children: [ + FutureBuilder( + future: context.read().getNewDeviceKey(), + builder: ( + final BuildContext context, + final AsyncSnapshot snapshot, + ) { + if (snapshot.hasData) { + return _KeyDisplay( + newDeviceKey: snapshot.data.toString(), + ); + } else { + return const Center(child: CircularProgressIndicator()); + } + }, + ), + ], + ); } class _KeyDisplay extends StatelessWidget { - const _KeyDisplay({super.key, required this.newDeviceKey}); + const _KeyDisplay({required this.newDeviceKey}); final String newDeviceKey; @override Widget build(final BuildContext context) => Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Divider(), - const SizedBox(height: 16), - Text( - newDeviceKey, - style: Theme.of(context).textTheme.bodyLarge!.copyWith( - fontSize: 24, - fontFamily: 'RobotoMono', - ), - textAlign: TextAlign.center, - ), - const SizedBox(height: 16), - const Divider(), - const SizedBox(height: 16), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Icon( - Icons.info_outline, - color: Theme.of(context).colorScheme.onBackground, - ), - const SizedBox(height: 16), - Text( - 'devices.add_new_device_screen.tip'.tr(), - style: Theme.of(context).textTheme.bodyMedium!, - ), - ], - ), - const SizedBox(height: 16), - FilledButton( - child: Text( - 'basis.done'.tr(), + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Divider(), + const SizedBox(height: 16), + Text( + newDeviceKey, + style: Theme.of(context).textTheme.bodyLarge!.copyWith( + fontSize: 24, + fontFamily: 'RobotoMono', + ), + textAlign: TextAlign.center, ), - onPressed: () => Navigator.of(context).pop(), - ), - const SizedBox(height: 24), - ], - ); + const SizedBox(height: 16), + const Divider(), + const SizedBox(height: 16), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Icon( + Icons.info_outline, + color: Theme.of(context).colorScheme.onBackground, + ), + const SizedBox(height: 16), + Text( + 'devices.add_new_device_screen.tip'.tr(), + style: Theme.of(context).textTheme.bodyMedium!, + ), + ], + ), + const SizedBox(height: 16), + FilledButton( + child: Text( + 'basis.done'.tr(), + ), + onPressed: () => Navigator.of(context).pop(), + ), + const SizedBox(height: 24), + ], + ); } diff --git a/lib/ui/pages/dns_details/dns_details.dart b/lib/ui/pages/dns_details/dns_details.dart index 3e3cc67a..44d6db0d 100644 --- a/lib/ui/pages/dns_details/dns_details.dart +++ b/lib/ui/pages/dns_details/dns_details.dart @@ -8,14 +8,17 @@ import 'package:selfprivacy/ui/components/brand_hero_screen/brand_hero_screen.da import 'package:selfprivacy/ui/components/brand_icons/brand_icons.dart'; class DnsDetailsPage extends StatefulWidget { - const DnsDetailsPage({super.key}); + const DnsDetailsPage({final super.key}); @override State createState() => _DnsDetailsPageState(); } class _DnsDetailsPageState extends State { - Widget _getStateCard(final DnsRecordsStatus dnsState, final Function fixCallback) { + Widget _getStateCard( + final DnsRecordsStatus dnsState, + final Function fixCallback, + ) { String description = ''; String subtitle = ''; Icon icon = const Icon( @@ -66,7 +69,8 @@ class _DnsDetailsPageState extends State { Widget build(final BuildContext context) { final bool isReady = context.watch().state is ServerInstallationFinished; - final String domain = getIt().serverDomain?.domainName ?? ''; + final String domain = + getIt().serverDomain?.domainName ?? ''; final DnsRecordsState dnsCubit = context.watch().state; print(dnsCubit.dnsState); diff --git a/lib/ui/pages/more/about/about.dart b/lib/ui/pages/more/about/about.dart index bc1a3819..3d642adc 100644 --- a/lib/ui/pages/more/about/about.dart +++ b/lib/ui/pages/more/about/about.dart @@ -4,19 +4,21 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:selfprivacy/ui/components/brand_md/brand_md.dart'; class AboutPage extends StatelessWidget { - const AboutPage({super.key}); + const AboutPage({final super.key}); @override Widget build(final BuildContext context) => SafeArea( - child: Scaffold( - appBar: PreferredSize( - preferredSize: const Size.fromHeight(52), - child: BrandHeader( - title: 'more.about_project'.tr(), hasBackButton: true,), + child: Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(52), + child: BrandHeader( + title: 'more.about_project'.tr(), + hasBackButton: true, + ), + ), + body: const BrandMarkdown( + fileName: 'about', + ), ), - body: const BrandMarkdown( - fileName: 'about', - ), - ), - ); + ); } diff --git a/lib/ui/pages/more/app_settings/app_setting.dart b/lib/ui/pages/more/app_settings/app_setting.dart index 1dc50416..862815c1 100644 --- a/lib/ui/pages/more/app_settings/app_setting.dart +++ b/lib/ui/pages/more/app_settings/app_setting.dart @@ -13,7 +13,7 @@ import 'package:selfprivacy/utils/named_font_weight.dart'; import 'package:easy_localization/easy_localization.dart'; class AppSettingsPage extends StatefulWidget { - const AppSettingsPage({super.key}); + const AppSettingsPage({final super.key}); @override State createState() => _AppSettingsPageState(); @@ -22,14 +22,18 @@ class AppSettingsPage extends StatefulWidget { class _AppSettingsPageState extends State { @override Widget build(final BuildContext context) { - final bool isDarkModeOn = context.watch().state.isDarkModeOn; + final bool isDarkModeOn = + context.watch().state.isDarkModeOn; return SafeArea( - child: Builder(builder: (final context) => Scaffold( + child: Builder( + builder: (final context) => Scaffold( appBar: PreferredSize( preferredSize: const Size.fromHeight(52), child: BrandHeader( - title: 'more.settings.title'.tr(), hasBackButton: true,), + title: 'more.settings.title'.tr(), + hasBackButton: true, + ), ), body: ListView( padding: paddingH15V0, @@ -38,9 +42,11 @@ class _AppSettingsPageState extends State { Container( padding: const EdgeInsets.only(top: 20, bottom: 5), decoration: const BoxDecoration( - border: Border( - bottom: BorderSide(width: 1, color: BrandColors.dividerColor), - ),), + border: Border( + bottom: + BorderSide(width: 1, color: BrandColors.dividerColor), + ), + ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -65,9 +71,11 @@ class _AppSettingsPageState extends State { Container( padding: const EdgeInsets.only(top: 20, bottom: 5), decoration: const BoxDecoration( - border: Border( - bottom: BorderSide(width: 1, color: BrandColors.dividerColor), - ),), + border: Border( + bottom: + BorderSide(width: 1, color: BrandColors.dividerColor), + ), + ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -95,23 +103,24 @@ class _AppSettingsPageState extends State { showDialog( context: context, builder: (final _) => BrandAlert( - title: 'modals.3'.tr(), - contentText: 'modals.4'.tr(), - actions: [ - ActionButton( - text: 'modals.5'.tr(), - isRed: true, - onPressed: () { - context - .read() - .clearAppConfig(); - Navigator.of(context).pop(); - },), - ActionButton( - text: 'basis.cancel'.tr(), - ), - ], - ), + title: 'modals.3'.tr(), + contentText: 'modals.4'.tr(), + actions: [ + ActionButton( + text: 'modals.5'.tr(), + isRed: true, + onPressed: () { + context + .read() + .clearAppConfig(); + Navigator.of(context).pop(); + }, + ), + ActionButton( + text: 'basis.cancel'.tr(), + ), + ], + ), ); }, ), @@ -121,7 +130,8 @@ class _AppSettingsPageState extends State { deleteServer(context) ], ), - ),), + ), + ), ); } @@ -131,9 +141,10 @@ class _AppSettingsPageState extends State { return Container( padding: const EdgeInsets.only(top: 20, bottom: 5), decoration: const BoxDecoration( - border: Border( - bottom: BorderSide(width: 1, color: BrandColors.dividerColor), - ),), + border: Border( + bottom: BorderSide(width: 1, color: BrandColors.dividerColor), + ), + ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -156,31 +167,34 @@ class _AppSettingsPageState extends State { showDialog( context: context, builder: (final _) => BrandAlert( - title: 'modals.3'.tr(), - contentText: 'modals.6'.tr(), - actions: [ - ActionButton( - text: 'modals.7'.tr(), - isRed: true, - onPressed: () async { - showDialog( - context: context, - builder: (final context) => Container( - alignment: Alignment.center, - child: - const CircularProgressIndicator(), - ),); - await context - .read() - .serverDelete(); - if (!mounted) return; - Navigator.of(context).pop(); - },), - ActionButton( - text: 'basis.cancel'.tr(), - ), - ], - ), + title: 'modals.3'.tr(), + contentText: 'modals.6'.tr(), + actions: [ + ActionButton( + text: 'modals.7'.tr(), + isRed: true, + onPressed: () async { + showDialog( + context: context, + builder: (final context) => Container( + alignment: Alignment.center, + child: const CircularProgressIndicator(), + ), + ); + await context + .read() + .serverDelete(); + if (!mounted) { + return; + } + Navigator.of(context).pop(); + }, + ), + ActionButton( + text: 'basis.cancel'.tr(), + ), + ], + ), ); }, child: Text( @@ -199,7 +213,6 @@ class _AppSettingsPageState extends State { class _TextColumn extends StatelessWidget { const _TextColumn({ - super.key, required this.title, required this.value, this.hasWarning = false, @@ -210,19 +223,21 @@ class _TextColumn extends StatelessWidget { final bool hasWarning; @override Widget build(final BuildContext context) => Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - BrandText.body1( - title, - style: TextStyle(color: hasWarning ? BrandColors.warning : null), - ), - const SizedBox(height: 5), - BrandText.body1(value, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BrandText.body1( + title, + style: TextStyle(color: hasWarning ? BrandColors.warning : null), + ), + const SizedBox(height: 5), + BrandText.body1( + value, style: const TextStyle( fontSize: 13, height: 1.53, color: BrandColors.gray1, - ).merge(TextStyle(color: hasWarning ? BrandColors.warning : null)),), - ], - ); + ).merge(TextStyle(color: hasWarning ? BrandColors.warning : null)), + ), + ], + ); } diff --git a/lib/ui/pages/more/console/console.dart b/lib/ui/pages/more/console/console.dart index a3d046b6..76703444 100644 --- a/lib/ui/pages/more/console/console.dart +++ b/lib/ui/pages/more/console/console.dart @@ -8,7 +8,7 @@ import 'package:selfprivacy/ui/components/brand_divider/brand_divider.dart'; import 'package:selfprivacy/ui/components/brand_header/brand_header.dart'; class Console extends StatefulWidget { - const Console({super.key}); + const Console({final super.key}); @override State createState() => _ConsoleState(); @@ -32,68 +32,77 @@ class _ConsoleState extends State { @override Widget build(final BuildContext context) => SafeArea( - child: Scaffold( - appBar: PreferredSize( - preferredSize: const Size.fromHeight(53), - child: Column( - children: const [ - BrandHeader(title: 'Console', hasBackButton: true), - BrandDivider(), - ], + child: Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(53), + child: Column( + children: const [ + BrandHeader(title: 'Console', hasBackButton: true), + BrandDivider(), + ], + ), ), - ), - body: FutureBuilder( - future: getIt.allReady(), - builder: (final BuildContext context, final AsyncSnapshot snapshot) { - if (snapshot.hasData) { - final List messages = getIt.get().messages; + body: FutureBuilder( + future: getIt.allReady(), + builder: ( + final BuildContext context, + final AsyncSnapshot snapshot, + ) { + if (snapshot.hasData) { + final List messages = + getIt.get().messages; - return ListView( - reverse: true, - shrinkWrap: true, - children: [ - const SizedBox(height: 20), - ...UnmodifiableListView(messages - .map((final message) { - final bool isError = message.type == MessageType.warning; - return Padding( - padding: const EdgeInsets.symmetric(vertical: 4), - child: RichText( - text: TextSpan( - style: DefaultTextStyle.of(context).style, - children: [ - TextSpan( - text: - '${message.timeString}${isError ? '(Error)' : ''}: \n', - style: TextStyle( + return ListView( + reverse: true, + shrinkWrap: true, + children: [ + const SizedBox(height: 20), + ...UnmodifiableListView( + messages + .map((final message) { + final bool isError = + message.type == MessageType.warning; + return Padding( + padding: const EdgeInsets.symmetric(vertical: 4), + child: RichText( + text: TextSpan( + style: DefaultTextStyle.of(context).style, + children: [ + TextSpan( + text: + '${message.timeString}${isError ? '(Error)' : ''}: \n', + style: TextStyle( fontWeight: FontWeight.bold, color: - isError ? BrandColors.red1 : null,),), - TextSpan(text: message.text), - ], - ), - ), - ); - }) - .toList() - .reversed,), - ], - ); - } else { - return Column( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: const [ - Text('Waiting for initialisation'), - SizedBox( - height: 16, - ), - CircularProgressIndicator(), - ], - ); - } - }, + isError ? BrandColors.red1 : null, + ), + ), + TextSpan(text: message.text), + ], + ), + ), + ); + }) + .toList() + .reversed, + ), + ], + ); + } else { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: const [ + Text('Waiting for initialisation'), + SizedBox( + height: 16, + ), + CircularProgressIndicator(), + ], + ); + } + }, + ), ), - ), - ); + ); } diff --git a/lib/ui/pages/more/info/info.dart b/lib/ui/pages/more/info/info.dart index baa82021..04de405e 100644 --- a/lib/ui/pages/more/info/info.dart +++ b/lib/ui/pages/more/info/info.dart @@ -7,28 +7,32 @@ import 'package:package_info/package_info.dart'; import 'package:easy_localization/easy_localization.dart'; class InfoPage extends StatelessWidget { - const InfoPage({super.key}); + const InfoPage({final super.key}); @override Widget build(final BuildContext context) => SafeArea( - child: Scaffold( - appBar: PreferredSize( - preferredSize: const Size.fromHeight(52), - child: BrandHeader(title: 'more.about_app'.tr(), hasBackButton: true), - ), - body: ListView( - padding: paddingH15V0, - children: [ - const BrandDivider(), - const SizedBox(height: 10), - FutureBuilder( + child: Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(52), + child: + BrandHeader(title: 'more.about_app'.tr(), hasBackButton: true), + ), + body: ListView( + padding: paddingH15V0, + children: [ + const BrandDivider(), + const SizedBox(height: 10), + FutureBuilder( future: _version(), - builder: (final context, final snapshot) => BrandText.body1('more.about_app_page.text' - .tr(args: [snapshot.data.toString()]),),), - ], + builder: (final context, final snapshot) => BrandText.body1( + 'more.about_app_page.text' + .tr(args: [snapshot.data.toString()]), + ), + ), + ], + ), ), - ), - ); + ); Future _version() async { final PackageInfo packageInfo = await PackageInfo.fromPlatform(); diff --git a/lib/ui/pages/more/more.dart b/lib/ui/pages/more/more.dart index eee3398e..5a02da3c 100644 --- a/lib/ui/pages/more/more.dart +++ b/lib/ui/pages/more/more.dart @@ -21,7 +21,7 @@ import 'package:selfprivacy/ui/pages/more/console/console.dart'; import 'package:selfprivacy/ui/pages/more/info/info.dart'; class MorePage extends StatelessWidget { - const MorePage({super.key}); + const MorePage({final super.key}); @override Widget build(final BuildContext context) { @@ -51,11 +51,12 @@ class MorePage extends StatelessWidget { ), if (isReady) _MoreMenuItem( - title: 'more.create_ssh_key'.tr(), - iconData: Ionicons.key_outline, - goTo: SshKeysPage( - user: context.read().state.rootUser, - ),), + title: 'more.create_ssh_key'.tr(), + iconData: Ionicons.key_outline, + goTo: SshKeysPage( + user: context.read().state.rootUser, + ), + ), if (isReady) _MoreMenuItem( iconData: Icons.password_outlined, @@ -105,7 +106,6 @@ class MorePage extends StatelessWidget { class _MoreMenuItem extends StatelessWidget { const _MoreMenuItem({ - super.key, required this.iconData, required this.title, this.subtitle, diff --git a/lib/ui/pages/onboarding/onboarding.dart b/lib/ui/pages/onboarding/onboarding.dart index 364f5380..dc5c8763 100644 --- a/lib/ui/pages/onboarding/onboarding.dart +++ b/lib/ui/pages/onboarding/onboarding.dart @@ -6,7 +6,7 @@ import 'package:selfprivacy/utils/route_transitions/basic.dart'; import 'package:easy_localization/easy_localization.dart'; class OnboardingPage extends StatefulWidget { - const OnboardingPage({super.key, required this.nextPage}); + const OnboardingPage({required this.nextPage, final super.key}); final Widget nextPage; @override @@ -23,111 +23,111 @@ class _OnboardingPageState extends State { @override Widget build(final BuildContext context) => SafeArea( - child: Scaffold( - body: PageView( - controller: pageController, - children: [ - _withPadding(firstPage()), - _withPadding(secondPage()), - ], + child: Scaffold( + body: PageView( + controller: pageController, + children: [ + _withPadding(firstPage()), + _withPadding(secondPage()), + ], + ), ), - ), - ); + ); Widget _withPadding(final Widget child) => Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: child, - ); + padding: const EdgeInsets.symmetric( + horizontal: 15, + ), + child: child, + ); Widget firstPage() => ConstrainedBox( - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox(height: 30), - BrandText.h2( - 'onboarding.page1_title'.tr(), - ), - const SizedBox(height: 20), - BrandText.body2('onboarding.page1_text'.tr()), - Flexible( - child: Center( - child: Image.asset( - _fileName( - context: context, - path: 'assets/images/onboarding', - fileExtention: 'png', - fileName: 'onboarding1', + constraints: BoxConstraints( + maxHeight: MediaQuery.of(context).size.height, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 30), + BrandText.h2( + 'onboarding.page1_title'.tr(), + ), + const SizedBox(height: 20), + BrandText.body2('onboarding.page1_text'.tr()), + Flexible( + child: Center( + child: Image.asset( + _fileName( + context: context, + path: 'assets/images/onboarding', + fileExtention: 'png', + fileName: 'onboarding1', + ), ), ), ), - ), - BrandButton.rised( - onPressed: () { - pageController.animateToPage( - 1, - duration: const Duration(milliseconds: 300), - curve: Curves.easeIn, - ); - }, - text: 'basis.next'.tr(), - ), - const SizedBox(height: 30), - ], - ), - ); + BrandButton.rised( + onPressed: () { + pageController.animateToPage( + 1, + duration: const Duration(milliseconds: 300), + curve: Curves.easeIn, + ); + }, + text: 'basis.next'.tr(), + ), + const SizedBox(height: 30), + ], + ), + ); Widget secondPage() => ConstrainedBox( - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height, - ), - child: Column( - children: [ - const SizedBox(height: 30), - BrandText.h2('onboarding.page2_title'.tr()), - const SizedBox(height: 20), - BrandText.body2('onboarding.page2_text'.tr()), - const SizedBox(height: 20), - Center( - child: Image.asset( - _fileName( - context: context, - path: 'assets/images/onboarding', - fileExtention: 'png', - fileName: 'logos_line', - ), - ), - ), - Flexible( - child: Center( + constraints: BoxConstraints( + maxHeight: MediaQuery.of(context).size.height, + ), + child: Column( + children: [ + const SizedBox(height: 30), + BrandText.h2('onboarding.page2_title'.tr()), + const SizedBox(height: 20), + BrandText.body2('onboarding.page2_text'.tr()), + const SizedBox(height: 20), + Center( child: Image.asset( _fileName( context: context, path: 'assets/images/onboarding', fileExtention: 'png', - fileName: 'onboarding2', + fileName: 'logos_line', ), ), ), - ), - BrandButton.rised( - onPressed: () { - context.read().turnOffOnboarding(); - Navigator.of(context).pushAndRemoveUntil( - materialRoute(widget.nextPage), - (final route) => false, - ); - }, - text: 'basis.got_it'.tr(), - ), - const SizedBox(height: 30), - ], - ), - ); + Flexible( + child: Center( + child: Image.asset( + _fileName( + context: context, + path: 'assets/images/onboarding', + fileExtention: 'png', + fileName: 'onboarding2', + ), + ), + ), + ), + BrandButton.rised( + onPressed: () { + context.read().turnOffOnboarding(); + Navigator.of(context).pushAndRemoveUntil( + materialRoute(widget.nextPage), + (final route) => false, + ); + }, + text: 'basis.got_it'.tr(), + ), + const SizedBox(height: 30), + ], + ), + ); } String _fileName({ diff --git a/lib/ui/pages/providers/providers.dart b/lib/ui/pages/providers/providers.dart index 7168689a..97e4aeeb 100644 --- a/lib/ui/pages/providers/providers.dart +++ b/lib/ui/pages/providers/providers.dart @@ -21,7 +21,7 @@ import 'package:selfprivacy/utils/route_transitions/basic.dart'; GlobalKey navigatorKey = GlobalKey(); class ProvidersPage extends StatefulWidget { - const ProvidersPage({super.key}); + const ProvidersPage({final super.key}); @override State createState() => _ProvidersPageState(); @@ -32,8 +32,10 @@ class _ProvidersPageState extends State { Widget build(final BuildContext context) { final bool isReady = context.watch().state is ServerInstallationFinished; - final bool isBackupInitialized = context.watch().state.isInitialized; - final DnsRecordsStatus dnsStatus = context.watch().state.dnsState; + final bool isBackupInitialized = + context.watch().state.isInitialized; + final DnsRecordsStatus dnsStatus = + context.watch().state.dnsState; StateType getDnsStatus() { if (dnsStatus == DnsRecordsStatus.uninitialized || @@ -87,7 +89,7 @@ class _ProvidersPageState extends State { } class _Card extends StatelessWidget { - const _Card({super.key, required this.provider}); + const _Card({required this.provider}); final ProviderModel provider; @override @@ -122,17 +124,21 @@ class _Card extends StatelessWidget { message = domainName; stableText = 'providers.domain.status'.tr(); - onTap = () => Navigator.of(context).push(materialRoute( - const DnsDetailsPage(), - ),); + 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(), - ),); + onTap = () => Navigator.of(context).push( + materialRoute( + const BackupDetails(), + ), + ); break; } return GestureDetector( diff --git a/lib/ui/pages/recovery_key/recovery_key.dart b/lib/ui/pages/recovery_key/recovery_key.dart index 9d329a20..d7167a6f 100644 --- a/lib/ui/pages/recovery_key/recovery_key.dart +++ b/lib/ui/pages/recovery_key/recovery_key.dart @@ -14,7 +14,7 @@ import 'package:selfprivacy/ui/pages/recovery_key/recovery_key_receiving.dart'; import 'package:selfprivacy/utils/route_transitions/basic.dart'; class RecoveryKey extends StatefulWidget { - const RecoveryKey({super.key}); + const RecoveryKey({final super.key}); @override State createState() => _RecoveryKeyState(); @@ -61,7 +61,7 @@ class _RecoveryKeyState extends State { } class RecoveryKeyContent extends StatefulWidget { - const RecoveryKeyContent({super.key}); + const RecoveryKeyContent({final super.key}); @override State createState() => _RecoveryKeyContentState(); @@ -107,50 +107,51 @@ class _RecoveryKeyContentState extends State { } class RecoveryKeyStatusCard extends StatelessWidget { - const RecoveryKeyStatusCard({required this.isValid, super.key}); + const RecoveryKeyStatusCard({required this.isValid, final super.key}); final bool isValid; @override Widget build(final BuildContext context) => BrandCards.filled( - child: ListTile( - title: isValid - ? Text( - 'recovery_key.key_valid'.tr(), - style: Theme.of(context).textTheme.titleMedium!.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ) - : Text( - 'recovery_key.key_invalid'.tr(), - style: Theme.of(context).textTheme.titleMedium!.copyWith( - color: Theme.of(context).colorScheme.onErrorContainer, - ), - ), - leading: isValid - ? Icon( - Icons.check_circle_outlined, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ) - : Icon( - Icons.cancel_outlined, - color: Theme.of(context).colorScheme.onErrorContainer, - ), - tileColor: isValid - ? Theme.of(context).colorScheme.surfaceVariant - : Theme.of(context).colorScheme.errorContainer, - ), - ); + child: ListTile( + title: isValid + ? Text( + 'recovery_key.key_valid'.tr(), + style: Theme.of(context).textTheme.titleMedium!.copyWith( + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ) + : Text( + 'recovery_key.key_invalid'.tr(), + style: Theme.of(context).textTheme.titleMedium!.copyWith( + color: Theme.of(context).colorScheme.onErrorContainer, + ), + ), + leading: isValid + ? Icon( + Icons.check_circle_outlined, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ) + : Icon( + Icons.cancel_outlined, + color: Theme.of(context).colorScheme.onErrorContainer, + ), + tileColor: isValid + ? Theme.of(context).colorScheme.surfaceVariant + : Theme.of(context).colorScheme.errorContainer, + ), + ); } class RecoveryKeyInformation extends StatelessWidget { - const RecoveryKeyInformation({required this.state, super.key}); + const RecoveryKeyInformation({required this.state, final super.key}); final RecoveryKeyState state; @override Widget build(final BuildContext context) { - const EdgeInsets padding = EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0); + const EdgeInsets padding = + EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0); return SizedBox( width: double.infinity, child: Column( @@ -191,7 +192,7 @@ class RecoveryKeyInformation extends StatelessWidget { } class RecoveryKeyConfiguration extends StatefulWidget { - const RecoveryKeyConfiguration({super.key}); + const RecoveryKeyConfiguration({final super.key}); @override State createState() => _RecoveryKeyConfigurationState(); @@ -217,11 +218,13 @@ class _RecoveryKeyConfigurationState extends State { _isLoading = true; }); try { - final String token = await context.read().generateRecoveryKey( - numberOfUses: - _isAmountToggled ? int.tryParse(_amountController.text) : null, - expirationDate: _isExpirationToggled ? _selectedDate : null, - ); + final String token = + await context.read().generateRecoveryKey( + numberOfUses: _isAmountToggled + ? int.tryParse(_amountController.text) + : null, + expirationDate: _isExpirationToggled ? _selectedDate : null, + ); if (!mounted) return; setState(() { _isLoading = false; @@ -310,9 +313,10 @@ class _RecoveryKeyConfigurationState extends State { enabled: _isAmountToggled, controller: _amountController, decoration: InputDecoration( - border: const OutlineInputBorder(), - errorText: _isAmountError ? ' ' : null, - labelText: 'recovery_key.key_amount_field_title'.tr(),), + border: const OutlineInputBorder(), + errorText: _isAmountError ? ' ' : null, + labelText: 'recovery_key.key_amount_field_title'.tr(), + ), keyboardType: TextInputType.number, inputFormatters: [ FilteringTextInputFormatter.digitsOnly, @@ -352,9 +356,10 @@ class _RecoveryKeyConfigurationState extends State { }, readOnly: true, decoration: InputDecoration( - border: const OutlineInputBorder(), - errorText: _isExpirationError ? ' ' : null, - labelText: 'recovery_key.key_duedate_field_title'.tr(),), + border: const OutlineInputBorder(), + errorText: _isExpirationError ? ' ' : null, + labelText: 'recovery_key.key_duedate_field_title'.tr(), + ), keyboardType: TextInputType.number, inputFormatters: [ FilteringTextInputFormatter.digitsOnly, @@ -378,10 +383,11 @@ class _RecoveryKeyConfigurationState extends State { Future _selectDate(final BuildContext context) async { final DateTime? selected = await showDatePicker( - context: context, - initialDate: _selectedDate, - firstDate: DateTime.now(), - lastDate: DateTime(DateTime.now().year + 50),); + context: context, + initialDate: _selectedDate, + firstDate: DateTime.now(), + lastDate: DateTime(DateTime.now().year + 50), + ); if (selected != null && selected != _selectedDate) { setState( diff --git a/lib/ui/pages/recovery_key/recovery_key_receiving.dart b/lib/ui/pages/recovery_key/recovery_key_receiving.dart index f695dd47..7ae6adaf 100644 --- a/lib/ui/pages/recovery_key/recovery_key_receiving.dart +++ b/lib/ui/pages/recovery_key/recovery_key_receiving.dart @@ -4,45 +4,45 @@ import 'package:selfprivacy/ui/components/brand_button/filled_button.dart'; import 'package:selfprivacy/ui/components/brand_hero_screen/brand_hero_screen.dart'; class RecoveryKeyReceiving extends StatelessWidget { - const RecoveryKeyReceiving({required this.recoveryKey, super.key}); + const RecoveryKeyReceiving({required this.recoveryKey, final super.key}); final String recoveryKey; @override Widget build(final BuildContext context) => BrandHeroScreen( - heroTitle: 'recovery_key.key_main_header'.tr(), - heroSubtitle: 'recovery_key.key_receiving_description'.tr(), - hasBackButton: true, - hasFlashButton: false, - children: [ - const Divider(), - const SizedBox(height: 16), - Text( - recoveryKey, - style: Theme.of(context).textTheme.bodyLarge!.copyWith( - fontSize: 24, - fontFamily: 'RobotoMono', - ), - textAlign: TextAlign.center, - ), - const SizedBox(height: 16), - const Divider(), - const SizedBox(height: 16), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Icon(Icons.info_outlined, size: 24), - const SizedBox(height: 16), - Text('recovery_key.key_receiving_info'.tr()), - ], - ), - const SizedBox(height: 16), - FilledButton( - title: 'recovery_key.key_receiving_done'.tr(), - onPressed: () { - Navigator.of(context).popUntil((final route) => route.isFirst); - }, - ), - ], - ); + heroTitle: 'recovery_key.key_main_header'.tr(), + heroSubtitle: 'recovery_key.key_receiving_description'.tr(), + hasBackButton: true, + hasFlashButton: false, + children: [ + const Divider(), + const SizedBox(height: 16), + Text( + recoveryKey, + style: Theme.of(context).textTheme.bodyLarge!.copyWith( + fontSize: 24, + fontFamily: 'RobotoMono', + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 16), + const Divider(), + const SizedBox(height: 16), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Icon(Icons.info_outlined, size: 24), + const SizedBox(height: 16), + Text('recovery_key.key_receiving_info'.tr()), + ], + ), + const SizedBox(height: 16), + FilledButton( + title: 'recovery_key.key_receiving_done'.tr(), + onPressed: () { + Navigator.of(context).popUntil((final route) => route.isFirst); + }, + ), + ], + ); } diff --git a/lib/ui/pages/root_route.dart b/lib/ui/pages/root_route.dart index fb4efeed..d68e4a0e 100644 --- a/lib/ui/pages/root_route.dart +++ b/lib/ui/pages/root_route.dart @@ -9,7 +9,7 @@ import 'package:selfprivacy/ui/pages/users/users.dart'; import 'package:selfprivacy/ui/components/pre_styled_buttons/flash_fab.dart'; class RootPage extends StatefulWidget { - const RootPage({super.key}); + const RootPage({final super.key}); @override State createState() => _RootPageState(); @@ -92,7 +92,6 @@ class _RootPageState extends State with TickerProviderStateMixin { } class ChangeTab { - ChangeTab(this.onPress); final ValueChanged onPress; } diff --git a/lib/ui/pages/server_details/chart.dart b/lib/ui/pages/server_details/chart.dart index 0091b6b1..f7972e9c 100644 --- a/lib/ui/pages/server_details/chart.dart +++ b/lib/ui/pages/server_details/chart.dart @@ -1,8 +1,6 @@ part of 'server_details_screen.dart'; class _Chart extends StatelessWidget { - const _Chart({final super.key}); - @override Widget build(final BuildContext context) { final HetznerMetricsCubit cubit = context.watch(); @@ -129,44 +127,40 @@ class _Chart extends StatelessWidget { class Legend extends StatelessWidget { const Legend({ - final Key? key, required this.color, required this.text, - }) : super(key: key); + final super.key, + }); final String text; final Color color; @override - Widget build(final BuildContext context) { - return Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - _ColoredBox(color: color), - const SizedBox(width: 5), - BrandText.small(text), - ], - ); - } + Widget build(final BuildContext context) => Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + _ColoredBox(color: color), + const SizedBox(width: 5), + BrandText.small(text), + ], + ); } class _ColoredBox extends StatelessWidget { const _ColoredBox({ - final Key? key, required this.color, - }) : super(key: key); + }); final Color color; @override - Widget build(final BuildContext context) { - return Container( - width: 10, - height: 10, - decoration: BoxDecoration( + Widget build(final BuildContext context) => Container( + width: 10, + height: 10, + decoration: BoxDecoration( color: color.withOpacity(0.3), border: Border.all( color: color, - )), - ); - } + ), + ), + ); } diff --git a/lib/ui/pages/server_details/cpu_chart.dart b/lib/ui/pages/server_details/cpu_chart.dart index 07bd8539..35d6fff4 100644 --- a/lib/ui/pages/server_details/cpu_chart.dart +++ b/lib/ui/pages/server_details/cpu_chart.dart @@ -8,7 +8,7 @@ import 'package:intl/intl.dart'; class CpuChart extends StatelessWidget { const CpuChart({ - Key? key, + final Key? key, required this.data, required this.period, required this.start, @@ -20,9 +20,9 @@ class CpuChart extends StatelessWidget { List getSpots() { var i = 0; - List res = []; + final List res = []; - for (var d in data) { + for (final d in data) { res.add(FlSpot(i.toDouble(), d.value)); i++; } @@ -31,97 +31,96 @@ class CpuChart extends StatelessWidget { } @override - Widget build(BuildContext context) { - return LineChart( - LineChartData( - lineTouchData: LineTouchData(enabled: false), - lineBarsData: [ - LineChartBarData( - spots: getSpots(), - isCurved: true, - barWidth: 1, - color: Colors.red, - dotData: FlDotData( - show: false, + Widget build(final BuildContext context) => LineChart( + LineChartData( + lineTouchData: LineTouchData(enabled: false), + lineBarsData: [ + LineChartBarData( + spots: getSpots(), + isCurved: true, + barWidth: 1, + color: Colors.red, + dotData: FlDotData( + show: false, + ), ), - ), - ], - minY: 0, - maxY: 100, - minX: data.length - 200, - titlesData: FlTitlesData( - topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)), - bottomTitles: AxisTitles( - sideTitles: SideTitles( - interval: 20, - reservedSize: 50, - getTitlesWidget: (value, titleMeta) { - return Padding( + ], + minY: 0, + maxY: 100, + minX: data.length - 200, + titlesData: FlTitlesData( + topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)), + bottomTitles: AxisTitles( + sideTitles: SideTitles( + interval: 20, + reservedSize: 50, + getTitlesWidget: (final value, final titleMeta) => Padding( padding: const EdgeInsets.all(8.0), child: RotatedBox( quarterTurns: 1, - child: Text(bottomTitle(value.toInt()), - style: const TextStyle( - fontSize: 10, - color: Colors.purple, - fontWeight: FontWeight.bold, - )), - ), - ); - }, - showTitles: true, - ), - ), - leftTitles: AxisTitles( - sideTitles: SideTitles( - getTitlesWidget: (value, titleMeta) { - return Padding( - padding: const EdgeInsets.only(right: 15), child: Text( - value.toInt().toString(), - style: progressTextStyleLight.copyWith( - color: Theme.of(context).brightness == Brightness.dark - ? BrandColors.gray4 - : null, + bottomTitle(value.toInt()), + style: const TextStyle( + fontSize: 10, + color: Colors.purple, + fontWeight: FontWeight.bold, ), - )); - }, - interval: 25, - showTitles: false, + ), + ), + ), + showTitles: true, + ), + ), + leftTitles: AxisTitles( + sideTitles: SideTitles( + getTitlesWidget: (final value, final titleMeta) => Padding( + padding: const EdgeInsets.only(right: 15), + child: Text( + value.toInt().toString(), + style: progressTextStyleLight.copyWith( + color: Theme.of(context).brightness == Brightness.dark + ? BrandColors.gray4 + : null, + ), + ), + ), + interval: 25, + showTitles: false, + ), ), ), + gridData: FlGridData(show: true), ), - gridData: FlGridData(show: true), - ), - ); - } + ); bool checkToShowTitle( - double minValue, - double maxValue, - SideTitles sideTitles, - double appliedInterval, - double value, + final double minValue, + final double maxValue, + final SideTitles sideTitles, + final double appliedInterval, + final double value, ) { if (value < 0) { return false; } else if (value == 0) { return true; } - var localValue = value - minValue; - var v = localValue / 20; + + final localValue = value - minValue; + final v = localValue / 20; return v - v.floor() == 0; } - String bottomTitle(int value) { + String bottomTitle(final int value) { final hhmm = DateFormat('HH:mm'); - var day = DateFormat('MMMd'); + final day = DateFormat('MMMd'); String res; if (value <= 0) { return ''; } - var time = data[value].time; + + final time = data[value].time; switch (period) { case Period.hour: case Period.day: diff --git a/lib/ui/pages/server_details/header.dart b/lib/ui/pages/server_details/header.dart index b28a5efc..a10bc1cf 100644 --- a/lib/ui/pages/server_details/header.dart +++ b/lib/ui/pages/server_details/header.dart @@ -2,60 +2,57 @@ part of 'server_details_screen.dart'; class _Header extends StatelessWidget { const _Header({ - Key? key, required this.providerState, required this.tabController, - }) : super(key: key); + }); final StateType providerState; final TabController tabController; @override - Widget build(BuildContext context) { - return Row( - children: [ - IconStatusMask( - status: providerState, - child: const Icon( - BrandIcons.server, - size: 40, - color: Colors.white, - ), - ), - const SizedBox(width: 10), - BrandText.h2('providers.server.card_title'.tr()), - const Spacer(), - Padding( - padding: const EdgeInsets.symmetric( - vertical: 4, - horizontal: 2, - ), - child: PopupMenuButton<_PopupMenuItemType>( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0), + Widget build(final BuildContext context) => Row( + children: [ + IconStatusMask( + status: providerState, + child: const Icon( + BrandIcons.server, + size: 40, + color: Colors.white, ), - onSelected: (_PopupMenuItemType result) { - switch (result) { - case _PopupMenuItemType.setting: - tabController.animateTo(1); - break; - } - }, - icon: const Icon(Icons.more_vert), - itemBuilder: (BuildContext context) => [ - PopupMenuItem<_PopupMenuItemType>( - value: _PopupMenuItemType.setting, - child: Container( - padding: const EdgeInsets.only(left: 5), - child: Text('basis.settings'.tr()), - ), - ), - ], ), - ), - ], - ); - } + const SizedBox(width: 10), + BrandText.h2('providers.server.card_title'.tr()), + const Spacer(), + Padding( + padding: const EdgeInsets.symmetric( + vertical: 4, + horizontal: 2, + ), + child: PopupMenuButton<_PopupMenuItemType>( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + onSelected: (final _PopupMenuItemType result) { + switch (result) { + case _PopupMenuItemType.setting: + tabController.animateTo(1); + break; + } + }, + icon: const Icon(Icons.more_vert), + itemBuilder: (final BuildContext context) => [ + PopupMenuItem<_PopupMenuItemType>( + value: _PopupMenuItemType.setting, + child: Container( + padding: const EdgeInsets.only(left: 5), + child: Text('basis.settings'.tr()), + ), + ), + ], + ), + ), + ], + ); } enum _PopupMenuItemType { setting } diff --git a/lib/ui/pages/server_details/network_charts.dart b/lib/ui/pages/server_details/network_charts.dart index 31b3dd21..838b4ebb 100644 --- a/lib/ui/pages/server_details/network_charts.dart +++ b/lib/ui/pages/server_details/network_charts.dart @@ -10,7 +10,7 @@ import 'package:intl/intl.dart'; class NetworkChart extends StatelessWidget { const NetworkChart({ - Key? key, + final Key? key, required this.listData, required this.period, required this.start, @@ -20,11 +20,11 @@ class NetworkChart extends StatelessWidget { final Period period; final DateTime start; - List getSpots(data) { + List getSpots(final data) { var i = 0; - List res = []; + final List res = []; - for (var d in data) { + for (final d in data) { res.add(FlSpot(i.toDouble(), d.value)); i++; } @@ -33,120 +33,119 @@ class NetworkChart extends StatelessWidget { } @override - Widget build(BuildContext context) { - return SizedBox( - height: 150, - width: MediaQuery.of(context).size.width, - child: LineChart( - LineChartData( - lineTouchData: LineTouchData(enabled: false), - lineBarsData: [ - LineChartBarData( - spots: getSpots(listData[0]), - isCurved: true, - barWidth: 1, - color: Colors.red, - dotData: FlDotData( - show: false, + Widget build(final BuildContext context) => SizedBox( + height: 150, + width: MediaQuery.of(context).size.width, + child: LineChart( + LineChartData( + lineTouchData: LineTouchData(enabled: false), + lineBarsData: [ + LineChartBarData( + spots: getSpots(listData[0]), + isCurved: true, + barWidth: 1, + color: Colors.red, + dotData: FlDotData( + show: false, + ), ), - ), - LineChartBarData( - spots: getSpots(listData[1]), - isCurved: true, - barWidth: 1, - color: Colors.green, - dotData: FlDotData( - show: false, + LineChartBarData( + spots: getSpots(listData[1]), + isCurved: true, + barWidth: 1, + color: Colors.green, + dotData: FlDotData( + show: false, + ), ), - ), - ], - minY: 0, - maxY: [ - ...listData[0].map((e) => e.value), - ...listData[1].map((e) => e.value) - ].reduce(max) * - 1.2, - minX: listData[0].length - 200, - titlesData: FlTitlesData( - topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)), - bottomTitles: AxisTitles( - sideTitles: SideTitles( - interval: 20, - reservedSize: 50, - getTitlesWidget: (value, titleMeta) { - return Padding( + ], + minY: 0, + maxY: [ + ...listData[0].map((final e) => e.value), + ...listData[1].map((final e) => e.value) + ].reduce(max) * + 1.2, + minX: listData[0].length - 200, + titlesData: FlTitlesData( + topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)), + bottomTitles: AxisTitles( + sideTitles: SideTitles( + interval: 20, + reservedSize: 50, + getTitlesWidget: (final value, final titleMeta) => Padding( padding: const EdgeInsets.all(8.0), child: RotatedBox( quarterTurns: 1, - child: Text(bottomTitle(value.toInt()), - style: const TextStyle( - fontSize: 10, - color: Colors.purple, - fontWeight: FontWeight.bold, - )), - ), - ); - }, - showTitles: true, - ), - ), - leftTitles: AxisTitles( - sideTitles: SideTitles( - reservedSize: 50, - getTitlesWidget: (value, titleMeta) { - return Padding( - padding: const EdgeInsets.only(right: 5), child: Text( - value.toInt().toString(), - style: progressTextStyleLight.copyWith( - color: Theme.of(context).brightness == Brightness.dark - ? BrandColors.gray4 - : null, + bottomTitle(value.toInt()), + style: const TextStyle( + fontSize: 10, + color: Colors.purple, + fontWeight: FontWeight.bold, ), - )); - }, - interval: [ - ...listData[0].map((e) => e.value), - ...listData[1].map((e) => e.value) - ].reduce(max) * - 2 / - 10, - showTitles: false, + ), + ), + ), + showTitles: true, + ), + ), + leftTitles: AxisTitles( + sideTitles: SideTitles( + reservedSize: 50, + getTitlesWidget: (final value, final titleMeta) => Padding( + padding: const EdgeInsets.only(right: 5), + child: Text( + value.toInt().toString(), + style: progressTextStyleLight.copyWith( + color: Theme.of(context).brightness == Brightness.dark + ? BrandColors.gray4 + : null, + ), + ), + ), + interval: [ + ...listData[0].map((final e) => e.value), + ...listData[1].map((final e) => e.value) + ].reduce(max) * + 2 / + 10, + showTitles: false, + ), ), ), + gridData: FlGridData(show: true), ), - gridData: FlGridData(show: true), ), - ), - ); - } + ); bool checkToShowTitle( - double minValue, - double maxValue, - SideTitles sideTitles, - double appliedInterval, - double value, + final double minValue, + final double maxValue, + final SideTitles sideTitles, + final double appliedInterval, + final double value, ) { if (value < 0) { return false; } else if (value == 0) { return true; } - var diff = value - minValue; - var finalValue = diff / 20; + + final diff = value - minValue; + final finalValue = diff / 20; return finalValue - finalValue.floor() == 0; } - String bottomTitle(int value) { + String bottomTitle(final int value) { final hhmm = DateFormat('HH:mm'); - var day = DateFormat('MMMd'); + final day = DateFormat('MMMd'); String res; if (value <= 0) { return ''; } - var time = listData[0][value].time; + + final time = listData[0][value].time; switch (period) { case Period.hour: case Period.day: diff --git a/lib/ui/pages/server_details/server_details_screen.dart b/lib/ui/pages/server_details/server_details_screen.dart index 5eb3be3e..1f442220 100644 --- a/lib/ui/pages/server_details/server_details_screen.dart +++ b/lib/ui/pages/server_details/server_details_screen.dart @@ -22,8 +22,8 @@ import 'package:selfprivacy/utils/named_font_weight.dart'; import 'package:selfprivacy/utils/route_transitions/basic.dart'; import 'package:timezone/timezone.dart'; -import 'cpu_chart.dart'; -import 'network_charts.dart'; +import 'package:selfprivacy/ui/pages/server_details/cpu_chart.dart'; +import 'package:selfprivacy/ui/pages/server_details/network_charts.dart'; part 'chart.dart'; part 'header.dart'; @@ -34,7 +34,7 @@ part 'time_zone/time_zone.dart'; var navigatorKey = GlobalKey(); class ServerDetailsScreen extends StatefulWidget { - const ServerDetailsScreen({Key? key}) : super(key: key); + const ServerDetailsScreen({final super.key}); @override State createState() => _ServerDetailsScreenState(); @@ -60,13 +60,13 @@ class _ServerDetailsScreenState extends State } @override - Widget build(BuildContext context) { - var isReady = context.watch().state + Widget build(final BuildContext context) { + final bool isReady = context.watch().state is ServerInstallationFinished; - var providerState = isReady ? StateType.stable : StateType.uninitialized; + final providerState = isReady ? StateType.stable : StateType.uninitialized; return BlocProvider( - create: (context) => ServerDetailsCubit()..check(), + create: (final context) => ServerDetailsCubit()..check(), child: Scaffold( appBar: PreferredSize( preferredSize: const Size.fromHeight(52), @@ -97,19 +97,20 @@ class _ServerDetailsScreenState extends State crossAxisAlignment: CrossAxisAlignment.start, children: [ _Header( - providerState: providerState, - tabController: tabController), + providerState: providerState, + tabController: tabController, + ), BrandText.body1('providers.server.bottom_sheet.1'.tr()), ], ), ), const SizedBox(height: 10), BlocProvider( - create: (context) => HetznerMetricsCubit()..restart(), - child: const _Chart(), + create: (final context) => HetznerMetricsCubit()..restart(), + child: _Chart(), ), const SizedBox(height: 20), - const _TextDetails(), + _TextDetails(), ], ), ), diff --git a/lib/ui/pages/server_details/server_settings.dart b/lib/ui/pages/server_details/server_settings.dart index 93393632..18d425e6 100644 --- a/lib/ui/pages/server_details/server_settings.dart +++ b/lib/ui/pages/server_details/server_settings.dart @@ -2,15 +2,14 @@ part of 'server_details_screen.dart'; class _ServerSettings extends StatelessWidget { const _ServerSettings({ - Key? key, required this.tabController, - }) : super(key: key); + }); final TabController tabController; @override - Widget build(BuildContext context) { - var serverDetailsState = context.watch().state; + Widget build(final BuildContext context) { + final serverDetailsState = context.watch().state; if (serverDetailsState is ServerDetailsNotReady) { return const Text('not ready'); } else if (serverDetailsState is! Loaded) { @@ -37,7 +36,7 @@ class _ServerSettings extends StatelessWidget { ), const BrandDivider(), SwitcherBlock( - onChange: (_) {}, + onChange: (final _) {}, isActive: serverDetailsState.autoUpgradeSettings.enable, child: const _TextColumn( title: 'Allow Auto-upgrade', @@ -46,7 +45,7 @@ class _ServerSettings extends StatelessWidget { ), ), SwitcherBlock( - onChange: (_) {}, + onChange: (final _) {}, isActive: serverDetailsState.autoUpgradeSettings.allowReboot, child: const _TextColumn( title: 'Reboot after upgrade', @@ -71,60 +70,55 @@ class _ServerSettings extends StatelessWidget { class _Button extends StatelessWidget { const _Button({ - Key? key, required this.onTap, required this.child, - }) : super(key: key); + }); final Widget child; final VoidCallback onTap; @override - Widget build(BuildContext context) { - return InkWell( - onTap: onTap, - child: Container( - padding: const EdgeInsets.only(top: 20, bottom: 5), - decoration: const BoxDecoration( + Widget build(final BuildContext context) => InkWell( + onTap: onTap, + child: Container( + padding: const EdgeInsets.only(top: 20, bottom: 5), + decoration: const BoxDecoration( border: Border( - bottom: BorderSide(width: 1, color: BrandColors.dividerColor), - )), - child: child, - ), - ); - } + bottom: BorderSide(width: 1, color: BrandColors.dividerColor), + ), + ), + child: child, + ), + ); } class _TextColumn extends StatelessWidget { const _TextColumn({ - Key? key, required this.title, required this.value, this.hasWarning = false, - }) : super(key: key); + }); final String title; final String value; final bool hasWarning; @override - Widget build(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - BrandText.body1( - title, - style: TextStyle(color: hasWarning ? BrandColors.warning : null), - ), - const SizedBox(height: 5), - BrandText.body1( - value, - style: TextStyle( - fontSize: 13, - height: 1.53, - color: hasWarning ? BrandColors.warning : BrandColors.gray1, + Widget build(final BuildContext context) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BrandText.body1( + title, + style: TextStyle(color: hasWarning ? BrandColors.warning : null), ), - ), - ], - ); - } + const SizedBox(height: 5), + BrandText.body1( + value, + style: TextStyle( + fontSize: 13, + height: 1.53, + color: hasWarning ? BrandColors.warning : BrandColors.gray1, + ), + ), + ], + ); } diff --git a/lib/ui/pages/server_details/text_details.dart b/lib/ui/pages/server_details/text_details.dart index 397f7da1..2285d305 100644 --- a/lib/ui/pages/server_details/text_details.dart +++ b/lib/ui/pages/server_details/text_details.dart @@ -1,19 +1,17 @@ part of 'server_details_screen.dart'; class _TextDetails extends StatelessWidget { - const _TextDetails({Key? key}) : super(key: key); - @override - Widget build(BuildContext context) { - var details = context.watch().state; + 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) { - var data = details.serverInfo; - var checkTime = details.checkTime; + final data = details.serverInfo; + final checkTime = details.checkTime; return Column( children: [ Center(child: BrandText.h3('providers.server.bottom_sheet.2'.tr())), @@ -128,44 +126,38 @@ class _TextDetails extends StatelessWidget { } } - Widget getRowTitle(String title) { - return Padding( - padding: const EdgeInsets.only(right: 10), - child: BrandText.h5( - title, - textAlign: TextAlign.right, - ), - ); - } + Widget getRowTitle(final String title) => Padding( + padding: const EdgeInsets.only(right: 10), + child: BrandText.h5( + title, + textAlign: TextAlign.right, + ), + ); - Widget getRowValue(String title, {bool isBold = false}) { - return BrandText.body1( - title, - style: isBold - ? const TextStyle( - fontWeight: NamedFontWeight.demiBold, - ) - : null, - ); - } + Widget getRowValue(final String title, {final bool isBold = false}) => + BrandText.body1( + title, + style: isBold + ? const TextStyle( + fontWeight: NamedFontWeight.demiBold, + ) + : null, + ); } class _TempMessage extends StatelessWidget { const _TempMessage({ - Key? key, required this.message, - }) : super(key: key); + }); final String message; @override - Widget build(BuildContext context) { - return SizedBox( - height: MediaQuery.of(context).size.height - 100, - child: Center( - child: BrandText.body2(message), - ), - ); - } + Widget build(final BuildContext context) => SizedBox( + height: MediaQuery.of(context).size.height - 100, + child: Center( + child: BrandText.body2(message), + ), + ); } final DateFormat formatter = DateFormat('HH:mm:ss'); diff --git a/lib/ui/pages/server_details/time_zone/time_zone.dart b/lib/ui/pages/server_details/time_zone/time_zone.dart index 402aeb26..33799c35 100644 --- a/lib/ui/pages/server_details/time_zone/time_zone.dart +++ b/lib/ui/pages/server_details/time_zone/time_zone.dart @@ -1,11 +1,13 @@ part of '../server_details_screen.dart'; final List locations = timeZoneDatabase.locations.values.toList() - ..sort((l1, l2) => - l1.currentTimeZone.offset.compareTo(l2.currentTimeZone.offset)); + ..sort( + (final l1, final l2) => + l1.currentTimeZone.offset.compareTo(l2.currentTimeZone.offset), + ); class SelectTimezone extends StatefulWidget { - const SelectTimezone({Key? key}) : super(key: key); + const SelectTimezone({final super.key}); @override State createState() => _SelectTimezoneState(); @@ -20,15 +22,20 @@ class _SelectTimezoneState extends State { super.initState(); } - void _afterLayout(_) { - var t = DateTime.now().timeZoneOffset; - var index = locations.indexWhere((element) => - Duration(milliseconds: element.currentTimeZone.offset) == t); + void _afterLayout(final _) { + final t = DateTime.now().timeZoneOffset; + final index = locations.indexWhere( + (final element) => + Duration(milliseconds: element.currentTimeZone.offset) == t, + ); print(t); if (index >= 0) { - controller.animateTo(60.0 * index, - duration: const Duration(milliseconds: 300), curve: Curves.easeIn); + controller.animateTo( + 60.0 * index, + duration: const Duration(milliseconds: 300), + curve: Curves.easeIn, + ); } } @@ -39,69 +46,69 @@ class _SelectTimezoneState extends State { } @override - Widget build(BuildContext context) { - return Scaffold( - appBar: const PreferredSize( - preferredSize: Size.fromHeight(52), - child: BrandHeader( - title: 'select timezone', - hasBackButton: true, + Widget build(final BuildContext context) => Scaffold( + appBar: const PreferredSize( + preferredSize: Size.fromHeight(52), + child: BrandHeader( + title: 'select timezone', + hasBackButton: true, + ), ), - ), - body: ListView( - controller: controller, - children: locations - .asMap() - .map((key, value) { - var duration = - Duration(milliseconds: value.currentTimeZone.offset); - var area = value.currentTimeZone.abbreviation - .replaceAll(RegExp(r'[\d+()-]'), ''); + body: ListView( + controller: controller, + children: locations + .asMap() + .map((final key, final value) { + final duration = + Duration(milliseconds: value.currentTimeZone.offset); + final area = value.currentTimeZone.abbreviation + .replaceAll(RegExp(r'[\d+()-]'), ''); - String timezoneName = value.name; - if (context.locale.toString() == 'ru') { - timezoneName = russian[value.name] ?? - () { - var arr = value.name.split('/')..removeAt(0); - return arr.join('/'); - }(); - } + String timezoneName = value.name; + if (context.locale.toString() == 'ru') { + timezoneName = russian[value.name] ?? + () { + final arr = value.name.split('/')..removeAt(0); + return arr.join('/'); + }(); + } - return MapEntry( - key, - Container( - height: 60, - padding: const EdgeInsets.symmetric(horizontal: 20), - decoration: const BoxDecoration( - border: Border( + return MapEntry( + key, + Container( + height: 60, + padding: const EdgeInsets.symmetric(horizontal: 20), + decoration: const BoxDecoration( + border: Border( bottom: BorderSide( - color: BrandColors.dividerColor, - )), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - BrandText.body1( - timezoneName, - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, + color: BrandColors.dividerColor, ), ), - BrandText.small( + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + BrandText.body1( + timezoneName, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + BrandText.small( 'GMT ${duration.toDayHourMinuteFormat()} ${area.isNotEmpty ? '($area)' : ''}', style: const TextStyle( fontSize: 13, - )), - ], + ), + ), + ], + ), ), - ), - ); - }) - .values - .toList(), - ), - ); - } + ); + }) + .values + .toList(), + ), + ); } diff --git a/lib/ui/pages/services/services.dart b/lib/ui/pages/services/services.dart index c4939615..0b8ea12d 100644 --- a/lib/ui/pages/services/services.dart +++ b/lib/ui/pages/services/services.dart @@ -21,7 +21,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:selfprivacy/utils/ui_helpers.dart'; import 'package:url_launcher/url_launcher_string.dart'; -import '../root_route.dart'; +import 'package:selfprivacy/ui/pages/root_route.dart'; const switchableServices = [ ServiceTypes.passwordManager, @@ -32,14 +32,14 @@ const switchableServices = [ ]; class ServicesPage extends StatefulWidget { - const ServicesPage({Key? key}) : super(key: key); + const ServicesPage({final super.key}); @override State createState() => _ServicesPageState(); } -void _launchURL(url) async { - var canLaunch = await canLaunchUrlString(url); +void _launchURL(final url) async { + final canLaunch = await canLaunchUrlString(url); if (canLaunch) { try { @@ -56,8 +56,8 @@ void _launchURL(url) async { class _ServicesPageState extends State { @override - Widget build(BuildContext context) { - var isReady = context.watch().state + Widget build(final BuildContext context) { + final isReady = context.watch().state is ServerInstallationFinished; return Scaffold( @@ -74,12 +74,14 @@ class _ServicesPageState extends State { const SizedBox(height: 24), if (!isReady) ...[const NotReadyCard(), const SizedBox(height: 24)], ...ServiceTypes.values - .map((t) => Padding( - padding: const EdgeInsets.only( - bottom: 30, - ), - child: _Card(serviceType: t), - )) + .map( + (final t) => Padding( + padding: const EdgeInsets.only( + bottom: 30, + ), + child: _Card(serviceType: t), + ), + ) .toList() ], ), @@ -88,31 +90,32 @@ class _ServicesPageState extends State { } class _Card extends StatelessWidget { - const _Card({Key? key, required this.serviceType}) : super(key: key); + const _Card({required this.serviceType}); final ServiceTypes serviceType; @override - Widget build(BuildContext context) { - var isReady = context.watch().state + Widget build(final BuildContext context) { + final isReady = context.watch().state is ServerInstallationFinished; - var changeTab = context.read().onPress; + final changeTab = context.read().onPress; - var serviceState = context.watch().state; - var jobsCubit = context.watch(); - var jobState = jobsCubit.state; + final serviceState = context.watch().state; + final jobsCubit = context.watch(); + final jobState = jobsCubit.state; - var switchableService = switchableServices.contains(serviceType); - var hasSwitchJob = switchableService && + final switchableService = switchableServices.contains(serviceType); + final hasSwitchJob = switchableService && jobState is JobsStateWithJobs && - jobState.jobList - .any((el) => el is ServiceToggleJob && el.type == serviceType); + jobState.jobList.any( + (final el) => el is ServiceToggleJob && el.type == serviceType, + ); - var isSwitchOn = isReady && + final isSwitchOn = isReady && (!switchableServices.contains(serviceType) || serviceState.isEnableByType(serviceType)); - var config = context.watch().state; - var domainName = UiHelpers.getDomainName(config); + final config = context.watch().state; + final domainName = UiHelpers.getDomainName(config); return GestureDetector( onTap: isSwitchOn @@ -120,16 +123,14 @@ class _Card extends StatelessWidget { context: context, // isScrollControlled: true, // backgroundColor: Colors.transparent, - builder: (BuildContext context) { - return _ServiceDetails( - serviceType: serviceType, - status: - isSwitchOn ? StateType.stable : StateType.uninitialized, - title: serviceType.title, - icon: serviceType.icon, - changeTab: changeTab, - ); - }, + builder: (final BuildContext context) => _ServiceDetails( + serviceType: serviceType, + status: + isSwitchOn ? StateType.stable : StateType.uninitialized, + title: serviceType.title, + icon: serviceType.icon, + changeTab: changeTab, + ), ) : null, child: BrandCards.big( @@ -146,12 +147,13 @@ class _Card extends StatelessWidget { if (isReady && switchableService) ...[ const Spacer(), Builder( - builder: (context) { + builder: (final context) { late bool isActive; if (hasSwitchJob) { - isActive = ((jobState).jobList.firstWhere((el) => - el is ServiceToggleJob && - el.type == serviceType) as ServiceToggleJob) + isActive = (jobState.jobList.firstWhere( + (final el) => + el is ServiceToggleJob && el.type == serviceType, + ) as ServiceToggleJob) .needToTurnOn; } else { isActive = serviceState.isEnableByType(serviceType); @@ -159,7 +161,7 @@ class _Card extends StatelessWidget { return BrandSwitch( value: isActive, - onChanged: (value) => + onChanged: (final value) => jobsCubit.createOrRemoveServiceToggleJob( ServiceToggleJob( type: serviceType, @@ -186,7 +188,8 @@ class _Card extends StatelessWidget { children: [ GestureDetector( onTap: () => _launchURL( - 'https://${serviceType.subdomain}.$domainName'), + 'https://${serviceType.subdomain}.$domainName', + ), child: Text( '${serviceType.subdomain}.$domainName', style: TextStyle( @@ -200,16 +203,18 @@ class _Card extends StatelessWidget { ], ), if (serviceType == ServiceTypes.mail) - Column(children: [ - Text( - domainName, - style: TextStyle( - color: Theme.of(context).colorScheme.primary, - decoration: TextDecoration.underline, + Column( + children: [ + Text( + domainName, + style: TextStyle( + color: Theme.of(context).colorScheme.primary, + decoration: TextDecoration.underline, + ), ), - ), - const SizedBox(height: 10), - ]), + const SizedBox(height: 10), + ], + ), BrandText.body2(serviceType.loginInfo), const SizedBox(height: 10), BrandText.body2(serviceType.subtitle), @@ -244,13 +249,12 @@ class _Card extends StatelessWidget { class _ServiceDetails extends StatelessWidget { const _ServiceDetails({ - Key? key, required this.serviceType, required this.icon, required this.status, required this.title, required this.changeTab, - }) : super(key: key); + }); final ServiceTypes serviceType; final IconData icon; @@ -259,13 +263,13 @@ class _ServiceDetails extends StatelessWidget { final ValueChanged changeTab; @override - Widget build(BuildContext context) { + Widget build(final BuildContext context) { late Widget child; - var config = context.watch().state; - var domainName = UiHelpers.getDomainName(config); + final config = context.watch().state; + final domainName = UiHelpers.getDomainName(config); - var linksStyle = body1Style.copyWith( + final linksStyle = body1Style.copyWith( fontSize: 15, color: Theme.of(context).brightness == Brightness.dark ? Colors.white @@ -274,7 +278,7 @@ class _ServiceDetails extends StatelessWidget { decoration: TextDecoration.underline, ); - var textStyle = body1Style.copyWith( + final textStyle = body1Style.copyWith( color: Theme.of(context).brightness == Brightness.dark ? Colors.white : BrandColors.black, @@ -282,163 +286,171 @@ class _ServiceDetails extends StatelessWidget { switch (serviceType) { case ServiceTypes.mail: child = RichText( - text: TextSpan( - children: [ - TextSpan( - text: 'services.mail.bottom_sheet.1'.tr(args: [domainName]), - style: textStyle, - ), - const WidgetSpan(child: SizedBox(width: 5)), - WidgetSpan( - child: Padding( - padding: const EdgeInsets.only(bottom: 0.8), - child: GestureDetector( - child: Text( - 'services.mail.bottom_sheet.2'.tr(), - style: linksStyle, + text: TextSpan( + children: [ + TextSpan( + text: 'services.mail.bottom_sheet.1'.tr(args: [domainName]), + style: textStyle, + ), + const WidgetSpan(child: SizedBox(width: 5)), + WidgetSpan( + child: Padding( + padding: const EdgeInsets.only(bottom: 0.8), + child: GestureDetector( + child: Text( + 'services.mail.bottom_sheet.2'.tr(), + style: linksStyle, + ), + onTap: () { + Navigator.of(context).pop(); + changeTab(2); + }, ), - onTap: () { - Navigator.of(context).pop(); - changeTab(2); - }, ), ), - ), - ], - )); + ], + ), + ); break; case ServiceTypes.messenger: child = RichText( - text: TextSpan( - children: [ - TextSpan( - text: 'services.messenger.bottom_sheet.1'.tr(args: [domainName]), - style: textStyle, - ) - ], - )); + text: TextSpan( + children: [ + TextSpan( + text: + 'services.messenger.bottom_sheet.1'.tr(args: [domainName]), + style: textStyle, + ) + ], + ), + ); break; case ServiceTypes.passwordManager: child = RichText( - text: TextSpan( - children: [ - TextSpan( - text: 'services.password_manager.bottom_sheet.1' - .tr(args: [domainName]), - style: textStyle, - ), - const WidgetSpan(child: SizedBox(width: 5)), - WidgetSpan( - child: Padding( - padding: const EdgeInsets.only(bottom: 0.8), - child: GestureDetector( - onTap: () => _launchURL('https://password.$domainName'), - child: Text( - 'password.$domainName', - style: linksStyle, + text: TextSpan( + children: [ + TextSpan( + text: 'services.password_manager.bottom_sheet.1' + .tr(args: [domainName]), + style: textStyle, + ), + const WidgetSpan(child: SizedBox(width: 5)), + WidgetSpan( + child: Padding( + padding: const EdgeInsets.only(bottom: 0.8), + child: GestureDetector( + onTap: () => _launchURL('https://password.$domainName'), + child: Text( + 'password.$domainName', + style: linksStyle, + ), ), ), ), - ), - ], - )); + ], + ), + ); break; case ServiceTypes.video: child = RichText( - text: TextSpan( - children: [ - TextSpan( - text: 'services.video.bottom_sheet.1'.tr(args: [domainName]), - style: textStyle, - ), - const WidgetSpan(child: SizedBox(width: 5)), - WidgetSpan( - child: Padding( - padding: const EdgeInsets.only(bottom: 0.8), - child: GestureDetector( - onTap: () => _launchURL('https://meet.$domainName'), - child: Text( - 'meet.$domainName', - style: linksStyle, + text: TextSpan( + children: [ + TextSpan( + text: 'services.video.bottom_sheet.1'.tr(args: [domainName]), + style: textStyle, + ), + const WidgetSpan(child: SizedBox(width: 5)), + WidgetSpan( + child: Padding( + padding: const EdgeInsets.only(bottom: 0.8), + child: GestureDetector( + onTap: () => _launchURL('https://meet.$domainName'), + child: Text( + 'meet.$domainName', + style: linksStyle, + ), ), ), ), - ), - ], - )); + ], + ), + ); break; case ServiceTypes.cloud: child = RichText( - text: TextSpan( - children: [ - TextSpan( - text: 'services.cloud.bottom_sheet.1'.tr(args: [domainName]), - style: textStyle, - ), - const WidgetSpan(child: SizedBox(width: 5)), - WidgetSpan( - child: Padding( - padding: const EdgeInsets.only(bottom: 0.8), - child: GestureDetector( - onTap: () => _launchURL('https://cloud.$domainName'), - child: Text( - 'cloud.$domainName', - style: linksStyle, + text: TextSpan( + children: [ + TextSpan( + text: 'services.cloud.bottom_sheet.1'.tr(args: [domainName]), + style: textStyle, + ), + const WidgetSpan(child: SizedBox(width: 5)), + WidgetSpan( + child: Padding( + padding: const EdgeInsets.only(bottom: 0.8), + child: GestureDetector( + onTap: () => _launchURL('https://cloud.$domainName'), + child: Text( + 'cloud.$domainName', + style: linksStyle, + ), ), ), ), - ), - ], - )); + ], + ), + ); break; case ServiceTypes.socialNetwork: child = RichText( - text: TextSpan( - children: [ - TextSpan( - text: 'services.social_network.bottom_sheet.1' - .tr(args: [domainName]), - style: textStyle, - ), - const WidgetSpan(child: SizedBox(width: 5)), - WidgetSpan( - child: Padding( - padding: const EdgeInsets.only(bottom: 0.8), - child: GestureDetector( - onTap: () => _launchURL('https://social.$domainName'), - child: Text( - 'social.$domainName', - style: linksStyle, + text: TextSpan( + children: [ + TextSpan( + text: 'services.social_network.bottom_sheet.1' + .tr(args: [domainName]), + style: textStyle, + ), + const WidgetSpan(child: SizedBox(width: 5)), + WidgetSpan( + child: Padding( + padding: const EdgeInsets.only(bottom: 0.8), + child: GestureDetector( + onTap: () => _launchURL('https://social.$domainName'), + child: Text( + 'social.$domainName', + style: linksStyle, + ), ), ), ), - ), - ], - )); + ], + ), + ); break; case ServiceTypes.git: child = RichText( - text: TextSpan( - children: [ - TextSpan( - text: 'services.git.bottom_sheet.1'.tr(args: [domainName]), - style: textStyle, - ), - const WidgetSpan(child: SizedBox(width: 5)), - WidgetSpan( - child: Padding( - padding: const EdgeInsets.only(bottom: 0.8), - child: GestureDetector( - onTap: () => _launchURL('https://git.$domainName'), - child: Text( - 'git.$domainName', - style: linksStyle, + text: TextSpan( + children: [ + TextSpan( + text: 'services.git.bottom_sheet.1'.tr(args: [domainName]), + style: textStyle, + ), + const WidgetSpan(child: SizedBox(width: 5)), + WidgetSpan( + child: Padding( + padding: const EdgeInsets.only(bottom: 0.8), + child: GestureDetector( + onTap: () => _launchURL('https://git.$domainName'), + child: Text( + 'git.$domainName', + style: linksStyle, + ), ), ), ), - ), - ], - )); + ], + ), + ); break; case ServiceTypes.vpn: child = Text( diff --git a/lib/ui/pages/setup/initializing.dart b/lib/ui/pages/setup/initializing.dart index e3fd0e77..1710113b 100644 --- a/lib/ui/pages/setup/initializing.dart +++ b/lib/ui/pages/setup/initializing.dart @@ -21,16 +21,16 @@ import 'package:selfprivacy/ui/pages/setup/recovering/recovery_routing.dart'; import 'package:selfprivacy/utils/route_transitions/basic.dart'; class InitializingPage extends StatelessWidget { - const InitializingPage({Key? key}) : super(key: key); + const InitializingPage({final super.key}); @override - Widget build(BuildContext context) { - var cubit = context.watch(); + Widget build(final BuildContext context) { + final cubit = context.watch(); if (cubit.state is ServerInstallationRecovery) { return const RecoveryRouting(); } else { - var actualInitializingPage = [ + final actualInitializingPage = [ () => _stepHetzner(cubit), () => _stepCloudflare(cubit), () => _stepBackblaze(cubit), @@ -44,7 +44,7 @@ class InitializingPage extends StatelessWidget { ][cubit.state.progress.index](); return BlocListener( - listener: (context, state) { + listener: (final context, final state) { if (cubit.state is ServerInstallationFinished) { Navigator.of(context) .pushReplacement(materialRoute(const RootPage())); @@ -82,43 +82,48 @@ class InitializingPage extends StatelessWidget { ), ), ConstrainedBox( - constraints: BoxConstraints( - minHeight: MediaQuery.of(context).size.height - - MediaQuery.of(context).padding.top - - MediaQuery.of(context).padding.bottom - - 566, - ), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ + constraints: BoxConstraints( + minHeight: MediaQuery.of(context).size.height - + MediaQuery.of(context).padding.top - + MediaQuery.of(context).padding.bottom - + 566, + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + alignment: Alignment.center, + child: BrandButton.text( + title: cubit.state is ServerInstallationFinished + ? 'basis.close'.tr() + : 'basis.later'.tr(), + onPressed: () { + Navigator.of(context).pushAndRemoveUntil( + materialRoute(const RootPage()), + (final predicate) => false, + ); + }, + ), + ), + if (cubit.state is ServerInstallationFinished) + Container() + else Container( alignment: Alignment.center, child: BrandButton.text( - title: cubit.state is ServerInstallationFinished - ? 'basis.close'.tr() - : 'basis.later'.tr(), + title: 'basis.connect_to_existing'.tr(), onPressed: () { - Navigator.of(context).pushAndRemoveUntil( - materialRoute(const RootPage()), - (predicate) => false, + Navigator.of(context).push( + materialRoute( + const RecoveryRouting(), + ), ); }, ), - ), - (cubit.state is ServerInstallationFinished) - ? Container() - : Container( - alignment: Alignment.center, - child: BrandButton.text( - title: 'basis.connect_to_existing'.tr(), - onPressed: () { - Navigator.of(context).push(materialRoute( - const RecoveryRouting())); - }, - ), - ) - ], - )), + ) + ], + ), + ), ], ), ), @@ -128,324 +133,338 @@ class InitializingPage extends StatelessWidget { } } - Widget _stepHetzner(ServerInstallationCubit serverInstallationCubit) { - return BlocProvider( - create: (context) => HetznerFormCubit(serverInstallationCubit), - child: Builder(builder: (context) { - var formCubitState = context.watch().state; - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/logos/hetzner.png', - width: 150, - ), - const SizedBox(height: 10), - BrandText.h2('initializing.1'.tr()), - const SizedBox(height: 10), - BrandText.body2('initializing.2'.tr()), - const Spacer(), - CubitFormTextField( - formFieldCubit: context.read().apiKey, - textAlign: TextAlign.center, - scrollPadding: const EdgeInsets.only(bottom: 70), - decoration: const InputDecoration( - hintText: 'Hetzner API Token', - ), - ), - const Spacer(), - BrandButton.rised( - onPressed: formCubitState.isSubmitting - ? null - : () => context.read().trySubmit(), - text: 'basis.connect'.tr(), - ), - const SizedBox(height: 10), - BrandButton.text( - onPressed: () => - _showModal(context, const _HowTo(fileName: 'how_hetzner')), - title: 'initializing.how'.tr(), - ), - ], - ); - }), - ); - } + Widget _stepHetzner(final ServerInstallationCubit serverInstallationCubit) => + BlocProvider( + create: (final context) => HetznerFormCubit(serverInstallationCubit), + child: Builder( + builder: (final context) { + final formCubitState = context.watch().state; + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Image.asset( + 'assets/images/logos/hetzner.png', + width: 150, + ), + const SizedBox(height: 10), + BrandText.h2('initializing.1'.tr()), + const SizedBox(height: 10), + BrandText.body2('initializing.2'.tr()), + const Spacer(), + CubitFormTextField( + formFieldCubit: context.read().apiKey, + textAlign: TextAlign.center, + scrollPadding: const EdgeInsets.only(bottom: 70), + decoration: const InputDecoration( + hintText: 'Hetzner API Token', + ), + ), + const Spacer(), + BrandButton.rised( + onPressed: formCubitState.isSubmitting + ? null + : () => context.read().trySubmit(), + text: 'basis.connect'.tr(), + ), + const SizedBox(height: 10), + BrandButton.text( + onPressed: () => _showModal( + context, + const _HowTo(fileName: 'how_hetzner'), + ), + title: 'initializing.how'.tr(), + ), + ], + ); + }, + ), + ); - void _showModal(BuildContext context, Widget widget) { + void _showModal(final BuildContext context, final Widget widget) { showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, - builder: (BuildContext context) { - return widget; - }, + builder: (final BuildContext context) => widget, ); } - Widget _stepCloudflare(ServerInstallationCubit initializingCubit) { - return BlocProvider( - create: (context) => CloudFlareFormCubit(initializingCubit), - child: Builder(builder: (context) { - var formCubitState = context.watch().state; + Widget _stepCloudflare(final ServerInstallationCubit initializingCubit) => + BlocProvider( + create: (final context) => CloudFlareFormCubit(initializingCubit), + child: Builder( + builder: (final context) { + final formCubitState = context.watch().state; - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/logos/cloudflare.png', - width: 150, - ), - const SizedBox(height: 10), - BrandText.h2('initializing.3'.tr()), - const SizedBox(height: 10), - BrandText.body2('initializing.4'.tr()), - const Spacer(), - CubitFormTextField( - formFieldCubit: context.read().apiKey, - textAlign: TextAlign.center, - scrollPadding: const EdgeInsets.only(bottom: 70), - decoration: InputDecoration( - hintText: 'initializing.5'.tr(), - ), - ), - const Spacer(), - BrandButton.rised( - onPressed: formCubitState.isSubmitting - ? null - : () => context.read().trySubmit(), - text: 'basis.connect'.tr(), - ), - const SizedBox(height: 10), - BrandButton.text( - onPressed: () => _showModal( - context, - const _HowTo( - fileName: 'how_cloudflare', - )), - title: 'initializing.how'.tr(), - ), - ], - ); - }), - ); - } - - Widget _stepBackblaze(ServerInstallationCubit initializingCubit) { - return BlocProvider( - create: (context) => BackblazeFormCubit(initializingCubit), - child: Builder(builder: (context) { - var formCubitState = context.watch().state; - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/logos/backblaze.png', - height: 50, - ), - const SizedBox(height: 10), - BrandText.h2('initializing.6'.tr()), - const SizedBox(height: 10), - const Spacer(), - CubitFormTextField( - formFieldCubit: context.read().keyId, - textAlign: TextAlign.center, - scrollPadding: const EdgeInsets.only(bottom: 70), - decoration: const InputDecoration( - hintText: 'KeyID', - ), - ), - const Spacer(), - CubitFormTextField( - formFieldCubit: context.read().applicationKey, - textAlign: TextAlign.center, - scrollPadding: const EdgeInsets.only(bottom: 70), - decoration: const InputDecoration( - hintText: 'Master Application Key', - ), - ), - const Spacer(), - BrandButton.rised( - onPressed: formCubitState.isSubmitting - ? null - : () => context.read().trySubmit(), - text: 'basis.connect'.tr(), - ), - const SizedBox(height: 10), - BrandButton.text( - onPressed: () => _showModal( - context, - const _HowTo( - fileName: 'how_backblaze', - )), - title: 'initializing.how'.tr(), - ), - ], - ); - }), - ); - } - - Widget _stepDomain(ServerInstallationCubit initializingCubit) { - return BlocProvider( - create: (context) => DomainSetupCubit(initializingCubit)..load(), - child: Builder(builder: (context) { - DomainSetupState state = context.watch().state; - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/logos/cloudflare.png', - width: 150, - ), - const SizedBox(height: 30), - BrandText.h2('basis.domain'.tr()), - const SizedBox(height: 10), - if (state is Empty) BrandText.body2('initializing.7'.tr()), - if (state is Loading) - BrandText.body2( - state.type == LoadingTypes.loadingDomain - ? 'initializing.8'.tr() - : 'basis.saving'.tr(), - ), - if (state is MoreThenOne) - BrandText.body2( - 'initializing.9'.tr(), - ), - if (state is Loaded) ...[ - const SizedBox(height: 10), - Row( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.end, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Expanded( - child: BrandText.h3( - state.domain, - textAlign: TextAlign.center, - ), - ), - SizedBox( - width: 56, - child: BrandButton.rised( - onPressed: () => context.read().load(), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: const [ - Icon( - Icons.refresh, - color: Colors.white, - ), - ], - ), - ), - ), - ], - ) - ], - if (state is Empty) ...[ - const SizedBox(height: 30), - BrandButton.rised( - onPressed: () => context.read().load(), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Icon( - Icons.refresh, - color: Colors.white, - ), - const SizedBox(width: 10), - BrandText.buttonTitleText('Обновить cписок'), - ], + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Image.asset( + 'assets/images/logos/cloudflare.png', + width: 150, ), - ), - ], - if (state is Loaded) ...[ - const SizedBox(height: 30), - BrandButton.rised( - onPressed: () => context.read().saveDomain(), - text: 'initializing.10'.tr(), - ), - ], - const SizedBox( - height: 10, - width: double.infinity, - ), - ], - ); - }), - ); - } - - Widget _stepUser(ServerInstallationCubit initializingCubit) { - return BlocProvider( - create: (context) => - RootUserFormCubit(initializingCubit, FieldCubitFactory(context)), - child: Builder(builder: (context) { - var formCubitState = context.watch().state; - - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - BrandText.h2('initializing.22'.tr()), - const SizedBox(height: 10), - BrandText.body2('initializing.23'.tr()), - const Spacer(), - CubitFormTextField( - formFieldCubit: context.read().userName, - textAlign: TextAlign.center, - scrollPadding: const EdgeInsets.only(bottom: 70), - decoration: InputDecoration( - hintText: 'basis.nickname'.tr(), - ), - ), - const SizedBox(height: 10), - BlocBuilder, FieldCubitState>( - bloc: context.read().isVisible, - builder: (context, state) { - var isVisible = state.value; - return CubitFormTextField( - obscureText: !isVisible, - formFieldCubit: context.read().password, + const SizedBox(height: 10), + BrandText.h2('initializing.3'.tr()), + const SizedBox(height: 10), + BrandText.body2('initializing.4'.tr()), + const Spacer(), + CubitFormTextField( + formFieldCubit: context.read().apiKey, textAlign: TextAlign.center, scrollPadding: const EdgeInsets.only(bottom: 70), decoration: InputDecoration( - hintText: 'basis.password'.tr(), - suffixIcon: IconButton( - icon: Icon( - isVisible ? Icons.visibility : Icons.visibility_off, - ), - onPressed: () => context - .read() - .isVisible - .setValue(!isVisible), - ), - suffixIconConstraints: const BoxConstraints(minWidth: 60), - prefixIconConstraints: const BoxConstraints(maxWidth: 60), - prefixIcon: Container(), + hintText: 'initializing.5'.tr(), ), - ); - }, - ), - const Spacer(), - BrandButton.rised( - onPressed: formCubitState.isSubmitting - ? null - : () => context.read().trySubmit(), - text: 'basis.connect'.tr(), - ), - ], - ); - }), - ); - } + ), + const Spacer(), + BrandButton.rised( + onPressed: formCubitState.isSubmitting + ? null + : () => context.read().trySubmit(), + text: 'basis.connect'.tr(), + ), + const SizedBox(height: 10), + BrandButton.text( + onPressed: () => _showModal( + context, + const _HowTo( + fileName: 'how_cloudflare', + ), + ), + title: 'initializing.how'.tr(), + ), + ], + ); + }, + ), + ); - Widget _stepServer(ServerInstallationCubit appConfigCubit) { - var isLoading = + Widget _stepBackblaze(final ServerInstallationCubit initializingCubit) => + BlocProvider( + create: (final context) => BackblazeFormCubit(initializingCubit), + child: Builder( + builder: (final context) { + final formCubitState = context.watch().state; + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Image.asset( + 'assets/images/logos/backblaze.png', + height: 50, + ), + const SizedBox(height: 10), + BrandText.h2('initializing.6'.tr()), + const SizedBox(height: 10), + const Spacer(), + CubitFormTextField( + formFieldCubit: context.read().keyId, + textAlign: TextAlign.center, + scrollPadding: const EdgeInsets.only(bottom: 70), + decoration: const InputDecoration( + hintText: 'KeyID', + ), + ), + const Spacer(), + CubitFormTextField( + formFieldCubit: + context.read().applicationKey, + textAlign: TextAlign.center, + scrollPadding: const EdgeInsets.only(bottom: 70), + decoration: const InputDecoration( + hintText: 'Master Application Key', + ), + ), + const Spacer(), + BrandButton.rised( + onPressed: formCubitState.isSubmitting + ? null + : () => context.read().trySubmit(), + text: 'basis.connect'.tr(), + ), + const SizedBox(height: 10), + BrandButton.text( + onPressed: () => _showModal( + context, + const _HowTo( + fileName: 'how_backblaze', + ), + ), + title: 'initializing.how'.tr(), + ), + ], + ); + }, + ), + ); + + Widget _stepDomain(final ServerInstallationCubit initializingCubit) => + BlocProvider( + create: (final context) => DomainSetupCubit(initializingCubit)..load(), + child: Builder( + builder: (final context) { + final DomainSetupState state = + context.watch().state; + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Image.asset( + 'assets/images/logos/cloudflare.png', + width: 150, + ), + const SizedBox(height: 30), + BrandText.h2('basis.domain'.tr()), + const SizedBox(height: 10), + if (state is Empty) BrandText.body2('initializing.7'.tr()), + if (state is Loading) + BrandText.body2( + state.type == LoadingTypes.loadingDomain + ? 'initializing.8'.tr() + : 'basis.saving'.tr(), + ), + if (state is MoreThenOne) + BrandText.body2( + 'initializing.9'.tr(), + ), + if (state is Loaded) ...[ + const SizedBox(height: 10), + Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: BrandText.h3( + state.domain, + textAlign: TextAlign.center, + ), + ), + SizedBox( + width: 56, + child: BrandButton.rised( + onPressed: () => + context.read().load(), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: const [ + Icon( + Icons.refresh, + color: Colors.white, + ), + ], + ), + ), + ), + ], + ) + ], + if (state is Empty) ...[ + const SizedBox(height: 30), + BrandButton.rised( + onPressed: () => context.read().load(), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Icon( + Icons.refresh, + color: Colors.white, + ), + const SizedBox(width: 10), + BrandText.buttonTitleText('Обновить cписок'), + ], + ), + ), + ], + if (state is Loaded) ...[ + const SizedBox(height: 30), + BrandButton.rised( + onPressed: () => + context.read().saveDomain(), + text: 'initializing.10'.tr(), + ), + ], + const SizedBox( + height: 10, + width: double.infinity, + ), + ], + ); + }, + ), + ); + + Widget _stepUser(final ServerInstallationCubit initializingCubit) => + BlocProvider( + create: (final context) => + RootUserFormCubit(initializingCubit, FieldCubitFactory(context)), + child: Builder( + builder: (final context) { + final formCubitState = context.watch().state; + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BrandText.h2('initializing.22'.tr()), + const SizedBox(height: 10), + BrandText.body2('initializing.23'.tr()), + const Spacer(), + CubitFormTextField( + formFieldCubit: context.read().userName, + textAlign: TextAlign.center, + scrollPadding: const EdgeInsets.only(bottom: 70), + decoration: InputDecoration( + hintText: 'basis.nickname'.tr(), + ), + ), + const SizedBox(height: 10), + BlocBuilder, FieldCubitState>( + bloc: context.read().isVisible, + builder: (final context, final state) { + final bool isVisible = state.value; + return CubitFormTextField( + obscureText: !isVisible, + formFieldCubit: + context.read().password, + textAlign: TextAlign.center, + scrollPadding: const EdgeInsets.only(bottom: 70), + decoration: InputDecoration( + hintText: 'basis.password'.tr(), + suffixIcon: IconButton( + icon: Icon( + isVisible ? Icons.visibility : Icons.visibility_off, + ), + onPressed: () => context + .read() + .isVisible + .setValue(!isVisible), + ), + suffixIconConstraints: + const BoxConstraints(minWidth: 60), + prefixIconConstraints: + const BoxConstraints(maxWidth: 60), + prefixIcon: Container(), + ), + ); + }, + ), + const Spacer(), + BrandButton.rised( + onPressed: formCubitState.isSubmitting + ? null + : () => context.read().trySubmit(), + text: 'basis.connect'.tr(), + ), + ], + ); + }, + ), + ); + + Widget _stepServer(final ServerInstallationCubit appConfigCubit) { + final bool isLoading = (appConfigCubit.state as ServerInstallationNotFinished).isLoading; - return Builder(builder: (context) { - return Column( + return Builder( + builder: (final context) => Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Spacer(flex: 2), @@ -454,20 +473,21 @@ class InitializingPage extends StatelessWidget { BrandText.body2('initializing.11'.tr()), const Spacer(), BrandButton.rised( - onPressed: isLoading - ? null - : () => appConfigCubit.createServerAndSetDnsRecords(), + onPressed: + isLoading ? null : appConfigCubit.createServerAndSetDnsRecords, text: isLoading ? 'basis.loading'.tr() : 'initializing.11'.tr(), ), ], - ); - }); + ), + ); } - Widget _stepCheck(ServerInstallationCubit appConfigCubit) { + Widget _stepCheck(final ServerInstallationCubit appConfigCubit) { assert( - appConfigCubit.state is ServerInstallationNotFinished, 'wrong state'); - var state = appConfigCubit.state as TimerState; + appConfigCubit.state is ServerInstallationNotFinished, + 'wrong state', + ); + final state = appConfigCubit.state as TimerState; late int doneCount; late String? text; if (state.isServerResetedSecondTime) { @@ -483,8 +503,8 @@ class InitializingPage extends StatelessWidget { text = 'initializing.15'.tr(); doneCount = 0; } - return Builder(builder: (context) { - return Column( + return Builder( + builder: (final context) => Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 15), @@ -497,9 +517,9 @@ class InitializingPage extends StatelessWidget { const SizedBox(height: 10), if (doneCount == 0 && state.dnsMatches != null) Column( - children: state.dnsMatches!.entries.map((entry) { - var domain = entry.key; - var isCorrect = entry.value; + children: state.dnsMatches!.entries.map((final entry) { + final String domain = entry.key; + final bool isCorrect = entry.value; return Row( children: [ if (isCorrect) const Icon(Icons.check, color: Colors.green), @@ -524,37 +544,32 @@ class InitializingPage extends StatelessWidget { ), if (state.isLoading) BrandText.body2('initializing.17'.tr()), ], - ); - }); - } - - Widget _addCard(Widget child) { - return Container( - height: 450, - padding: paddingH15V0, - child: BrandCards.big(child: child), + ), ); } + + Widget _addCard(final Widget child) => Container( + height: 450, + padding: paddingH15V0, + child: BrandCards.big(child: child), + ); } class _HowTo extends StatelessWidget { const _HowTo({ - Key? key, required this.fileName, - }) : super(key: key); + }); final String fileName; @override - Widget build(BuildContext context) { - return BrandBottomSheet( - isExpended: true, - child: Padding( - padding: paddingH15V0, - child: BrandMarkdown( - fileName: fileName, + Widget build(final BuildContext context) => BrandBottomSheet( + isExpended: true, + child: Padding( + padding: paddingH15V0, + child: BrandMarkdown( + fileName: fileName, + ), ), - ), - ); - } + ); } diff --git a/lib/ui/pages/setup/recovering/recover_by_new_device_key.dart b/lib/ui/pages/setup/recovering/recover_by_new_device_key.dart index 1c02f34d..d9fb3952 100644 --- a/lib/ui/pages/setup/recovering/recover_by_new_device_key.dart +++ b/lib/ui/pages/setup/recovering/recover_by_new_device_key.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:selfprivacy/logic/cubit/forms/setup/recovering/recovery_device_form_cubit.dart'; @@ -11,51 +9,52 @@ import 'package:selfprivacy/logic/cubit/server_installation/server_installation_ import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart'; class RecoverByNewDeviceKeyInstruction extends StatelessWidget { - const RecoverByNewDeviceKeyInstruction({Key? key}) : super(key: key); + const RecoverByNewDeviceKeyInstruction({final super.key}); @override - Widget build(BuildContext context) { - return BrandHeroScreen( - heroTitle: 'recovering.recovery_main_header'.tr(), - heroSubtitle: 'recovering.method_device_description'.tr(), - hasBackButton: true, - hasFlashButton: false, - onBackButtonPressed: () => - context.read().revertRecoveryStep(), - children: [ - FilledButton( - title: 'recovering.method_device_button'.tr(), - onPressed: () => Navigator.of(context) - .push(materialRoute(const RecoverByNewDeviceKeyInput())), - ) - ], - ); - } + Widget build(final BuildContext context) => BrandHeroScreen( + heroTitle: 'recovering.recovery_main_header'.tr(), + heroSubtitle: 'recovering.method_device_description'.tr(), + hasBackButton: true, + hasFlashButton: false, + onBackButtonPressed: () => + context.read().revertRecoveryStep(), + children: [ + FilledButton( + title: 'recovering.method_device_button'.tr(), + onPressed: () => Navigator.of(context) + .push(materialRoute(const RecoverByNewDeviceKeyInput())), + ) + ], + ); } class RecoverByNewDeviceKeyInput extends StatelessWidget { - const RecoverByNewDeviceKeyInput({Key? key}) : super(key: key); + const RecoverByNewDeviceKeyInput({final super.key}); @override - Widget build(BuildContext context) { - ServerInstallationCubit appConfig = context.watch(); + Widget build(final BuildContext context) { + final ServerInstallationCubit appConfig = + context.watch(); return BlocProvider( - create: (BuildContext context) => RecoveryDeviceFormCubit( + create: (final BuildContext context) => RecoveryDeviceFormCubit( appConfig, FieldCubitFactory(context), ServerRecoveryMethods.newDeviceKey, ), child: BlocListener( - listener: (BuildContext context, ServerInstallationState state) { + listener: + (final BuildContext context, final ServerInstallationState state) { if (state is ServerInstallationRecovery && state.currentStep != RecoveryStep.newDeviceKey) { Navigator.of(context).pop(); } }, child: Builder( - builder: (BuildContext context) { - FormCubitState formCubitState = context.watch().state; + builder: (final BuildContext context) { + final FormCubitState formCubitState = + context.watch().state; return BrandHeroScreen( heroTitle: 'recovering.recovery_main_header'.tr(), diff --git a/lib/ui/pages/setup/recovering/recover_by_old_token.dart b/lib/ui/pages/setup/recovering/recover_by_old_token.dart index fa96c04e..6d3831f9 100644 --- a/lib/ui/pages/setup/recovering/recover_by_old_token.dart +++ b/lib/ui/pages/setup/recovering/recover_by_old_token.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:selfprivacy/logic/cubit/forms/setup/recovering/recovery_device_form_cubit.dart'; @@ -12,47 +10,51 @@ import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart class RecoverByOldTokenInstruction extends StatelessWidget { @override - const RecoverByOldTokenInstruction( - {super.key, required this.instructionFilename,}); + const RecoverByOldTokenInstruction({ + required this.instructionFilename, + final super.key, + }); @override - Widget build(final BuildContext context) => BlocListener( - listener: (final context, final state) { - if (state is ServerInstallationRecovery && - state.currentStep != RecoveryStep.selecting) { - Navigator.of(context).pop(); - } - }, - child: BrandHeroScreen( - heroTitle: 'recovering.recovery_main_header'.tr(), - hasBackButton: true, - hasFlashButton: false, - onBackButtonPressed: () => - context.read().revertRecoveryStep(), - children: [ - BrandMarkdown( - fileName: instructionFilename, - ), - const SizedBox(height: 16), - FilledButton( - title: 'recovering.method_device_button'.tr(), - onPressed: () => context - .read() - .selectRecoveryMethod(ServerRecoveryMethods.oldToken), - ) - ], - ), - ); + Widget build(final BuildContext context) => + BlocListener( + listener: (final context, final state) { + if (state is ServerInstallationRecovery && + state.currentStep != RecoveryStep.selecting) { + Navigator.of(context).pop(); + } + }, + child: BrandHeroScreen( + heroTitle: 'recovering.recovery_main_header'.tr(), + hasBackButton: true, + hasFlashButton: false, + onBackButtonPressed: () => + context.read().revertRecoveryStep(), + children: [ + BrandMarkdown( + fileName: instructionFilename, + ), + const SizedBox(height: 16), + FilledButton( + title: 'recovering.method_device_button'.tr(), + onPressed: () => context + .read() + .selectRecoveryMethod(ServerRecoveryMethods.oldToken), + ) + ], + ), + ); final String instructionFilename; } class RecoverByOldToken extends StatelessWidget { - const RecoverByOldToken({super.key}); + const RecoverByOldToken({final super.key}); @override Widget build(final BuildContext context) { - final ServerInstallationCubit appConfig = context.watch(); + final ServerInstallationCubit appConfig = + context.watch(); return BlocProvider( create: (final context) => RecoveryDeviceFormCubit( @@ -62,7 +64,8 @@ class RecoverByOldToken extends StatelessWidget { ), child: Builder( builder: (final context) { - final FormCubitState formCubitState = context.watch().state; + final FormCubitState formCubitState = + context.watch().state; return BrandHeroScreen( heroTitle: 'recovering.recovery_main_header'.tr(), diff --git a/lib/ui/pages/setup/recovering/recover_by_recovery_key.dart b/lib/ui/pages/setup/recovering/recover_by_recovery_key.dart index 51a930a8..a6cc44cd 100644 --- a/lib/ui/pages/setup/recovering/recover_by_recovery_key.dart +++ b/lib/ui/pages/setup/recovering/recover_by_recovery_key.dart @@ -8,11 +8,12 @@ import 'package:selfprivacy/ui/components/brand_button/filled_button.dart'; import 'package:selfprivacy/ui/components/brand_hero_screen/brand_hero_screen.dart'; class RecoverByRecoveryKey extends StatelessWidget { - const RecoverByRecoveryKey({final Key? key}) : super(key: key); + const RecoverByRecoveryKey({final super.key}); @override Widget build(final BuildContext context) { - ServerInstallationCubit appConfig = context.watch(); + final ServerInstallationCubit appConfig = + context.watch(); return BlocProvider( create: (final context) => RecoveryDeviceFormCubit( @@ -22,7 +23,8 @@ class RecoverByRecoveryKey extends StatelessWidget { ), child: Builder( builder: (final context) { - FormCubitState formCubitState = context.watch().state; + final FormCubitState formCubitState = + context.watch().state; return BrandHeroScreen( heroTitle: 'recovering.recovery_main_header'.tr(), diff --git a/lib/ui/pages/setup/recovering/recovery_confirm_backblaze.dart b/lib/ui/pages/setup/recovering/recovery_confirm_backblaze.dart index d14955d7..2513b054 100644 --- a/lib/ui/pages/setup/recovering/recovery_confirm_backblaze.dart +++ b/lib/ui/pages/setup/recovering/recovery_confirm_backblaze.dart @@ -14,48 +14,53 @@ class RecoveryConfirmBackblaze extends StatelessWidget { @override Widget build(final BuildContext context) { - ServerInstallationCubit appConfig = context.watch(); + final ServerInstallationCubit appConfig = + context.watch(); return BlocProvider( create: (final BuildContext context) => BackblazeFormCubit(appConfig), - child: Builder(builder: (final BuildContext context) { - FormCubitState formCubitState = context.watch().state; + child: Builder( + builder: (final BuildContext context) { + final FormCubitState formCubitState = + context.watch().state; - return BrandHeroScreen( - heroTitle: 'recovering.confirm_backblaze'.tr(), - heroSubtitle: 'recovering.confirm_backblaze_description'.tr(), - hasBackButton: true, - hasFlashButton: false, - children: [ - CubitFormTextField( - formFieldCubit: context.read().keyId, - decoration: const InputDecoration( - border: OutlineInputBorder(), - labelText: 'KeyID', + return BrandHeroScreen( + heroTitle: 'recovering.confirm_backblaze'.tr(), + heroSubtitle: 'recovering.confirm_backblaze_description'.tr(), + hasBackButton: true, + hasFlashButton: false, + children: [ + CubitFormTextField( + formFieldCubit: context.read().keyId, + decoration: const InputDecoration( + border: OutlineInputBorder(), + labelText: 'KeyID', + ), ), - ), - const SizedBox(height: 16), - CubitFormTextField( - formFieldCubit: context.read().applicationKey, - decoration: const InputDecoration( - border: OutlineInputBorder(), - labelText: 'Master Application Key', + const SizedBox(height: 16), + CubitFormTextField( + formFieldCubit: + context.read().applicationKey, + decoration: const InputDecoration( + border: OutlineInputBorder(), + labelText: 'Master Application Key', + ), ), - ), - const SizedBox(height: 16), - BrandButton.rised( - onPressed: formCubitState.isSubmitting - ? null - : () => context.read().trySubmit(), - text: 'basis.connect'.tr(), - ), - const SizedBox(height: 16), - BrandButton.text( - onPressed: () => showModalBottomSheet( - context: context, - isScrollControlled: true, - backgroundColor: Colors.transparent, - builder: (final BuildContext context) => const BrandBottomSheet( + const SizedBox(height: 16), + BrandButton.rised( + onPressed: formCubitState.isSubmitting + ? null + : () => context.read().trySubmit(), + text: 'basis.connect'.tr(), + ), + const SizedBox(height: 16), + BrandButton.text( + onPressed: () => showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: Colors.transparent, + builder: (final BuildContext context) => + const BrandBottomSheet( isExpended: true, child: Padding( padding: paddingH15V0, @@ -64,12 +69,13 @@ class RecoveryConfirmBackblaze extends StatelessWidget { ), ), ), + ), + title: 'initializing.how'.tr(), ), - title: 'initializing.how'.tr(), - ), - ], - ); - },), + ], + ); + }, + ), ); } } diff --git a/lib/ui/pages/setup/recovering/recovery_confirm_cloudflare.dart b/lib/ui/pages/setup/recovering/recovery_confirm_cloudflare.dart index 1de939b1..b64ca6ae 100644 --- a/lib/ui/pages/setup/recovering/recovery_confirm_cloudflare.dart +++ b/lib/ui/pages/setup/recovering/recovery_confirm_cloudflare.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:cubit_form/cubit_form.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; @@ -12,46 +10,50 @@ import 'package:selfprivacy/ui/components/brand_hero_screen/brand_hero_screen.da import 'package:selfprivacy/ui/components/brand_md/brand_md.dart'; class RecoveryConfirmCloudflare extends StatelessWidget { - const RecoveryConfirmCloudflare({super.key}); + const RecoveryConfirmCloudflare({final super.key}); @override Widget build(final BuildContext context) { - final ServerInstallationCubit appConfig = context.watch(); + final ServerInstallationCubit appConfig = + context.watch(); return BlocProvider( create: (final BuildContext context) => CloudFlareFormCubit(appConfig), - child: Builder(builder: (final BuildContext context) { - final FormCubitState formCubitState = context.watch().state; + child: Builder( + builder: (final BuildContext context) { + final FormCubitState formCubitState = + context.watch().state; - return BrandHeroScreen( - heroTitle: 'recovering.confirm_cloudflare'.tr(), - heroSubtitle: 'recovering.confirm_cloudflare_description'.tr(args: [ - appConfig.state.serverDomain?.domainName ?? 'your domain' - ],), - hasBackButton: true, - hasFlashButton: false, - children: [ - CubitFormTextField( - formFieldCubit: context.read().apiKey, - decoration: InputDecoration( - border: const OutlineInputBorder(), - labelText: 'initializing.5'.tr(), + return BrandHeroScreen( + heroTitle: 'recovering.confirm_cloudflare'.tr(), + heroSubtitle: 'recovering.confirm_cloudflare_description'.tr( + args: [appConfig.state.serverDomain?.domainName ?? 'your domain'], + ), + hasBackButton: true, + hasFlashButton: false, + children: [ + CubitFormTextField( + formFieldCubit: context.read().apiKey, + decoration: InputDecoration( + border: const OutlineInputBorder(), + labelText: 'initializing.5'.tr(), + ), ), - ), - const SizedBox(height: 16), - BrandButton.rised( - onPressed: formCubitState.isSubmitting - ? null - : () => context.read().trySubmit(), - text: 'basis.connect'.tr(), - ), - const SizedBox(height: 16), - BrandButton.text( - onPressed: () => showModalBottomSheet( - context: context, - isScrollControlled: true, - backgroundColor: Colors.transparent, - builder: (final BuildContext context) => const BrandBottomSheet( + const SizedBox(height: 16), + BrandButton.rised( + onPressed: formCubitState.isSubmitting + ? null + : () => context.read().trySubmit(), + text: 'basis.connect'.tr(), + ), + const SizedBox(height: 16), + BrandButton.text( + onPressed: () => showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: Colors.transparent, + builder: (final BuildContext context) => + const BrandBottomSheet( isExpended: true, child: Padding( padding: paddingH15V0, @@ -60,12 +62,13 @@ class RecoveryConfirmCloudflare extends StatelessWidget { ), ), ), + ), + title: 'initializing.how'.tr(), ), - title: 'initializing.how'.tr(), - ), - ], - ); - },), + ], + ); + }, + ), ); } } diff --git a/lib/ui/pages/setup/recovering/recovery_confirm_server.dart b/lib/ui/pages/setup/recovering/recovery_confirm_server.dart index fd7658ab..110425ef 100644 --- a/lib/ui/pages/setup/recovering/recovery_confirm_server.dart +++ b/lib/ui/pages/setup/recovering/recovery_confirm_server.dart @@ -8,7 +8,7 @@ import 'package:selfprivacy/ui/components/brand_cards/brand_cards.dart'; import 'package:selfprivacy/ui/components/brand_hero_screen/brand_hero_screen.dart'; class RecoveryConfirmServer extends StatefulWidget { - const RecoveryConfirmServer({super.key}); + const RecoveryConfirmServer({final super.key}); @override State createState() => _RecoveryConfirmServerState(); @@ -17,252 +17,252 @@ class RecoveryConfirmServer extends StatefulWidget { class _RecoveryConfirmServerState extends State { bool _isExtended = false; - bool _isServerFound(List servers) { - return servers - .where((server) => server.isIpValid && server.isReverseDnsValid) - .length == - 1; - } + bool _isServerFound(final List servers) => + servers + .where((final server) => server.isIpValid && server.isReverseDnsValid) + .length == + 1; ServerBasicInfoWithValidators _firstValidServer( - List servers) { - return servers - .where((server) => server.isIpValid && server.isReverseDnsValid) - .first; - } + final List servers, + ) => + servers + .where((final server) => server.isIpValid && server.isReverseDnsValid) + .first; @override - Widget build(BuildContext context) { - return BrandHeroScreen( - heroTitle: _isExtended - ? 'recovering.choose_server'.tr() - : 'recovering.confirm_server'.tr(), - heroSubtitle: _isExtended - ? 'recovering.choose_server_description'.tr() - : 'recovering.confirm_server_description'.tr(), - hasBackButton: true, - hasFlashButton: false, - children: [ - FutureBuilder>( - future: context - .read() - .getServersOnHetznerAccount(), - builder: (context, snapshot) { - if (snapshot.hasData) { - final servers = snapshot.data; - return Column( - children: [ - if (servers != null && servers.isNotEmpty) - Column( - children: [ - if (servers.length == 1 || - (!_isExtended && _isServerFound(servers))) - confirmServer(context, _firstValidServer(servers), - servers.length > 1), - if (servers.length > 1 && - (_isExtended || !_isServerFound(servers))) - chooseServer(context, servers), - ], - ), - if (servers?.isEmpty ?? true) - Center( - child: Text( - 'recovering.no_servers'.tr(), - style: Theme.of(context).textTheme.headline6, + Widget build(final BuildContext context) => BrandHeroScreen( + heroTitle: _isExtended + ? 'recovering.choose_server'.tr() + : 'recovering.confirm_server'.tr(), + heroSubtitle: _isExtended + ? 'recovering.choose_server_description'.tr() + : 'recovering.confirm_server_description'.tr(), + hasBackButton: true, + hasFlashButton: false, + children: [ + FutureBuilder>( + future: context + .read() + .getServersOnHetznerAccount(), + builder: (final context, final snapshot) { + if (snapshot.hasData) { + final servers = snapshot.data; + return Column( + children: [ + if (servers != null && servers.isNotEmpty) + Column( + children: [ + if (servers.length == 1 || + (!_isExtended && _isServerFound(servers))) + confirmServer( + context, + _firstValidServer(servers), + servers.length > 1, + ), + if (servers.length > 1 && + (_isExtended || !_isServerFound(servers))) + chooseServer(context, servers), + ], ), - ), - ], - ); - } else { - return const Center( - child: CircularProgressIndicator(), - ); - } - }, - ) - ], - ); - } + if (servers?.isEmpty ?? true) + Center( + child: Text( + 'recovering.no_servers'.tr(), + style: Theme.of(context).textTheme.headline6, + ), + ), + ], + ); + } else { + return const Center( + child: CircularProgressIndicator(), + ); + } + }, + ) + ], + ); Widget confirmServer( - BuildContext context, - ServerBasicInfoWithValidators server, - bool showMoreServersButton, - ) { - return Column( - children: [ - serverCard( - context: context, - server: server, - ), - const SizedBox(height: 16), - FilledButton( - title: 'recovering.confirm_server_accept'.tr(), - onPressed: () => _showConfirmationDialog(context, server), - ), - const SizedBox(height: 16), - if (showMoreServersButton) - BrandButton.text( - title: 'recovering.confirm_server_decline'.tr(), - onPressed: () => setState(() => _isExtended = true), + final BuildContext context, + final ServerBasicInfoWithValidators server, + final bool showMoreServersButton, + ) => + Column( + children: [ + serverCard( + context: context, + server: server, ), - ], - ); - } + const SizedBox(height: 16), + FilledButton( + title: 'recovering.confirm_server_accept'.tr(), + onPressed: () => _showConfirmationDialog(context, server), + ), + const SizedBox(height: 16), + if (showMoreServersButton) + BrandButton.text( + title: 'recovering.confirm_server_decline'.tr(), + onPressed: () => setState(() => _isExtended = true), + ), + ], + ); Widget chooseServer( - BuildContext context, List servers) { - return Column( - children: [ - for (final server in servers) - Padding( - padding: const EdgeInsets.symmetric(vertical: 8.0), - child: serverCard( - context: context, - server: server, - onTap: () => _showConfirmationDialog(context, server), - ), - ), - ], - ); - } - - Widget serverCard( - {required BuildContext context, - required ServerBasicInfoWithValidators server, - VoidCallback? onTap}) { - return BrandCards.filled( - child: ListTile( - contentPadding: - const EdgeInsets.symmetric(horizontal: 16, vertical: 16), - onTap: onTap, - title: Text( - server.name, - style: Theme.of(context).textTheme.titleMedium!.copyWith( - color: Theme.of(context).colorScheme.onSurface, + final BuildContext context, + final List servers, + ) => + Column( + children: [ + for (final server in servers) + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: serverCard( + context: context, + server: server, + onTap: () => _showConfirmationDialog(context, server), ), - ), - leading: Icon( - Icons.dns_outlined, - color: Theme.of(context).colorScheme.onSurface, - ), - subtitle: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Icon( - server.isReverseDnsValid ? Icons.check : Icons.close, - color: Theme.of(context).colorScheme.onSurface, - ), - const SizedBox(width: 8), - Expanded( - child: Text( - 'rDNS: ${server.reverseDns}', - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: Theme.of(context).colorScheme.onSurface, - ), - ), - ), - ], ), - Row( - children: [ - Icon( - server.isIpValid ? Icons.check : Icons.close, + ], + ); + + Widget serverCard({ + required final BuildContext context, + required final ServerBasicInfoWithValidators server, + final VoidCallback? onTap, + }) => + BrandCards.filled( + child: ListTile( + contentPadding: + const EdgeInsets.symmetric(horizontal: 16, vertical: 16), + onTap: onTap, + title: Text( + server.name, + style: Theme.of(context).textTheme.titleMedium!.copyWith( color: Theme.of(context).colorScheme.onSurface, ), - const SizedBox(width: 8), - Expanded( - child: Text( - 'IP: ${server.ip}', - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: Theme.of(context).colorScheme.onSurface, - ), + ), + leading: Icon( + Icons.dns_outlined, + color: Theme.of(context).colorScheme.onSurface, + ), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + server.isReverseDnsValid ? Icons.check : Icons.close, + color: Theme.of(context).colorScheme.onSurface, ), - ), - ], + const SizedBox(width: 8), + Expanded( + child: Text( + 'rDNS: ${server.reverseDns}', + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + color: Theme.of(context).colorScheme.onSurface, + ), + ), + ), + ], + ), + Row( + children: [ + Icon( + server.isIpValid ? Icons.check : Icons.close, + color: Theme.of(context).colorScheme.onSurface, + ), + const SizedBox(width: 8), + Expanded( + child: Text( + 'IP: ${server.ip}', + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + color: Theme.of(context).colorScheme.onSurface, + ), + ), + ), + ], + ), + ], + ), + ), + ); + + Future _showConfirmationDialog( + final BuildContext context, + final ServerBasicInfoWithValidators server, + ) => + showDialog( + context: context, + builder: (final context) => AlertDialog( + title: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Icon(Icons.warning_amber_outlined), + const SizedBox(height: 16), + Text( + 'recovering.modal_confirmation_title'.tr(), + style: Theme.of(context).textTheme.headlineSmall, + textAlign: TextAlign.center, + ), + ], + ), + content: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'recovering.modal_confirmation_description'.tr(), + style: Theme.of(context).textTheme.bodyMedium, + ), + const SizedBox(height: 12), + const Divider(), + const SizedBox(height: 12), + Text( + server.name, + style: Theme.of(context).textTheme.titleMedium, + textAlign: TextAlign.start, + ), + const SizedBox(height: 8), + IsValidStringDisplay( + isValid: server.isReverseDnsValid, + textIfValid: 'recovering.modal_confirmation_dns_valid'.tr(), + textIfInvalid: 'recovering.modal_confirmation_dns_invalid'.tr(), + ), + const SizedBox(height: 8), + IsValidStringDisplay( + isValid: server.isIpValid, + textIfValid: 'recovering.modal_confirmation_ip_valid'.tr(), + textIfInvalid: 'recovering.modal_confirmation_ip_invalid'.tr(), + ), + ], + ), + actions: [ + TextButton( + child: Text('modals.no'.tr()), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + TextButton( + child: Text('modals.yes'.tr()), + onPressed: () { + context.read().setServerId(server); + Navigator.of(context).pop(); + }, ), ], ), - ), - ); - } - - _showConfirmationDialog( - BuildContext context, ServerBasicInfoWithValidators server) => - showDialog( - context: context, - builder: (context) { - return AlertDialog( - title: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const Icon(Icons.warning_amber_outlined), - const SizedBox(height: 16), - Text( - 'recovering.modal_confirmation_title'.tr(), - style: Theme.of(context).textTheme.headlineSmall, - textAlign: TextAlign.center, - ), - ], - ), - content: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text('recovering.modal_confirmation_description'.tr(), - style: Theme.of(context).textTheme.bodyMedium), - const SizedBox(height: 12), - const Divider(), - const SizedBox(height: 12), - Text( - server.name, - style: Theme.of(context).textTheme.titleMedium, - textAlign: TextAlign.start, - ), - const SizedBox(height: 8), - IsValidStringDisplay( - isValid: server.isReverseDnsValid, - textIfValid: 'recovering.modal_confirmation_dns_valid'.tr(), - textIfInvalid: - 'recovering.modal_confirmation_dns_invalid'.tr(), - ), - const SizedBox(height: 8), - IsValidStringDisplay( - isValid: server.isIpValid, - textIfValid: 'recovering.modal_confirmation_ip_valid'.tr(), - textIfInvalid: - 'recovering.modal_confirmation_ip_invalid'.tr(), - ), - ], - ), - actions: [ - TextButton( - child: Text('modals.no'.tr()), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - TextButton( - child: Text('modals.yes'.tr()), - onPressed: () { - context.read().setServerId(server); - Navigator.of(context).pop(); - }, - ), - ], - ); - }, ); } class IsValidStringDisplay extends StatelessWidget { const IsValidStringDisplay({ - super.key, required this.isValid, required this.textIfValid, required this.textIfInvalid, + final super.key, }); final bool isValid; @@ -270,15 +270,15 @@ class IsValidStringDisplay extends StatelessWidget { final String textIfInvalid; @override - Widget build(BuildContext context) { - return Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - isValid - ? Icon(Icons.check, color: Theme.of(context).colorScheme.onSurface) - : Icon(Icons.close, color: Theme.of(context).colorScheme.error), - const SizedBox(width: 8), - Expanded( + Widget build(final BuildContext context) => Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + if (isValid) + Icon(Icons.check, color: Theme.of(context).colorScheme.onSurface) + else + Icon(Icons.close, color: Theme.of(context).colorScheme.error), + const SizedBox(width: 8), + Expanded( child: isValid ? Text( textIfValid, @@ -291,8 +291,8 @@ class IsValidStringDisplay extends StatelessWidget { style: Theme.of(context).textTheme.bodyMedium!.copyWith( color: Theme.of(context).colorScheme.error, ), - )), - ], - ); - } + ), + ), + ], + ); } diff --git a/lib/ui/pages/setup/recovering/recovery_hentzner_connected.dart b/lib/ui/pages/setup/recovering/recovery_hentzner_connected.dart index 6973ae2d..29506e8b 100644 --- a/lib/ui/pages/setup/recovering/recovery_hentzner_connected.dart +++ b/lib/ui/pages/setup/recovering/recovery_hentzner_connected.dart @@ -11,23 +11,25 @@ import 'package:selfprivacy/logic/cubit/server_installation/server_installation_ import 'package:selfprivacy/ui/components/brand_md/brand_md.dart'; class RecoveryHetznerConnected extends StatelessWidget { - const RecoveryHetznerConnected({final Key? key}) : super(key: key); + const RecoveryHetznerConnected({final super.key}); @override Widget build(final BuildContext context) { - ServerInstallationCubit appConfig = context.watch(); + final ServerInstallationCubit appConfig = + context.watch(); return BlocProvider( create: (final BuildContext context) => HetznerFormCubit(appConfig), child: Builder( builder: (final BuildContext context) { - FormCubitState formCubitState = context.watch().state; + final FormCubitState formCubitState = + context.watch().state; return BrandHeroScreen( heroTitle: 'recovering.hetzner_connected'.tr(), - heroSubtitle: 'recovering.hetzner_connected_description'.tr(args: [ - appConfig.state.serverDomain?.domainName ?? 'your domain' - ]), + heroSubtitle: 'recovering.hetzner_connected_description'.tr( + args: [appConfig.state.serverDomain?.domainName ?? 'your domain'], + ), hasBackButton: true, hasFlashButton: false, children: [ @@ -52,17 +54,16 @@ class RecoveryHetznerConnected extends StatelessWidget { context: context, isScrollControlled: true, backgroundColor: Colors.transparent, - builder: (final BuildContext context) { - return const BrandBottomSheet( - isExpended: true, - child: Padding( - padding: paddingH15V0, - child: BrandMarkdown( - fileName: 'how_hetzner', - ), + builder: (final BuildContext context) => + const BrandBottomSheet( + isExpended: true, + child: Padding( + padding: paddingH15V0, + child: BrandMarkdown( + fileName: 'how_hetzner', ), - ); - }, + ), + ), ), ), ], diff --git a/lib/ui/pages/setup/recovering/recovery_method_select.dart b/lib/ui/pages/setup/recovering/recovery_method_select.dart index a8e4860c..8abe3a27 100644 --- a/lib/ui/pages/setup/recovering/recovery_method_select.dart +++ b/lib/ui/pages/setup/recovering/recovery_method_select.dart @@ -9,119 +9,125 @@ import 'package:selfprivacy/ui/pages/setup/recovering/recover_by_old_token.dart' import 'package:selfprivacy/utils/route_transitions/basic.dart'; class RecoveryMethodSelect extends StatelessWidget { - const RecoveryMethodSelect({Key? key}) : super(key: key); + const RecoveryMethodSelect({final super.key}); @override - Widget build(BuildContext context) { - return BrandHeroScreen( - heroTitle: 'recovering.recovery_main_header'.tr(), - heroSubtitle: 'recovering.method_select_description'.tr(), - hasBackButton: true, - hasFlashButton: false, - children: [ - BrandCards.outlined( - child: ListTile( - title: Text( - 'recovering.method_select_other_device'.tr(), - style: Theme.of(context).textTheme.titleMedium, - ), - leading: const Icon(Icons.offline_share_outlined), - onTap: () => context - .read() - .selectRecoveryMethod(ServerRecoveryMethods.newDeviceKey), - ), - ), - const SizedBox(height: 16), - BrandCards.outlined( - child: ListTile( - title: Text( - 'recovering.method_select_recovery_key'.tr(), - style: Theme.of(context).textTheme.titleMedium, - ), - leading: const Icon(Icons.password_outlined), - onTap: () => context - .read() - .selectRecoveryMethod(ServerRecoveryMethods.recoveryKey), - ), - ), - const SizedBox(height: 16), - BrandButton.text( - title: 'recovering.method_select_nothing'.tr(), - onPressed: () => Navigator.of(context) - .push(materialRoute(const RecoveryFallbackMethodSelect())), - ) - ], - ); - } -} - -class RecoveryFallbackMethodSelect extends StatelessWidget { - const RecoveryFallbackMethodSelect({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return BlocListener( - listener: (context, state) { - if (state is ServerInstallationRecovery && - state.recoveryCapabilities == - ServerRecoveryCapabilities.loginTokens && - state.currentStep != RecoveryStep.selecting) { - Navigator.of(context).pop(); - } - }, - child: BrandHeroScreen( + Widget build(final BuildContext context) => BrandHeroScreen( heroTitle: 'recovering.recovery_main_header'.tr(), - heroSubtitle: 'recovering.fallback_select_description'.tr(), + heroSubtitle: 'recovering.method_select_description'.tr(), hasBackButton: true, hasFlashButton: false, children: [ BrandCards.outlined( child: ListTile( title: Text( - 'recovering.fallback_select_token_copy'.tr(), + 'recovering.method_select_other_device'.tr(), style: Theme.of(context).textTheme.titleMedium, ), - leading: const Icon(Icons.vpn_key), - onTap: () => Navigator.of(context) - .push(materialRoute(const RecoverByOldTokenInstruction( - instructionFilename: 'how_fallback_old', - ))), + leading: const Icon(Icons.offline_share_outlined), + onTap: () => context + .read() + .selectRecoveryMethod(ServerRecoveryMethods.newDeviceKey), ), ), const SizedBox(height: 16), BrandCards.outlined( child: ListTile( title: Text( - 'recovering.fallback_select_root_ssh'.tr(), + 'recovering.method_select_recovery_key'.tr(), style: Theme.of(context).textTheme.titleMedium, ), - leading: const Icon(Icons.terminal), - onTap: () => Navigator.of(context) - .push(materialRoute(const RecoverByOldTokenInstruction( - instructionFilename: 'how_fallback_ssh', - ))), + leading: const Icon(Icons.password_outlined), + onTap: () => context + .read() + .selectRecoveryMethod(ServerRecoveryMethods.recoveryKey), ), ), const SizedBox(height: 16), - BrandCards.outlined( - child: ListTile( - title: Text( - 'recovering.fallback_select_provider_console'.tr(), - style: Theme.of(context).textTheme.titleMedium, - ), - subtitle: Text( - 'recovering.fallback_select_provider_console_hint'.tr(), - style: Theme.of(context).textTheme.bodyMedium, - ), - leading: const Icon(Icons.web), - onTap: () => Navigator.of(context) - .push(materialRoute(const RecoverByOldTokenInstruction( - instructionFilename: 'how_fallback_terminal', - ))), - ), - ), + BrandButton.text( + title: 'recovering.method_select_nothing'.tr(), + onPressed: () => Navigator.of(context) + .push(materialRoute(const RecoveryFallbackMethodSelect())), + ) ], - ), - ); - } + ); +} + +class RecoveryFallbackMethodSelect extends StatelessWidget { + const RecoveryFallbackMethodSelect({final super.key}); + + @override + Widget build(final BuildContext context) => + BlocListener( + listener: (final context, final state) { + if (state is ServerInstallationRecovery && + state.recoveryCapabilities == + ServerRecoveryCapabilities.loginTokens && + state.currentStep != RecoveryStep.selecting) { + Navigator.of(context).pop(); + } + }, + child: BrandHeroScreen( + heroTitle: 'recovering.recovery_main_header'.tr(), + heroSubtitle: 'recovering.fallback_select_description'.tr(), + hasBackButton: true, + hasFlashButton: false, + children: [ + BrandCards.outlined( + child: ListTile( + title: Text( + 'recovering.fallback_select_token_copy'.tr(), + style: Theme.of(context).textTheme.titleMedium, + ), + leading: const Icon(Icons.vpn_key), + onTap: () => Navigator.of(context).push( + materialRoute( + const RecoverByOldTokenInstruction( + instructionFilename: 'how_fallback_old', + ), + ), + ), + ), + ), + const SizedBox(height: 16), + BrandCards.outlined( + child: ListTile( + title: Text( + 'recovering.fallback_select_root_ssh'.tr(), + style: Theme.of(context).textTheme.titleMedium, + ), + leading: const Icon(Icons.terminal), + onTap: () => Navigator.of(context).push( + materialRoute( + const RecoverByOldTokenInstruction( + instructionFilename: 'how_fallback_ssh', + ), + ), + ), + ), + ), + const SizedBox(height: 16), + BrandCards.outlined( + child: ListTile( + title: Text( + 'recovering.fallback_select_provider_console'.tr(), + style: Theme.of(context).textTheme.titleMedium, + ), + subtitle: Text( + 'recovering.fallback_select_provider_console_hint'.tr(), + style: Theme.of(context).textTheme.bodyMedium, + ), + leading: const Icon(Icons.web), + onTap: () => Navigator.of(context).push( + materialRoute( + const RecoverByOldTokenInstruction( + instructionFilename: 'how_fallback_terminal', + ), + ), + ), + ), + ), + ], + ), + ); } diff --git a/lib/ui/pages/setup/recovering/recovery_routing.dart b/lib/ui/pages/setup/recovering/recovery_routing.dart index 191ee1e6..e5a86074 100644 --- a/lib/ui/pages/setup/recovering/recovery_routing.dart +++ b/lib/ui/pages/setup/recovering/recovery_routing.dart @@ -16,11 +16,11 @@ import 'package:selfprivacy/ui/pages/setup/recovering/recovery_hentzner_connecte import 'package:selfprivacy/ui/pages/setup/recovering/recovery_method_select.dart'; class RecoveryRouting extends StatelessWidget { - const RecoveryRouting({Key? key}) : super(key: key); + const RecoveryRouting({final super.key}); @override - Widget build(BuildContext context) { - var serverInstallation = context.watch().state; + Widget build(final BuildContext context) { + final serverInstallation = context.watch().state; Widget currentPage = const SelectDomainToRecover(); @@ -61,9 +61,9 @@ class RecoveryRouting extends StatelessWidget { } return BlocListener( - listener: (context, state) { + listener: (final context, final state) { if (state is ServerInstallationFinished) { - Navigator.of(context).popUntil((route) => route.isFirst); + Navigator.of(context).popUntil((final route) => route.isFirst); } }, child: AnimatedSwitcher( @@ -75,21 +75,23 @@ class RecoveryRouting extends StatelessWidget { } class SelectDomainToRecover extends StatelessWidget { - const SelectDomainToRecover({Key? key}) : super(key: key); + const SelectDomainToRecover({final super.key}); @override - Widget build(BuildContext context) { - var serverInstallation = context.watch(); + Widget build(final BuildContext context) { + final serverInstallation = context.watch(); return BlocProvider( - create: (context) => RecoveryDomainFormCubit( - serverInstallation, FieldCubitFactory(context)), + create: (final context) => RecoveryDomainFormCubit( + serverInstallation, + FieldCubitFactory(context), + ), child: Builder( - builder: (context) { - var formCubitState = context.watch().state; + builder: (final context) { + final formCubitState = context.watch().state; return BlocListener( - listener: (context, state) { + listener: (final context, final state) { if (state is ServerInstallationRecovery) { if (state.currentStep == RecoveryStep.selecting) { if (state.recoveryCapabilities == @@ -108,7 +110,7 @@ class SelectDomainToRecover extends StatelessWidget { hasFlashButton: false, onBackButtonPressed: serverInstallation is ServerInstallationRecovery - ? () => serverInstallation.clearAppConfig() + ? serverInstallation.clearAppConfig : null, children: [ CubitFormTextField( diff --git a/lib/ui/pages/ssh_keys/new_ssh_key.dart b/lib/ui/pages/ssh_keys/new_ssh_key.dart index abeda0db..247590b7 100644 --- a/lib/ui/pages/ssh_keys/new_ssh_key.dart +++ b/lib/ui/pages/ssh_keys/new_ssh_key.dart @@ -1,76 +1,76 @@ part of 'ssh_keys.dart'; class _NewSshKey extends StatelessWidget { + const _NewSshKey(this.user); final User user; - const _NewSshKey(this.user); - @override - Widget build(BuildContext context) { - return BrandBottomSheet( - child: BlocProvider( - create: (context) { - var jobCubit = context.read(); - var jobState = jobCubit.state; - if (jobState is JobsStateWithJobs) { - var jobs = jobState.jobList; - for (var job in jobs) { - if (job is CreateSSHKeyJob && job.user.login == user.login) { - user.sshKeys.add(job.publicKey); + Widget build(final BuildContext context) => BrandBottomSheet( + child: BlocProvider( + create: (final context) { + final jobCubit = context.read(); + final jobState = jobCubit.state; + if (jobState is JobsStateWithJobs) { + final jobs = jobState.jobList; + for (final job in jobs) { + if (job is CreateSSHKeyJob && job.user.login == user.login) { + user.sshKeys.add(job.publicKey); + } } } - } - return SshFormCubit( - jobsCubit: jobCubit, - user: user, - ); - }, - child: Builder(builder: (context) { - var formCubitState = context.watch().state; + return SshFormCubit( + jobsCubit: jobCubit, + user: user, + ); + }, + child: Builder( + builder: (final context) { + final formCubitState = context.watch().state; - return BlocListener( - listener: (context, state) { - if (state.isSubmitted) { - Navigator.pop(context); - } - }, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - BrandHeader( - title: user.login, - ), - const SizedBox(width: 14), - Padding( - padding: paddingH15V0, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - IntrinsicHeight( - child: CubitFormTextField( - formFieldCubit: context.read().key, - decoration: InputDecoration( - labelText: 'ssh.input_label'.tr(), + return BlocListener( + listener: (final context, final state) { + if (state.isSubmitted) { + Navigator.pop(context); + } + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + BrandHeader( + title: user.login, + ), + const SizedBox(width: 14), + Padding( + padding: paddingH15V0, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + IntrinsicHeight( + child: CubitFormTextField( + formFieldCubit: context.read().key, + decoration: InputDecoration( + labelText: 'ssh.input_label'.tr(), + ), + ), ), - ), + const SizedBox(height: 30), + BrandButton.rised( + onPressed: formCubitState.isSubmitting + ? null + : () => + context.read().trySubmit(), + text: 'ssh.create'.tr(), + ), + const SizedBox(height: 30), + ], ), - const SizedBox(height: 30), - BrandButton.rised( - onPressed: formCubitState.isSubmitting - ? null - : () => context.read().trySubmit(), - text: 'ssh.create'.tr(), - ), - const SizedBox(height: 30), - ], - ), + ), + ], ), - ], - ), - ); - }), - ), - ); - } + ); + }, + ), + ), + ); } diff --git a/lib/ui/pages/ssh_keys/ssh_keys.dart b/lib/ui/pages/ssh_keys/ssh_keys.dart index 6fc5087b..4059ba63 100644 --- a/lib/ui/pages/ssh_keys/ssh_keys.dart +++ b/lib/ui/pages/ssh_keys/ssh_keys.dart @@ -8,136 +8,137 @@ import 'package:selfprivacy/ui/components/brand_cards/brand_cards.dart'; import 'package:selfprivacy/ui/components/brand_hero_screen/brand_hero_screen.dart'; import 'package:selfprivacy/ui/components/brand_icons/brand_icons.dart'; -import '../../../config/brand_colors.dart'; -import '../../../config/brand_theme.dart'; -import '../../../logic/cubit/jobs/jobs_cubit.dart'; -import '../../../logic/models/hive/user.dart'; -import '../../components/brand_button/brand_button.dart'; -import '../../components/brand_header/brand_header.dart'; +import 'package:selfprivacy/config/brand_colors.dart'; +import 'package:selfprivacy/config/brand_theme.dart'; +import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart'; +import 'package:selfprivacy/logic/models/hive/user.dart'; +import 'package:selfprivacy/ui/components/brand_button/brand_button.dart'; +import 'package:selfprivacy/ui/components/brand_header/brand_header.dart'; part 'new_ssh_key.dart'; // Get user object as a parameter class SshKeysPage extends StatefulWidget { + const SshKeysPage({required this.user, final super.key}); final User user; - const SshKeysPage({Key? key, required this.user}) : super(key: key); - @override State createState() => _SshKeysPageState(); } class _SshKeysPageState extends State { @override - Widget build(BuildContext context) { - return BrandHeroScreen( - heroTitle: 'ssh.title'.tr(), - heroSubtitle: widget.user.login, - heroIcon: BrandIcons.key, - children: [ - if (widget.user.login == 'root') - Column( - children: [ - // Show alert card if user is root - BrandCards.outlined( - child: ListTile( - leading: Icon( - Icons.warning_rounded, - color: Theme.of(context).colorScheme.error, + Widget build(final BuildContext context) => BrandHeroScreen( + heroTitle: 'ssh.title'.tr(), + heroSubtitle: widget.user.login, + heroIcon: BrandIcons.key, + children: [ + if (widget.user.login == 'root') + Column( + children: [ + // Show alert card if user is root + BrandCards.outlined( + child: ListTile( + leading: Icon( + Icons.warning_rounded, + color: Theme.of(context).colorScheme.error, + ), + title: Text('ssh.root.title'.tr()), + subtitle: Text('ssh.root.subtitle'.tr()), ), - title: Text('ssh.root.title'.tr()), - subtitle: Text('ssh.root.subtitle'.tr()), + ) + ], + ), + BrandCards.outlined( + child: Column( + children: [ + ListTile( + title: Text( + 'ssh.create'.tr(), + style: Theme.of(context).textTheme.headline6, + ), + leading: const Icon(Icons.add_circle_outline_rounded), + onTap: () { + showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: Colors.transparent, + builder: (final BuildContext context) => Padding( + padding: MediaQuery.of(context).viewInsets, + child: _NewSshKey(widget.user), + ), + ); + }, ), - ) - ], - ), - BrandCards.outlined( - child: Column( - children: [ - ListTile( - title: Text( - 'ssh.create'.tr(), - style: Theme.of(context).textTheme.headline6, - ), - leading: const Icon(Icons.add_circle_outline_rounded), - onTap: () { - showModalBottomSheet( - context: context, - isScrollControlled: true, - backgroundColor: Colors.transparent, - builder: (BuildContext context) { - return Padding( - padding: MediaQuery.of(context).viewInsets, - child: _NewSshKey(widget.user)); - }, - ); - }, - ), - const Divider(height: 0), - // show a list of ListTiles with ssh keys - // Clicking on one should delete it - Column( - children: widget.user.sshKeys.map((key) { - final publicKey = - key.split(' ').length > 1 ? key.split(' ')[1] : key; - final keyType = key.split(' ')[0]; - final keyName = key.split(' ').length > 2 - ? key.split(' ')[2] - : 'ssh.no_key_name'.tr(); - return ListTile( + const Divider(height: 0), + // show a list of ListTiles with ssh keys + // Clicking on one should delete it + Column( + children: widget.user.sshKeys.map((final String key) { + final publicKey = + key.split(' ').length > 1 ? key.split(' ')[1] : key; + final keyType = key.split(' ')[0]; + final keyName = key.split(' ').length > 2 + ? key.split(' ')[2] + : 'ssh.no_key_name'.tr(); + return ListTile( title: Text('$keyName ($keyType)'), // do not overflow text - subtitle: Text(publicKey, - maxLines: 1, overflow: TextOverflow.ellipsis), + subtitle: Text( + publicKey, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), onTap: () { showDialog( context: context, - builder: (context) { - return AlertDialog( - title: Text('ssh.delete'.tr()), - content: SingleChildScrollView( - child: ListBody( - children: [ - Text('ssh.delete_confirm_question'.tr()), - Text('$keyName ($keyType)'), - Text(publicKey), - ], - ), + builder: (final BuildContext context) => AlertDialog( + title: Text('ssh.delete'.tr()), + content: SingleChildScrollView( + child: ListBody( + children: [ + Text('ssh.delete_confirm_question'.tr()), + Text('$keyName ($keyType)'), + Text(publicKey), + ], ), - actions: [ - TextButton( - child: Text('basis.cancel'.tr()), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - TextButton( - child: Text( - 'basis.delete'.tr(), - style: const TextStyle( - color: BrandColors.red1, - ), + ), + actions: [ + TextButton( + child: Text('basis.cancel'.tr()), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + TextButton( + child: Text( + 'basis.delete'.tr(), + style: const TextStyle( + color: BrandColors.red1, ), - onPressed: () { - context.read().addJob( - DeleteSSHKeyJob( - user: widget.user, publicKey: key)); - Navigator.of(context) - ..pop() - ..pop(); - }, ), - ], - ); - }, + onPressed: () { + context.read().addJob( + DeleteSSHKeyJob( + user: widget.user, + publicKey: key, + ), + ); + Navigator.of(context) + ..pop() + ..pop(); + }, + ), + ], + ), ); - }); - }).toList(), - ) - ], + }, + ); + }).toList(), + ) + ], + ), ), - ), - ], - ); - } + ], + ); } diff --git a/lib/ui/pages/users/add_user_fab.dart b/lib/ui/pages/users/add_user_fab.dart index c527a60b..a78f056d 100644 --- a/lib/ui/pages/users/add_user_fab.dart +++ b/lib/ui/pages/users/add_user_fab.dart @@ -1,25 +1,22 @@ part of 'users.dart'; class AddUserFab extends StatelessWidget { - const AddUserFab({Key? key}) : super(key: key); + const AddUserFab({final super.key}); @override - Widget build(BuildContext context) { - return FloatingActionButton.small( - heroTag: 'new_user_fab', - onPressed: () { - showModalBottomSheet( - context: context, - isScrollControlled: true, - backgroundColor: Colors.transparent, - builder: (BuildContext context) { - return Padding( - padding: MediaQuery.of(context).viewInsets, - child: const NewUser()); - }, - ); - }, - child: const Icon(Icons.person_add_outlined), - ); - } + Widget build(final BuildContext context) => FloatingActionButton.small( + heroTag: 'new_user_fab', + onPressed: () { + showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: Colors.transparent, + builder: (final BuildContext context) => Padding( + padding: MediaQuery.of(context).viewInsets, + child: const NewUser(), + ), + ); + }, + child: const Icon(Icons.person_add_outlined), + ); } diff --git a/lib/ui/pages/users/empty.dart b/lib/ui/pages/users/empty.dart index 2e5c5906..847003d3 100644 --- a/lib/ui/pages/users/empty.dart +++ b/lib/ui/pages/users/empty.dart @@ -1,35 +1,33 @@ part of 'users.dart'; class _NoUsers extends StatelessWidget { - const _NoUsers({Key? key, required this.text}) : super(key: key); + const _NoUsers({required this.text}); final String text; @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Icon(BrandIcons.users, size: 50, color: BrandColors.grey7), - const SizedBox(height: 20), - BrandText.h2( - 'users.nobody_here'.tr(), - style: const TextStyle( - color: BrandColors.grey7, + Widget build(final BuildContext context) => Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Icon(BrandIcons.users, size: 50, color: BrandColors.grey7), + const SizedBox(height: 20), + BrandText.h2( + 'users.nobody_here'.tr(), + style: const TextStyle( + color: BrandColors.grey7, + ), ), - ), - const SizedBox(height: 10), - BrandText.medium( - text, - textAlign: TextAlign.center, - style: const TextStyle( - color: BrandColors.grey7, + const SizedBox(height: 10), + BrandText.medium( + text, + textAlign: TextAlign.center, + style: const TextStyle( + color: BrandColors.grey7, + ), ), - ), - ], - ), - ); - } + ], + ), + ); } diff --git a/lib/ui/pages/users/new_user.dart b/lib/ui/pages/users/new_user.dart index 4dd434b5..72cb6387 100644 --- a/lib/ui/pages/users/new_user.dart +++ b/lib/ui/pages/users/new_user.dart @@ -1,24 +1,25 @@ part of 'users.dart'; class NewUser extends StatelessWidget { - const NewUser({Key? key}) : super(key: key); + const NewUser({final super.key}); @override - Widget build(BuildContext context) { - var config = context.watch().state; + Widget build(final BuildContext context) { + final ServerInstallationState config = + context.watch().state; - var domainName = UiHelpers.getDomainName(config); + final String domainName = UiHelpers.getDomainName(config); return BrandBottomSheet( child: BlocProvider( - create: (context) { - var jobCubit = context.read(); - var jobState = jobCubit.state; - var users = []; + create: (final BuildContext context) { + final jobCubit = context.read(); + final jobState = jobCubit.state; + final users = []; users.addAll(context.read().state.users); if (jobState is JobsStateWithJobs) { - var jobs = jobState.jobList; - for (var job in jobs) { + final jobs = jobState.jobList; + for (final job in jobs) { if (job is CreateUserJob) { users.add(job.user); } @@ -29,73 +30,80 @@ class NewUser extends StatelessWidget { fieldFactory: FieldCubitFactory(context), ); }, - child: Builder(builder: (context) { - var formCubitState = context.watch().state; + child: Builder( + builder: (final BuildContext context) { + final FormCubitState formCubitState = + context.watch().state; - return BlocListener( - listener: (context, state) { - if (state.isSubmitted) { - Navigator.pop(context); - } - }, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - BrandHeader( - title: 'users.new_user'.tr(), - ), - const SizedBox(width: 14), - Padding( - padding: paddingH15V0, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - IntrinsicHeight( - child: CubitFormTextField( - formFieldCubit: context.read().login, - decoration: InputDecoration( - labelText: 'users.login'.tr(), - suffixText: '@$domainName', - ), - ), - ), - const SizedBox(height: 20), - CubitFormTextField( - formFieldCubit: context.read().password, - decoration: InputDecoration( - alignLabelWithHint: false, - labelText: 'basis.password'.tr(), - suffixIcon: Padding( - padding: const EdgeInsets.only(right: 8), - child: IconButton( - icon: Icon( - BrandIcons.refresh, - color: Theme.of(context).colorScheme.secondary, - ), - onPressed: - context.read().genNewPassword, + return BlocListener( + listener: + (final BuildContext context, final FormCubitState state) { + if (state.isSubmitted) { + Navigator.pop(context); + } + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + BrandHeader( + title: 'users.new_user'.tr(), + ), + const SizedBox(width: 14), + Padding( + padding: paddingH15V0, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + IntrinsicHeight( + child: CubitFormTextField( + formFieldCubit: context.read().login, + decoration: InputDecoration( + labelText: 'users.login'.tr(), + suffixText: '@$domainName', ), ), ), - ), - const SizedBox(height: 30), - BrandButton.rised( - onPressed: formCubitState.isSubmitting - ? null - : () => context.read().trySubmit(), - text: 'basis.create'.tr(), - ), - const SizedBox(height: 40), - Text('users.new_user_info_note'.tr()), - const SizedBox(height: 30), - ], + const SizedBox(height: 20), + CubitFormTextField( + formFieldCubit: + context.read().password, + decoration: InputDecoration( + alignLabelWithHint: false, + labelText: 'basis.password'.tr(), + suffixIcon: Padding( + padding: const EdgeInsets.only(right: 8), + child: IconButton( + icon: Icon( + BrandIcons.refresh, + color: + Theme.of(context).colorScheme.secondary, + ), + onPressed: context + .read() + .genNewPassword, + ), + ), + ), + ), + const SizedBox(height: 30), + BrandButton.rised( + onPressed: formCubitState.isSubmitting + ? null + : () => context.read().trySubmit(), + text: 'basis.create'.tr(), + ), + const SizedBox(height: 40), + Text('users.new_user_info_note'.tr()), + const SizedBox(height: 30), + ], + ), ), - ), - ], - ), - ); - }), + ], + ), + ); + }, + ), ), ); } diff --git a/lib/ui/pages/users/user.dart b/lib/ui/pages/users/user.dart index c59d53fc..69a2e5dc 100644 --- a/lib/ui/pages/users/user.dart +++ b/lib/ui/pages/users/user.dart @@ -1,49 +1,51 @@ part of 'users.dart'; class _User extends StatelessWidget { - const _User({Key? key, required this.user, required this.isRootUser}) - : super(key: key); + const _User({ + required this.user, + required this.isRootUser, + }); final User user; final bool isRootUser; @override - Widget build(BuildContext context) { - return InkWell( - onTap: () { - showBrandBottomSheet( - context: context, - builder: (BuildContext context) { - return _UserDetails(user: user, isRootUser: isRootUser); - }, - ); - }, - child: Container( - padding: paddingH15V0, - height: 48, - child: Row( - children: [ - Container( - width: 17, - height: 17, - decoration: BoxDecoration( - color: user.color, - shape: BoxShape.circle, + Widget build(final BuildContext context) => InkWell( + onTap: () { + showBrandBottomSheet( + context: context, + builder: (final BuildContext context) => + _UserDetails(user: user, isRootUser: isRootUser), + ); + }, + child: Container( + padding: paddingH15V0, + height: 48, + child: Row( + children: [ + Container( + width: 17, + height: 17, + decoration: BoxDecoration( + color: user.color, + shape: BoxShape.circle, + ), ), - ), - const SizedBox(width: 20), - Flexible( - child: isRootUser - ? BrandText.h4Underlined(user.login) - // cross out text if user not found on server - : BrandText.h4(user.login, - style: user.isFoundOnServer - ? null - : const TextStyle( - decoration: TextDecoration.lineThrough)), - ), - ], + const SizedBox(width: 20), + Flexible( + child: isRootUser + ? BrandText.h4Underlined(user.login) + // cross out text if user not found on server + : BrandText.h4( + user.login, + style: user.isFoundOnServer + ? null + : const TextStyle( + decoration: TextDecoration.lineThrough, + ), + ), + ), + ], + ), ), - ), - ); - } + ); } diff --git a/lib/ui/pages/users/user_details.dart b/lib/ui/pages/users/user_details.dart index bd7cbb2d..f7e212c8 100644 --- a/lib/ui/pages/users/user_details.dart +++ b/lib/ui/pages/users/user_details.dart @@ -2,7 +2,7 @@ part of 'users.dart'; class _UserDetails extends StatelessWidget { const _UserDetails({ - Key? key, + final Key? key, required this.user, required this.isRootUser, }) : super(key: key); @@ -10,10 +10,11 @@ class _UserDetails extends StatelessWidget { final User user; final bool isRootUser; @override - Widget build(BuildContext context) { - var config = context.watch().state; + Widget build(final BuildContext context) { + final ServerInstallationState config = + context.watch().state; - var domainName = UiHelpers.getDomainName(config); + final String domainName = UiHelpers.getDomainName(config); return BrandBottomSheet( isExpended: true, @@ -44,60 +45,54 @@ class _UserDetails extends StatelessWidget { shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.0), ), - onSelected: (PopupMenuItemType result) { + onSelected: (final PopupMenuItemType result) { switch (result) { case PopupMenuItemType.delete: showDialog( context: context, - builder: (context) { - return AlertDialog( - title: Text('basis.confirmation'.tr()), - content: SingleChildScrollView( - child: ListBody( - children: [ - Text('users.delete_confirm_question' - .tr()), - ], - ), - ), - actions: [ - TextButton( - child: Text('basis.cancel'.tr()), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - TextButton( - child: Text( - 'basis.delete'.tr(), - style: const TextStyle( - color: BrandColors.red1, - ), + builder: (final BuildContext context) => + AlertDialog( + title: Text('basis.confirmation'.tr()), + content: SingleChildScrollView( + child: ListBody( + children: [ + Text( + 'users.delete_confirm_question'.tr(), + ), + ], + ), + ), + actions: [ + TextButton( + child: Text('basis.cancel'.tr()), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + TextButton( + child: Text( + 'basis.delete'.tr(), + style: const TextStyle( + color: BrandColors.red1, ), - onPressed: () { - context.read().addJob( - DeleteUserJob(user: user)); - Navigator.of(context) - ..pop() - ..pop(); - }, ), - ], - ); - }, + onPressed: () { + context + .read() + .addJob(DeleteUserJob(user: user)); + Navigator.of(context) + ..pop() + ..pop(); + }, + ), + ], + ), ); break; } }, icon: const Icon(Icons.more_vert), - itemBuilder: (BuildContext context) => [ - // PopupMenuItem( - // value: PopupMenuItemType.reset, - // child: Container( - // padding: EdgeInsets.only(left: 5), - // child: Text('users.reset_password'.tr()), - // ), - // ), + itemBuilder: (final BuildContext context) => [ PopupMenuItem( value: PopupMenuItemType.delete, child: Container( @@ -114,18 +109,19 @@ class _UserDetails extends StatelessWidget { ), const Spacer(), Padding( - padding: const EdgeInsets.symmetric( - vertical: 20, - horizontal: 15, - ), - child: AutoSizeText( - user.login, - style: headline1Style, - softWrap: true, - minFontSize: 9, - maxLines: 3, - overflow: TextOverflow.ellipsis, - )), + padding: const EdgeInsets.symmetric( + vertical: 20, + horizontal: 15, + ), + child: AutoSizeText( + user.login, + style: headline1Style, + softWrap: true, + minFontSize: 9, + maxLines: 3, + overflow: TextOverflow.ellipsis, + ), + ), ], ), ), @@ -158,21 +154,25 @@ class _UserDetails extends StatelessWidget { const BrandDivider(), const SizedBox(height: 20), ListTile( - onTap: () { - Navigator.of(context) - .push(materialRoute(SshKeysPage(user: user))); - }, - title: Text('ssh.title'.tr()), - subtitle: user.sshKeys.isNotEmpty - ? Text('ssh.subtitle_with_keys' - .tr(args: [user.sshKeys.length.toString()])) - : Text('ssh.subtitle_without_keys'.tr()), - trailing: const Icon(BrandIcons.key)), + onTap: () { + Navigator.of(context) + .push(materialRoute(SshKeysPage(user: user))); + }, + title: Text('ssh.title'.tr()), + subtitle: user.sshKeys.isNotEmpty + ? Text( + 'ssh.subtitle_with_keys' + .tr(args: [user.sshKeys.length.toString()]), + ) + : Text('ssh.subtitle_without_keys'.tr()), + trailing: const Icon(BrandIcons.key), + ), const SizedBox(height: 20), ListTile( onTap: () { Share.share( - 'login: ${user.login}, password: ${user.password}'); + 'login: ${user.login}, password: ${user.password}', + ); }, title: Text( 'users.send_registration_data'.tr(), diff --git a/lib/ui/pages/users/users.dart b/lib/ui/pages/users/users.dart index 52bb430d..659453d1 100644 --- a/lib/ui/pages/users/users.dart +++ b/lib/ui/pages/users/users.dart @@ -24,7 +24,7 @@ import 'package:selfprivacy/ui/pages/ssh_keys/ssh_keys.dart'; import 'package:selfprivacy/utils/ui_helpers.dart'; import 'package:share_plus/share_plus.dart'; -import '../../../utils/route_transitions/basic.dart'; +import 'package:selfprivacy/utils/route_transitions/basic.dart'; part 'empty.dart'; part 'new_user.dart'; @@ -33,23 +33,19 @@ part 'user_details.dart'; part 'add_user_fab.dart'; class UsersPage extends StatelessWidget { - const UsersPage({Key? key}) : super(key: key); + const UsersPage({final super.key}); @override - Widget build(BuildContext context) { - // final usersCubitState = context.watch().state; - var isReady = context.watch().state + Widget build(final BuildContext context) { + final bool isReady = context.watch().state is ServerInstallationFinished; - // final primaryUser = usersCubitState.primaryUser; - // final users = [primaryUser, ...usersCubitState.users]; - // final isEmpty = users.isEmpty; Widget child; if (!isReady) { child = isNotReady(); } else { child = BlocBuilder( - builder: (context, state) { + builder: (final BuildContext context, final UsersState state) { print('Rebuild users page'); final primaryUser = state.primaryUser; final users = [primaryUser, ...state.users]; @@ -60,12 +56,11 @@ class UsersPage extends StatelessWidget { }, child: ListView.builder( itemCount: users.length, - itemBuilder: (BuildContext context, int index) { - return _User( - user: users[index], - isRootUser: index == 0, - ); - }, + itemBuilder: (final BuildContext context, final int index) => + _User( + user: users[index], + isRootUser: index == 0, + ), ), ); }, @@ -83,25 +78,23 @@ class UsersPage extends StatelessWidget { ); } - Widget isNotReady() { - return Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const Padding( - padding: EdgeInsets.symmetric(horizontal: 15), - child: NotReadyCard(), - ), - Expanded( - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 15), - child: Center( - child: _NoUsers( - text: 'users.not_ready'.tr(), + Widget isNotReady() => Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const Padding( + padding: EdgeInsets.symmetric(horizontal: 15), + child: NotReadyCard(), + ), + Expanded( + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 15), + child: Center( + child: _NoUsers( + text: 'users.not_ready'.tr(), + ), ), ), - ), - ) - ], - ); - } + ) + ], + ); } diff --git a/lib/utils/color_utils.dart b/lib/utils/color_utils.dart index ac0c63ba..9fcf7397 100644 --- a/lib/utils/color_utils.dart +++ b/lib/utils/color_utils.dart @@ -1,8 +1,9 @@ import 'package:flutter/material.dart'; -Color stringToColor(String string) { - var number = string.codeUnits.reduce((a, b) => a + b); - var index = number % colorPalette.length; +Color stringToColor(final String string) { + final int number = + string.codeUnits.reduce((final int a, final int b) => a + b); + final int index = number % colorPalette.length; return colorPalette[index]; } @@ -10,7 +11,7 @@ var originalColor = const Color(0xFFDBD8BD); var count = 40; var colorPalette = List.generate( count, - (index) => HSLColor.fromColor(originalColor) - .withHue((index) * 360.0 / count) + (final int index) => HSLColor.fromColor(originalColor) + .withHue(index * 360.0 / count) .toColor(), ); diff --git a/lib/utils/extensions/duration.dart b/lib/utils/extensions/duration.dart index aac00eb2..2c302fb8 100644 --- a/lib/utils/extensions/duration.dart +++ b/lib/utils/extensions/duration.dart @@ -1,35 +1,32 @@ // ignore_for_file: unnecessary_this extension DurationFormatter on Duration { - String toDayHourMinuteSecondFormat() { - return [ - this.inHours.remainder(24), - this.inMinutes.remainder(60), - this.inSeconds.remainder(60) - ].map((seg) => seg.toString().padLeft(2, '0')).join(':'); - } + String toDayHourMinuteSecondFormat() => [ + this.inHours.remainder(24), + this.inMinutes.remainder(60), + this.inSeconds.remainder(60) + ].map((final int seg) => seg.toString().padLeft(2, '0')).join(':'); String toDayHourMinuteFormat() { - var designator = this >= Duration.zero ? '+' : '-'; + final designator = this >= Duration.zero ? '+' : '-'; - var segments = [ + final Iterable segments = [ this.inHours.remainder(24).abs(), this.inMinutes.remainder(60).abs(), - ].map((seg) => seg.toString().padLeft(2, '0')); + ].map((final int seg) => seg.toString().padLeft(2, '0')); return '$designator${segments.first}:${segments.last}'; } - String toHoursMinutesSecondsFormat() { - // WAT: https://flutterigniter.com/how-to-format-duration/ - return this.toString().split('.').first.padLeft(8, '0'); - } +// WAT: https://flutterigniter.com/how-to-format-duration/ + String toHoursMinutesSecondsFormat() => + this.toString().split('.').first.padLeft(8, '0'); String toDayHourMinuteFormat2() { - var segments = [ + final Iterable segments = [ this.inHours.remainder(24), this.inMinutes.remainder(60), - ].map((seg) => seg.toString().padLeft(2, '0')); + ].map((final int seg) => seg.toString().padLeft(2, '0')); return '${segments.first} h ${segments.last} min'; } } diff --git a/lib/utils/extensions/elevation_extension.dart b/lib/utils/extensions/elevation_extension.dart index 4b1cbf3f..9c6bbc14 100644 --- a/lib/utils/extensions/elevation_extension.dart +++ b/lib/utils/extensions/elevation_extension.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - library elevation_extension; import 'package:flutter/material.dart'; @@ -15,16 +13,20 @@ extension ElevationExtension on BoxDecoration { final Gradient? gradient, final BlendMode? backgroundBlendMode, final BoxShape? shape, - }) => BoxDecoration( - color: color ?? this.color, - image: image ?? this.image, - border: border ?? this.border, - borderRadius: borderRadius ?? this.borderRadius, - boxShadow: this.boxShadow != null || boxShadow != null - ? [...this.boxShadow ?? [], ...boxShadow ?? []] - : null, - gradient: gradient ?? this.gradient, - backgroundBlendMode: backgroundBlendMode ?? this.backgroundBlendMode, - shape: shape ?? this.shape, - ); + }) => + BoxDecoration( + color: color ?? this.color, + image: image ?? this.image, + border: border ?? this.border, + borderRadius: borderRadius ?? this.borderRadius, + boxShadow: this.boxShadow != null || boxShadow != null + ? [ + ...this.boxShadow ?? [], + ...boxShadow ?? [] + ] + : null, + gradient: gradient ?? this.gradient, + backgroundBlendMode: backgroundBlendMode ?? this.backgroundBlendMode, + shape: shape ?? this.shape, + ); } diff --git a/lib/utils/password_generator.dart b/lib/utils/password_generator.dart index 70fd83a9..5acf3888 100644 --- a/lib/utils/password_generator.dart +++ b/lib/utils/password_generator.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'dart:math'; Random _rnd = Random(); @@ -20,10 +18,22 @@ class StringGenerators { final isStrict = false, }) { String chars = ''; - if (hasLowercaseLetters) chars += letters; - if (hasUppercaseLetters) chars += letters.toUpperCase(); - if (hasNumbers) chars += numbers; - if (hasSymbols) chars += symbols; + + if (hasLowercaseLetters) { + chars += letters; + } + + if (hasUppercaseLetters) { + chars += letters.toUpperCase(); + } + + if (hasNumbers) { + chars += numbers; + } + + if (hasSymbols) { + chars += symbols; + } assert(chars.isNotEmpty, 'chart empty'); @@ -55,14 +65,15 @@ class StringGenerators { return shuffledlist.join(); } - static String genString(final int length, final String chars) => String.fromCharCodes( - Iterable.generate( - length, - (final _) => chars.codeUnitAt( - _rnd.nextInt(chars.length), + static String genString(final int length, final String chars) => + String.fromCharCodes( + Iterable.generate( + length, + (final _) => chars.codeUnitAt( + _rnd.nextInt(chars.length), + ), ), - ), - ); + ); static StringGeneratorFunction userPassword = () => getRandomString( 8, diff --git a/lib/utils/route_transitions/basic.dart b/lib/utils/route_transitions/basic.dart index 5cd69cfd..a3148e1d 100644 --- a/lib/utils/route_transitions/basic.dart +++ b/lib/utils/route_transitions/basic.dart @@ -1,5 +1,3 @@ -// ignore_for_file: always_specify_types - import 'package:flutter/material.dart'; Route materialRoute(final Widget widget) => MaterialPageRoute( @@ -7,5 +5,10 @@ Route materialRoute(final Widget widget) => MaterialPageRoute( ); Route noAnimationRoute(final Widget widget) => PageRouteBuilder( - pageBuilder: (final BuildContext context, final Animation animation1, final Animation animation2) => widget, + pageBuilder: ( + final BuildContext context, + final Animation animation1, + final Animation animation2, + ) => + widget, ); diff --git a/pubspec.lock b/pubspec.lock index 965eb666..e3faf1b6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -363,6 +363,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.9.2" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" flutter_localizations: dependency: transitive description: flutter @@ -519,7 +526,7 @@ packages: source: hosted version: "3.1.3" intl: - dependency: transitive + dependency: "direct main" description: name: intl url: "https://pub.dartlang.org" @@ -560,6 +567,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "6.2.0" + lints: + dependency: transitive + description: + name: lints + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" local_auth: dependency: "direct main" description: