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/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';
@ -93,6 +95,19 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
)
.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 {
await repository.saveServerProviderKey(serverProviderKey);

View File

@ -3,6 +3,7 @@ part of '../server_installation/server_installation_cubit.dart';
abstract class ServerInstallationState extends Equatable {
const ServerInstallationState({
required this.providerApiToken,
required this.serverType,
required this.cloudFlareKey,
required this.backblazeCredential,
required this.serverDomain,
@ -31,11 +32,13 @@ abstract class ServerInstallationState extends Equatable {
final ServerDomain? serverDomain;
final User? rootUser;
final ServerHostingDetails? serverDetails;
final ServerType? serverType;
final bool isServerStarted;
final bool isServerResetedFirstTime;
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 isBackupsProviderFilled => backblazeCredential != null;
bool get isDomainSelected => serverDomain != null;
@ -58,7 +61,8 @@ abstract class ServerInstallationState extends Equatable {
List<bool?> get _fulfilementList {
final List<bool> res = [
isServerProviderFilled,
isServerProviderApiKeyFilled,
isServerTypeFilled,
isDnsProviderFilled,
isBackupsProviderFilled,
isDomainSelected,
@ -76,11 +80,12 @@ abstract class ServerInstallationState extends Equatable {
class TimerState extends ServerInstallationNotFinished {
TimerState({
required this.dataState,
required final super.isLoading,
required super.isLoading,
this.timerStart,
this.duration,
}) : super(
providerApiToken: dataState.providerApiToken,
serverType: dataState.serverType,
cloudFlareKey: dataState.cloudFlareKey,
backblazeCredential: dataState.backblazeCredential,
serverDomain: dataState.serverDomain,
@ -119,17 +124,18 @@ enum ServerSetupProgress {
class ServerInstallationNotFinished extends ServerInstallationState {
const ServerInstallationNotFinished({
required final super.isServerStarted,
required final super.isServerResetedFirstTime,
required final super.isServerResetedSecondTime,
required final this.isLoading,
required super.isServerStarted,
required super.isServerResetedFirstTime,
required super.isServerResetedSecondTime,
required this.isLoading,
required this.dnsMatches,
final super.providerApiToken,
final super.cloudFlareKey,
final super.backblazeCredential,
final super.serverDomain,
final super.rootUser,
final super.serverDetails,
super.providerApiToken,
super.serverType,
super.cloudFlareKey,
super.backblazeCredential,
super.serverDomain,
super.rootUser,
super.serverDetails,
});
final bool isLoading;
final Map<String, bool>? dnsMatches;
@ -137,6 +143,7 @@ class ServerInstallationNotFinished extends ServerInstallationState {
@override
List<Object?> get props => [
providerApiToken,
serverType,
cloudFlareKey,
backblazeCredential,
serverDomain,
@ -150,6 +157,7 @@ class ServerInstallationNotFinished extends ServerInstallationState {
ServerInstallationNotFinished copyWith({
final String? providerApiToken,
final ServerType? serverType,
final String? cloudFlareKey,
final BackblazeCredential? backblazeCredential,
final ServerDomain? serverDomain,
@ -163,6 +171,7 @@ class ServerInstallationNotFinished extends ServerInstallationState {
}) =>
ServerInstallationNotFinished(
providerApiToken: providerApiToken ?? this.providerApiToken,
serverType: serverType ?? this.serverType,
cloudFlareKey: cloudFlareKey ?? this.cloudFlareKey,
backblazeCredential: backblazeCredential ?? this.backblazeCredential,
serverDomain: serverDomain ?? this.serverDomain,
@ -179,6 +188,7 @@ class ServerInstallationNotFinished extends ServerInstallationState {
ServerInstallationFinished finish() => ServerInstallationFinished(
providerApiToken: providerApiToken!,
serverType: serverType!,
cloudFlareKey: cloudFlareKey!,
backblazeCredential: backblazeCredential!,
serverDomain: serverDomain!,
@ -209,20 +219,22 @@ class ServerInstallationEmpty extends ServerInstallationNotFinished {
class ServerInstallationFinished extends ServerInstallationState {
const ServerInstallationFinished({
required final String super.providerApiToken,
required final String super.cloudFlareKey,
required final BackblazeCredential super.backblazeCredential,
required final ServerDomain super.serverDomain,
required final User super.rootUser,
required final ServerHostingDetails super.serverDetails,
required final super.isServerStarted,
required final super.isServerResetedFirstTime,
required final super.isServerResetedSecondTime,
required String super.providerApiToken,
required ServerType super.serverType,
required String super.cloudFlareKey,
required BackblazeCredential super.backblazeCredential,
required ServerDomain super.serverDomain,
required User super.rootUser,
required ServerHostingDetails super.serverDetails,
required super.isServerStarted,
required super.isServerResetedFirstTime,
required super.isServerResetedSecondTime,
});
@override
List<Object?> get props => [
providerApiToken,
serverType,
cloudFlareKey,
backblazeCredential,
serverDomain,
@ -260,12 +272,13 @@ class ServerInstallationRecovery extends ServerInstallationState {
const ServerInstallationRecovery({
required this.currentStep,
required this.recoveryCapabilities,
final super.providerApiToken,
final super.cloudFlareKey,
final super.backblazeCredential,
final super.serverDomain,
final super.rootUser,
final super.serverDetails,
super.providerApiToken,
super.serverType,
super.cloudFlareKey,
super.backblazeCredential,
super.serverDomain,
super.rootUser,
super.serverDetails,
}) : super(
isServerStarted: true,
isServerResetedFirstTime: true,
@ -277,6 +290,7 @@ class ServerInstallationRecovery extends ServerInstallationState {
@override
List<Object?> get props => [
providerApiToken,
serverType,
cloudFlareKey,
backblazeCredential,
serverDomain,
@ -289,6 +303,7 @@ class ServerInstallationRecovery extends ServerInstallationState {
ServerInstallationRecovery copyWith({
final String? providerApiToken,
final ServerType? serverType,
final String? cloudFlareKey,
final BackblazeCredential? backblazeCredential,
final ServerDomain? serverDomain,
@ -299,6 +314,7 @@ class ServerInstallationRecovery extends ServerInstallationState {
}) =>
ServerInstallationRecovery(
providerApiToken: providerApiToken ?? this.providerApiToken,
serverType: serverType ?? this.serverType,
cloudFlareKey: cloudFlareKey ?? this.cloudFlareKey,
backblazeCredential: backblazeCredential ?? this.backblazeCredential,
serverDomain: serverDomain ?? this.serverDomain,
@ -310,6 +326,7 @@ class ServerInstallationRecovery extends ServerInstallationState {
ServerInstallationFinished finish() => ServerInstallationFinished(
providerApiToken: providerApiToken!,
serverType: serverType!,
cloudFlareKey: cloudFlareKey!,
backblazeCredential: backblazeCredential!,
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/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/provider_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_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/progress_bar/progress_bar.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/utils/route_transitions/basic.dart';
class InitializingPage extends StatelessWidget {
const InitializingPage({
final super.key,
super.key,
});
@override
@ -36,7 +36,8 @@ class InitializingPage extends StatelessWidget {
Widget? actualInitializingPage;
if (cubit.state is! ServerInstallationFinished) {
actualInitializingPage = [
() => _stepHetzner(cubit),
() => _stepServerProviderToken(cubit),
() => _stepServerType(cubit),
() => _stepCloudflare(cubit),
() => _stepBackblaze(cubit),
() => _stepDomain(cubit),
@ -139,11 +140,16 @@ class InitializingPage extends StatelessWidget {
}
}
Widget _stepHetzner(final ServerInstallationCubit serverInstallationCubit) =>
ProviderPicker(
Widget _stepServerProviderToken(final ServerInstallationCubit serverInstallationCubit) =>
ServerProviderPicker(
serverInstallationCubit: serverInstallationCubit,
);
Widget _stepServerType(final ServerInstallationCubit serverInstallationCubit) =>
ServerTypePicker(
serverInstallationCubit: serverInstallationCubit,
);
void _showModal(final BuildContext context, final Widget widget) {
showModalBottomSheet<void>(
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_md/brand_md.dart';
class ProviderPicker extends StatefulWidget {
const ProviderPicker({
class ServerProviderPicker extends StatefulWidget {
const ServerProviderPicker({
required this.serverInstallationCubit,
super.key,
});
@ -18,10 +18,10 @@ class ProviderPicker extends StatefulWidget {
final ServerInstallationCubit serverInstallationCubit;
@override
State<ProviderPicker> createState() => _ProviderPickerState();
State<ServerProviderPicker> createState() => _ServerProviderPickerState();
}
class _ProviderPickerState extends State<ProviderPicker> {
class _ServerProviderPickerState extends State<ServerProviderPicker> {
ServerProvider selectedProvider = ServerProvider.unknown;
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,
),
),
],
),
),
],
);
}