feat(initializing): Implement location selection step for initializing page

routes-refactor
NaiJi ✨ 2022-10-15 19:49:31 +00:00
parent b30e372322
commit fe820ef5be
5 changed files with 194 additions and 38 deletions

View File

@ -16,6 +16,8 @@ import 'package:selfprivacy/logic/models/hive/user.dart';
import 'package:selfprivacy/logic/models/server_basic_info.dart'; import 'package:selfprivacy/logic/models/server_basic_info.dart';
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_repository.dart'; import 'package:selfprivacy/logic/cubit/server_installation/server_installation_repository.dart';
import 'package:selfprivacy/logic/models/server_provider_location.dart';
import 'package:selfprivacy/logic/models/server_type.dart';
export 'package:provider/provider.dart'; export 'package:provider/provider.dart';
@ -93,6 +95,19 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
) )
.isApiTokenValid(providerToken); .isApiTokenValid(providerToken);
Future<List<ServerProviderLocation>> fetchAvailableLocations() async {
if (repository.serverProviderApiFactory == null) {
return [];
}
return repository.serverProviderApiFactory!
.getServerProvider(
settings: const ServerProviderApiSettings(region: 'fra1'),
)
.getAvailableLocations();
}
void setServerProviderKey(final String serverProviderKey) async { void setServerProviderKey(final String serverProviderKey) async {
await repository.saveServerProviderKey(serverProviderKey); await repository.saveServerProviderKey(serverProviderKey);

View File

@ -3,6 +3,7 @@ part of '../server_installation/server_installation_cubit.dart';
abstract class ServerInstallationState extends Equatable { abstract class ServerInstallationState extends Equatable {
const ServerInstallationState({ const ServerInstallationState({
required this.providerApiToken, required this.providerApiToken,
required this.serverType,
required this.cloudFlareKey, required this.cloudFlareKey,
required this.backblazeCredential, required this.backblazeCredential,
required this.serverDomain, required this.serverDomain,
@ -31,11 +32,13 @@ abstract class ServerInstallationState extends Equatable {
final ServerDomain? serverDomain; final ServerDomain? serverDomain;
final User? rootUser; final User? rootUser;
final ServerHostingDetails? serverDetails; final ServerHostingDetails? serverDetails;
final ServerType? serverType;
final bool isServerStarted; final bool isServerStarted;
final bool isServerResetedFirstTime; final bool isServerResetedFirstTime;
final bool isServerResetedSecondTime; final bool isServerResetedSecondTime;
bool get isServerProviderFilled => providerApiToken != null; bool get isServerProviderApiKeyFilled => providerApiToken != null;
bool get isServerTypeFilled => serverType != null;
bool get isDnsProviderFilled => cloudFlareKey != null; bool get isDnsProviderFilled => cloudFlareKey != null;
bool get isBackupsProviderFilled => backblazeCredential != null; bool get isBackupsProviderFilled => backblazeCredential != null;
bool get isDomainSelected => serverDomain != null; bool get isDomainSelected => serverDomain != null;
@ -58,7 +61,8 @@ abstract class ServerInstallationState extends Equatable {
List<bool?> get _fulfilementList { List<bool?> get _fulfilementList {
final List<bool> res = [ final List<bool> res = [
isServerProviderFilled, isServerProviderApiKeyFilled,
isServerTypeFilled,
isDnsProviderFilled, isDnsProviderFilled,
isBackupsProviderFilled, isBackupsProviderFilled,
isDomainSelected, isDomainSelected,
@ -76,11 +80,12 @@ abstract class ServerInstallationState extends Equatable {
class TimerState extends ServerInstallationNotFinished { class TimerState extends ServerInstallationNotFinished {
TimerState({ TimerState({
required this.dataState, required this.dataState,
required final super.isLoading, required super.isLoading,
this.timerStart, this.timerStart,
this.duration, this.duration,
}) : super( }) : super(
providerApiToken: dataState.providerApiToken, providerApiToken: dataState.providerApiToken,
serverType: dataState.serverType,
cloudFlareKey: dataState.cloudFlareKey, cloudFlareKey: dataState.cloudFlareKey,
backblazeCredential: dataState.backblazeCredential, backblazeCredential: dataState.backblazeCredential,
serverDomain: dataState.serverDomain, serverDomain: dataState.serverDomain,
@ -119,17 +124,18 @@ enum ServerSetupProgress {
class ServerInstallationNotFinished extends ServerInstallationState { class ServerInstallationNotFinished extends ServerInstallationState {
const ServerInstallationNotFinished({ const ServerInstallationNotFinished({
required final super.isServerStarted, required super.isServerStarted,
required final super.isServerResetedFirstTime, required super.isServerResetedFirstTime,
required final super.isServerResetedSecondTime, required super.isServerResetedSecondTime,
required final this.isLoading, required this.isLoading,
required this.dnsMatches, required this.dnsMatches,
final super.providerApiToken, super.providerApiToken,
final super.cloudFlareKey, super.serverType,
final super.backblazeCredential, super.cloudFlareKey,
final super.serverDomain, super.backblazeCredential,
final super.rootUser, super.serverDomain,
final super.serverDetails, super.rootUser,
super.serverDetails,
}); });
final bool isLoading; final bool isLoading;
final Map<String, bool>? dnsMatches; final Map<String, bool>? dnsMatches;
@ -137,6 +143,7 @@ class ServerInstallationNotFinished extends ServerInstallationState {
@override @override
List<Object?> get props => [ List<Object?> get props => [
providerApiToken, providerApiToken,
serverType,
cloudFlareKey, cloudFlareKey,
backblazeCredential, backblazeCredential,
serverDomain, serverDomain,
@ -150,6 +157,7 @@ class ServerInstallationNotFinished extends ServerInstallationState {
ServerInstallationNotFinished copyWith({ ServerInstallationNotFinished copyWith({
final String? providerApiToken, final String? providerApiToken,
final ServerType? serverType,
final String? cloudFlareKey, final String? cloudFlareKey,
final BackblazeCredential? backblazeCredential, final BackblazeCredential? backblazeCredential,
final ServerDomain? serverDomain, final ServerDomain? serverDomain,
@ -163,6 +171,7 @@ class ServerInstallationNotFinished extends ServerInstallationState {
}) => }) =>
ServerInstallationNotFinished( ServerInstallationNotFinished(
providerApiToken: providerApiToken ?? this.providerApiToken, providerApiToken: providerApiToken ?? this.providerApiToken,
serverType: serverType ?? this.serverType,
cloudFlareKey: cloudFlareKey ?? this.cloudFlareKey, cloudFlareKey: cloudFlareKey ?? this.cloudFlareKey,
backblazeCredential: backblazeCredential ?? this.backblazeCredential, backblazeCredential: backblazeCredential ?? this.backblazeCredential,
serverDomain: serverDomain ?? this.serverDomain, serverDomain: serverDomain ?? this.serverDomain,
@ -179,6 +188,7 @@ class ServerInstallationNotFinished extends ServerInstallationState {
ServerInstallationFinished finish() => ServerInstallationFinished( ServerInstallationFinished finish() => ServerInstallationFinished(
providerApiToken: providerApiToken!, providerApiToken: providerApiToken!,
serverType: serverType!,
cloudFlareKey: cloudFlareKey!, cloudFlareKey: cloudFlareKey!,
backblazeCredential: backblazeCredential!, backblazeCredential: backblazeCredential!,
serverDomain: serverDomain!, serverDomain: serverDomain!,
@ -209,20 +219,22 @@ class ServerInstallationEmpty extends ServerInstallationNotFinished {
class ServerInstallationFinished extends ServerInstallationState { class ServerInstallationFinished extends ServerInstallationState {
const ServerInstallationFinished({ const ServerInstallationFinished({
required final String super.providerApiToken, required String super.providerApiToken,
required final String super.cloudFlareKey, required ServerType super.serverType,
required final BackblazeCredential super.backblazeCredential, required String super.cloudFlareKey,
required final ServerDomain super.serverDomain, required BackblazeCredential super.backblazeCredential,
required final User super.rootUser, required ServerDomain super.serverDomain,
required final ServerHostingDetails super.serverDetails, required User super.rootUser,
required final super.isServerStarted, required ServerHostingDetails super.serverDetails,
required final super.isServerResetedFirstTime, required super.isServerStarted,
required final super.isServerResetedSecondTime, required super.isServerResetedFirstTime,
required super.isServerResetedSecondTime,
}); });
@override @override
List<Object?> get props => [ List<Object?> get props => [
providerApiToken, providerApiToken,
serverType,
cloudFlareKey, cloudFlareKey,
backblazeCredential, backblazeCredential,
serverDomain, serverDomain,
@ -260,12 +272,13 @@ class ServerInstallationRecovery extends ServerInstallationState {
const ServerInstallationRecovery({ const ServerInstallationRecovery({
required this.currentStep, required this.currentStep,
required this.recoveryCapabilities, required this.recoveryCapabilities,
final super.providerApiToken, super.providerApiToken,
final super.cloudFlareKey, super.serverType,
final super.backblazeCredential, super.cloudFlareKey,
final super.serverDomain, super.backblazeCredential,
final super.rootUser, super.serverDomain,
final super.serverDetails, super.rootUser,
super.serverDetails,
}) : super( }) : super(
isServerStarted: true, isServerStarted: true,
isServerResetedFirstTime: true, isServerResetedFirstTime: true,
@ -277,6 +290,7 @@ class ServerInstallationRecovery extends ServerInstallationState {
@override @override
List<Object?> get props => [ List<Object?> get props => [
providerApiToken, providerApiToken,
serverType,
cloudFlareKey, cloudFlareKey,
backblazeCredential, backblazeCredential,
serverDomain, serverDomain,
@ -289,6 +303,7 @@ class ServerInstallationRecovery extends ServerInstallationState {
ServerInstallationRecovery copyWith({ ServerInstallationRecovery copyWith({
final String? providerApiToken, final String? providerApiToken,
final ServerType? serverType,
final String? cloudFlareKey, final String? cloudFlareKey,
final BackblazeCredential? backblazeCredential, final BackblazeCredential? backblazeCredential,
final ServerDomain? serverDomain, final ServerDomain? serverDomain,
@ -299,6 +314,7 @@ class ServerInstallationRecovery extends ServerInstallationState {
}) => }) =>
ServerInstallationRecovery( ServerInstallationRecovery(
providerApiToken: providerApiToken ?? this.providerApiToken, providerApiToken: providerApiToken ?? this.providerApiToken,
serverType: serverType ?? this.serverType,
cloudFlareKey: cloudFlareKey ?? this.cloudFlareKey, cloudFlareKey: cloudFlareKey ?? this.cloudFlareKey,
backblazeCredential: backblazeCredential ?? this.backblazeCredential, backblazeCredential: backblazeCredential ?? this.backblazeCredential,
serverDomain: serverDomain ?? this.serverDomain, serverDomain: serverDomain ?? this.serverDomain,
@ -310,6 +326,7 @@ class ServerInstallationRecovery extends ServerInstallationState {
ServerInstallationFinished finish() => ServerInstallationFinished( ServerInstallationFinished finish() => ServerInstallationFinished(
providerApiToken: providerApiToken!, providerApiToken: providerApiToken!,
serverType: serverType!,
cloudFlareKey: cloudFlareKey!, cloudFlareKey: cloudFlareKey!,
backblazeCredential: backblazeCredential!, backblazeCredential: backblazeCredential!,
serverDomain: serverDomain!, serverDomain: serverDomain!,

View File

@ -7,7 +7,6 @@ import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart
import 'package:selfprivacy/logic/cubit/forms/setup/initializing/backblaze_form_cubit.dart'; import 'package:selfprivacy/logic/cubit/forms/setup/initializing/backblaze_form_cubit.dart';
import 'package:selfprivacy/logic/cubit/forms/setup/initializing/dns_provider_form_cubit.dart'; import 'package:selfprivacy/logic/cubit/forms/setup/initializing/dns_provider_form_cubit.dart';
import 'package:selfprivacy/logic/cubit/forms/setup/initializing/domain_setup_cubit.dart'; import 'package:selfprivacy/logic/cubit/forms/setup/initializing/domain_setup_cubit.dart';
import 'package:selfprivacy/logic/cubit/forms/setup/initializing/provider_form_cubit.dart';
import 'package:selfprivacy/logic/cubit/forms/setup/initializing/root_user_form_cubit.dart'; import 'package:selfprivacy/logic/cubit/forms/setup/initializing/root_user_form_cubit.dart';
import 'package:selfprivacy/ui/components/brand_bottom_sheet/brand_bottom_sheet.dart'; import 'package:selfprivacy/ui/components/brand_bottom_sheet/brand_bottom_sheet.dart';
import 'package:selfprivacy/ui/components/brand_button/brand_button.dart'; import 'package:selfprivacy/ui/components/brand_button/brand_button.dart';
@ -17,13 +16,14 @@ import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
import 'package:selfprivacy/ui/components/brand_timer/brand_timer.dart'; import 'package:selfprivacy/ui/components/brand_timer/brand_timer.dart';
import 'package:selfprivacy/ui/components/progress_bar/progress_bar.dart'; import 'package:selfprivacy/ui/components/progress_bar/progress_bar.dart';
import 'package:selfprivacy/ui/pages/root_route.dart'; import 'package:selfprivacy/ui/pages/root_route.dart';
import 'package:selfprivacy/ui/pages/setup/initializing/provider_picker.dart'; import 'package:selfprivacy/ui/pages/setup/initializing/server_provider_picker.dart';
import 'package:selfprivacy/ui/pages/setup/initializing/server_type_picker.dart';
import 'package:selfprivacy/ui/pages/setup/recovering/recovery_routing.dart'; import 'package:selfprivacy/ui/pages/setup/recovering/recovery_routing.dart';
import 'package:selfprivacy/utils/route_transitions/basic.dart'; import 'package:selfprivacy/utils/route_transitions/basic.dart';
class InitializingPage extends StatelessWidget { class InitializingPage extends StatelessWidget {
const InitializingPage({ const InitializingPage({
final super.key, super.key,
}); });
@override @override
@ -36,7 +36,8 @@ class InitializingPage extends StatelessWidget {
Widget? actualInitializingPage; Widget? actualInitializingPage;
if (cubit.state is! ServerInstallationFinished) { if (cubit.state is! ServerInstallationFinished) {
actualInitializingPage = [ actualInitializingPage = [
() => _stepHetzner(cubit), () => _stepServerProviderToken(cubit),
() => _stepServerType(cubit),
() => _stepCloudflare(cubit), () => _stepCloudflare(cubit),
() => _stepBackblaze(cubit), () => _stepBackblaze(cubit),
() => _stepDomain(cubit), () => _stepDomain(cubit),
@ -139,11 +140,16 @@ class InitializingPage extends StatelessWidget {
} }
} }
Widget _stepHetzner(final ServerInstallationCubit serverInstallationCubit) => Widget _stepServerProviderToken(final ServerInstallationCubit serverInstallationCubit) =>
ProviderPicker( ServerProviderPicker(
serverInstallationCubit: serverInstallationCubit, serverInstallationCubit: serverInstallationCubit,
); );
Widget _stepServerType(final ServerInstallationCubit serverInstallationCubit) =>
ServerTypePicker(
serverInstallationCubit: serverInstallationCubit,
);
void _showModal(final BuildContext context, final Widget widget) { void _showModal(final BuildContext context, final Widget widget) {
showModalBottomSheet<void>( showModalBottomSheet<void>(
context: context, context: context,

View File

@ -9,8 +9,8 @@ import 'package:selfprivacy/ui/components/brand_bottom_sheet/brand_bottom_sheet.
import 'package:selfprivacy/ui/components/brand_button/filled_button.dart'; import 'package:selfprivacy/ui/components/brand_button/filled_button.dart';
import 'package:selfprivacy/ui/components/brand_md/brand_md.dart'; import 'package:selfprivacy/ui/components/brand_md/brand_md.dart';
class ProviderPicker extends StatefulWidget { class ServerProviderPicker extends StatefulWidget {
const ProviderPicker({ const ServerProviderPicker({
required this.serverInstallationCubit, required this.serverInstallationCubit,
super.key, super.key,
}); });
@ -18,10 +18,10 @@ class ProviderPicker extends StatefulWidget {
final ServerInstallationCubit serverInstallationCubit; final ServerInstallationCubit serverInstallationCubit;
@override @override
State<ProviderPicker> createState() => _ProviderPickerState(); State<ServerProviderPicker> createState() => _ServerProviderPickerState();
} }
class _ProviderPickerState extends State<ProviderPicker> { class _ServerProviderPickerState extends State<ServerProviderPicker> {
ServerProvider selectedProvider = ServerProvider.unknown; ServerProvider selectedProvider = ServerProvider.unknown;
void setProvider(final ServerProvider provider) { void setProvider(final ServerProvider provider) {

View File

@ -0,0 +1,118 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
import 'package:selfprivacy/logic/models/hive/server_details.dart';
import 'package:selfprivacy/logic/models/server_provider_location.dart';
class ServerTypePicker extends StatefulWidget {
const ServerTypePicker({
required this.serverInstallationCubit,
super.key,
});
final ServerInstallationCubit serverInstallationCubit;
@override
State<ServerTypePicker> createState() => _ServerTypePickerState();
}
class _ServerTypePickerState extends State<ServerTypePicker> {
ServerProviderLocation? serverProviderLocation;
void setServerProviderLocation(final ServerProviderLocation location) {
setState(() {
serverProviderLocation = location;
});
}
@override
Widget build(final BuildContext context) {
}
}
class SelectLocationPage extends StatelessWidget {
const SelectLocationPage({
required this.serverInstallationCubit,
super.key,
});
final ServerInstallationCubit serverInstallationCubit;
@override
Widget build(final BuildContext context) => FutureBuilder(
future: serverInstallationCubit.repository.serverProviderApiFactory,
builder: (
final BuildContext context,
final AsyncSnapshot<Object?> snapshot,
) {
if (snapshot.hasData) {
return _KeyDisplay(
newDeviceKey: snapshot.data.toString(),
);
} else {
return const Center(child: CircularProgressIndicator());
}
},
),
}
class ProviderSelectionPage extends StatelessWidget {
const ProviderSelectionPage({
required this.callback,
super.key,
});
final Function callback;
@override
Widget build(final BuildContext context) => Column(
children: [
Text(
'initializing.select_provider'.tr(),
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 10),
Text(
'initializing.place_where_data'.tr(),
),
const SizedBox(height: 10),
ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 320,
),
child: Row(
children: [
InkWell(
onTap: () {
context
.read<ServerInstallationCubit>()
.setServerProviderType(ServerProvider.hetzner);
callback(ServerProvider.hetzner);
},
child: Image.asset(
'assets/images/logos/hetzner.png',
width: 150,
),
),
const SizedBox(
width: 20,
),
InkWell(
onTap: () {
context
.read<ServerInstallationCubit>()
.setServerProviderType(ServerProvider.digitalOcean);
callback(ServerProvider.digitalOcean);
},
child: Image.asset(
'assets/images/logos/digital_ocean.png',
width: 150,
),
),
],
),
),
],
);
}