mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2024-11-19 07:09:14 +00:00
refactor: Server location is no longer a part of server provider controller.
This commit is contained in:
parent
55616c3e69
commit
e13b324afa
|
@ -10,7 +10,6 @@ import 'package:selfprivacy/utils/password_generator.dart';
|
|||
|
||||
class DigitalOceanApi extends RestApiMap {
|
||||
DigitalOceanApi({
|
||||
required this.region,
|
||||
this.token = '',
|
||||
this.hasLogger = true,
|
||||
this.isWithToken = true,
|
||||
|
@ -21,7 +20,6 @@ class DigitalOceanApi extends RestApiMap {
|
|||
@override
|
||||
bool isWithToken;
|
||||
|
||||
final String? region;
|
||||
final String token;
|
||||
|
||||
@override
|
||||
|
@ -79,6 +77,7 @@ class DigitalOceanApi extends RestApiMap {
|
|||
required final String hostName,
|
||||
required final String serverType,
|
||||
required final String? customSshKey,
|
||||
required final String region,
|
||||
}) async {
|
||||
final String stagingAcme = TlsOptions.stagingAcme ? 'true' : 'false';
|
||||
|
||||
|
@ -98,7 +97,7 @@ class DigitalOceanApi extends RestApiMap {
|
|||
"HOSTNAME=$hostName LUSER='${rootUser.login}' NIX_VERSION=2.18.1 PROVIDER=$infectProviderName STAGING_ACME='$stagingAcme' "
|
||||
"${customSshKey != null ? "SSH_AUTHORIZED_KEY='$customSshKey'" : ""} "
|
||||
'bash 2>&1 | tee /root/nixos-infect.log',
|
||||
'region': region!,
|
||||
'region': region,
|
||||
};
|
||||
print('Decoded data: $data');
|
||||
|
||||
|
@ -326,7 +325,10 @@ class DigitalOceanApi extends RestApiMap {
|
|||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<DigitalOceanVolume?>> createVolume(final int gb) async {
|
||||
Future<GenericResult<DigitalOceanVolume?>> createVolume({
|
||||
required final int gb,
|
||||
required final String region,
|
||||
}) async {
|
||||
DigitalOceanVolume? volume;
|
||||
Response? createVolumeResponse;
|
||||
final Dio client = await getClient();
|
||||
|
@ -363,10 +365,11 @@ class DigitalOceanApi extends RestApiMap {
|
|||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<bool>> attachVolume(
|
||||
final String name,
|
||||
final int serverId,
|
||||
) async {
|
||||
Future<GenericResult<bool>> attachVolume({
|
||||
required final String name,
|
||||
required final int serverId,
|
||||
required final String region,
|
||||
}) async {
|
||||
bool success = false;
|
||||
|
||||
Response? attachVolumeResponse;
|
||||
|
@ -402,10 +405,11 @@ class DigitalOceanApi extends RestApiMap {
|
|||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<bool>> detachVolume(
|
||||
final String name,
|
||||
final int serverId,
|
||||
) async {
|
||||
Future<GenericResult<bool>> detachVolume({
|
||||
required final String name,
|
||||
required final int serverId,
|
||||
required final String region,
|
||||
}) async {
|
||||
bool success = false;
|
||||
|
||||
final Response detachVolumeResponse;
|
||||
|
@ -460,10 +464,11 @@ class DigitalOceanApi extends RestApiMap {
|
|||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<bool>> resizeVolume(
|
||||
final String uuid,
|
||||
final int gb,
|
||||
) async {
|
||||
Future<GenericResult<bool>> resizeVolume({
|
||||
required final String uuid,
|
||||
required final int gb,
|
||||
required final String region,
|
||||
}) async {
|
||||
bool success = false;
|
||||
|
||||
final Response resizeVolumeResponse;
|
||||
|
|
|
@ -11,7 +11,6 @@ import 'package:selfprivacy/utils/password_generator.dart';
|
|||
|
||||
class HetznerApi extends RestApiMap {
|
||||
HetznerApi({
|
||||
this.region,
|
||||
this.token = '',
|
||||
this.hasLogger = true,
|
||||
this.isWithToken = true,
|
||||
|
@ -22,7 +21,6 @@ class HetznerApi extends RestApiMap {
|
|||
@override
|
||||
bool isWithToken;
|
||||
|
||||
final String? region;
|
||||
final String token;
|
||||
|
||||
@override
|
||||
|
@ -85,6 +83,7 @@ class HetznerApi extends RestApiMap {
|
|||
required final int volumeId,
|
||||
required final String serverType,
|
||||
required final String? customSshKey,
|
||||
required final String region,
|
||||
}) async {
|
||||
final String stagingAcme = TlsOptions.stagingAcme ? 'true' : 'false';
|
||||
Response? serverCreateResponse;
|
||||
|
@ -111,7 +110,7 @@ class HetznerApi extends RestApiMap {
|
|||
'bash 2>&1 | tee /root/nixos-infect.log',
|
||||
'labels': {},
|
||||
'automount': true,
|
||||
'location': region!,
|
||||
'location': region,
|
||||
};
|
||||
print('Decoded data: $data');
|
||||
|
||||
|
@ -326,7 +325,9 @@ class HetznerApi extends RestApiMap {
|
|||
return GenericResult(success: true, data: null);
|
||||
}
|
||||
|
||||
Future<GenericResult<HetznerPricing?>> getPricing() async {
|
||||
Future<GenericResult<HetznerPricing?>> getPricing({
|
||||
required final String region,
|
||||
}) async {
|
||||
HetznerPricing? pricing;
|
||||
|
||||
final Response pricingResponse;
|
||||
|
@ -341,14 +342,14 @@ class HetznerApi extends RestApiMap {
|
|||
for (final primaryIp in primaryIps) {
|
||||
if (primaryIp['type'] == 'ipv4') {
|
||||
for (final primaryIpPrice in primaryIp['prices']) {
|
||||
if (primaryIpPrice['location'] == region!) {
|
||||
if (primaryIpPrice['location'] == region) {
|
||||
ipPrice = primaryIpPrice['price_monthly']['gross'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pricing = HetznerPricing(
|
||||
region!,
|
||||
region,
|
||||
double.parse(volumePrice),
|
||||
double.parse(ipPrice!),
|
||||
);
|
||||
|
@ -395,7 +396,10 @@ class HetznerApi extends RestApiMap {
|
|||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<HetznerVolume?>> createVolume(final int gb) async {
|
||||
Future<GenericResult<HetznerVolume?>> createVolume({
|
||||
required final int gb,
|
||||
required final String region,
|
||||
}) async {
|
||||
Response? createVolumeResponse;
|
||||
HetznerVolume? volume;
|
||||
final Dio client = await getClient();
|
||||
|
|
|
@ -201,7 +201,7 @@ class TokensBloc extends Bloc<TokensEvent, TokensState> {
|
|||
),
|
||||
apiToken: event.server.hostingDetails.apiToken,
|
||||
provider: event.serverProviderCredential.provider,
|
||||
serverLocation: event.server.hostingDetails.serverLocation,
|
||||
serverLocation: event.providerServer.location,
|
||||
serverType: event.server.hostingDetails.serverType,
|
||||
),
|
||||
);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:bloc_concurrency/bloc_concurrency.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
@ -88,14 +89,21 @@ class VolumesBloc extends Bloc<VolumesEvent, VolumesState> {
|
|||
return null;
|
||||
}
|
||||
Price? price;
|
||||
final pricingResult =
|
||||
await ProvidersController.currentServerProvider!.getAdditionalPricing();
|
||||
if (pricingResult.data == null || !pricingResult.success) {
|
||||
final location = state.location;
|
||||
if (location != null) {
|
||||
final pricingResult = await ProvidersController.currentServerProvider!
|
||||
.getAdditionalPricing(location);
|
||||
if (pricingResult.data == null || !pricingResult.success) {
|
||||
getIt<NavigationService>().showSnackBar('server.pricing_error'.tr());
|
||||
return price;
|
||||
}
|
||||
price = pricingResult.data!.perVolumeGb;
|
||||
return price;
|
||||
} else {
|
||||
await Future.delayed(Duration.zero);
|
||||
getIt<NavigationService>().showSnackBar('server.pricing_error'.tr());
|
||||
return price;
|
||||
}
|
||||
price = pricingResult.data!.perVolumeGb;
|
||||
return price;
|
||||
}
|
||||
|
||||
Future<void> _loadState(
|
||||
|
|
|
@ -17,6 +17,11 @@ sealed class VolumesState extends Equatable {
|
|||
orElse: () => DiskVolume(),
|
||||
);
|
||||
|
||||
String? get location => volumes
|
||||
.firstWhereOrNull((final volume) => volume.isResizable)
|
||||
?.providerVolume
|
||||
?.location;
|
||||
|
||||
bool get isProviderVolumesLoaded => providerVolumes.isNotEmpty;
|
||||
|
||||
VolumesState copyWith({
|
||||
|
|
|
@ -45,17 +45,26 @@ class ServerDetailsCubit
|
|||
Future<List<ServerMetadataEntity>> get _metadata async {
|
||||
final List<ServerMetadataEntity> data = [];
|
||||
|
||||
final Server? server = getIt<ResourcesModel>().servers.firstOrNull;
|
||||
|
||||
if (server == null) {
|
||||
return data;
|
||||
}
|
||||
|
||||
final serverProviderApi = ProvidersController.currentServerProvider;
|
||||
final dnsProviderApi = ProvidersController.currentDnsProvider;
|
||||
if (serverProviderApi?.isAuthorized ?? false) {
|
||||
final serverId = getIt<ResourcesModel>().serverDetails?.id ?? 0;
|
||||
final metadataResult = await serverProviderApi?.getMetadata(serverId);
|
||||
if (server.hostingDetails.serverLocation != null &&
|
||||
(serverProviderApi?.isAuthorized ?? false)) {
|
||||
final serverId = server.hostingDetails.id;
|
||||
final metadataResult = await serverProviderApi?.getMetadata(
|
||||
serverId,
|
||||
server.hostingDetails.serverLocation!,
|
||||
);
|
||||
|
||||
data.addAll(metadataResult?.data ?? []);
|
||||
}
|
||||
|
||||
if (serverProviderApi == null || !serverProviderApi.isAuthorized) {
|
||||
final Server server = getIt<ResourcesModel>().servers.first;
|
||||
data.add(
|
||||
ServerMetadataEntity(
|
||||
type: MetadataType.other,
|
||||
|
@ -74,7 +83,6 @@ class ServerDetailsCubit
|
|||
),
|
||||
);
|
||||
} else {
|
||||
final Server server = getIt<ResourcesModel>().servers.first;
|
||||
data.add(
|
||||
ServerMetadataEntity(
|
||||
trId: 'server.dns_provider',
|
||||
|
|
|
@ -168,10 +168,12 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
|||
return apiResult.data;
|
||||
}
|
||||
|
||||
Future<AdditionalPricing?> fetchAvailableAdditionalPricing() async {
|
||||
Future<AdditionalPricing?> fetchAvailableAdditionalPricing(
|
||||
final ServerProviderLocation location,
|
||||
) async {
|
||||
AdditionalPricing? prices;
|
||||
final pricingResult =
|
||||
await ProvidersController.currentServerProvider!.getAdditionalPricing();
|
||||
final pricingResult = await ProvidersController.currentServerProvider!
|
||||
.getAdditionalPricing(location.identifier);
|
||||
if (pricingResult.data == null || !pricingResult.success) {
|
||||
getIt<NavigationService>().showSnackBar('server.pricing_error'.tr());
|
||||
return prices;
|
||||
|
@ -202,8 +204,11 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
|||
}
|
||||
|
||||
Future<void> setLocationIdentifier(final String locationId) async {
|
||||
await ProvidersController.currentServerProvider!
|
||||
.trySetServerLocation(locationId);
|
||||
emit(
|
||||
(state as ServerInstallationNotFinished).copyWith(
|
||||
serverLocation: locationId,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void setServerType(final ServerType serverType) async {
|
||||
|
@ -212,6 +217,7 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
|||
emit(
|
||||
(state as ServerInstallationNotFinished).copyWith(
|
||||
serverTypeIdentificator: serverType.identifier,
|
||||
serverLocation: serverType.location.identifier,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -335,6 +341,7 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
|||
successCallback: onCreateServerSuccess,
|
||||
storageSize: initialStorage,
|
||||
customSshKey: (state as ServerInstallationNotFinished).customSshKey,
|
||||
location: state.serverLocation!,
|
||||
);
|
||||
|
||||
final result =
|
||||
|
@ -794,12 +801,14 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
|||
),
|
||||
apiToken: dataState.serverDetails!.apiToken,
|
||||
provider: dataState.serverDetails!.provider,
|
||||
serverLocation: server.location,
|
||||
);
|
||||
await repository.saveDomain(serverDomain);
|
||||
await repository.saveServerDetails(serverDetails);
|
||||
emit(
|
||||
dataState.copyWith(
|
||||
serverDetails: serverDetails,
|
||||
serverLocation: server.location,
|
||||
currentStep: RecoveryStep.dnsProviderToken,
|
||||
),
|
||||
);
|
||||
|
@ -858,8 +867,6 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
|||
?.getServerType(state.serverDetails!.id);
|
||||
if (serverType != null) {
|
||||
await repository.saveServerType(serverType.data!);
|
||||
await ProvidersController.currentServerProvider!
|
||||
.trySetServerLocation(serverType.data!.location.identifier);
|
||||
}
|
||||
} else {
|
||||
serverType = null;
|
||||
|
|
|
@ -64,7 +64,6 @@ class ServerInstallationRepository {
|
|||
ServerProviderSettings(
|
||||
provider: serverProvider ?? serverDetails!.provider,
|
||||
isAuthorized: providerApiToken != null,
|
||||
location: location,
|
||||
token: providerApiToken,
|
||||
),
|
||||
);
|
||||
|
@ -100,6 +99,7 @@ class ServerInstallationRepository {
|
|||
serverDomain: serverDomain!,
|
||||
backblazeCredential: backblazeCredential!,
|
||||
serverDetails: serverDetails!,
|
||||
serverLocation: location,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -111,7 +111,6 @@ class ServerInstallationRepository {
|
|||
ServerProviderSettings(
|
||||
provider: wizardData.serverProviderType!,
|
||||
isAuthorized: wizardData.serverProviderKey != null,
|
||||
location: wizardData.serverLocation,
|
||||
token: wizardData.serverProviderKey,
|
||||
),
|
||||
);
|
||||
|
@ -134,6 +133,7 @@ class ServerInstallationRepository {
|
|||
dnsApiToken: wizardData.dnsProviderKey,
|
||||
serverDomain: wizardData.serverDomain,
|
||||
serverTypeIdentificator: wizardData.serverTypeIdentifier,
|
||||
serverLocation: wizardData.serverLocation,
|
||||
backblazeCredential: wizardData.backupsCredential,
|
||||
serverDetails: wizardData.serverDetails,
|
||||
currentStep: _getCurrentRecoveryStep(
|
||||
|
|
|
@ -13,6 +13,7 @@ abstract class ServerInstallationState extends Equatable {
|
|||
required this.isServerResetedFirstTime,
|
||||
required this.isServerResetedSecondTime,
|
||||
required this.installationDialoguePopUp,
|
||||
required this.serverLocation,
|
||||
});
|
||||
|
||||
@override
|
||||
|
@ -27,11 +28,13 @@ abstract class ServerInstallationState extends Equatable {
|
|||
isServerStarted,
|
||||
isServerResetedFirstTime,
|
||||
installationDialoguePopUp,
|
||||
serverLocation,
|
||||
];
|
||||
|
||||
final String? providerApiToken;
|
||||
final String? dnsApiToken;
|
||||
final String? serverTypeIdentificator;
|
||||
final String? serverLocation;
|
||||
final BackupsCredential? backblazeCredential;
|
||||
final ServerDomain? serverDomain;
|
||||
final User? rootUser;
|
||||
|
@ -91,6 +94,7 @@ class TimerState extends ServerInstallationNotFinished {
|
|||
}) : super(
|
||||
providerApiToken: dataState.providerApiToken,
|
||||
serverTypeIdentificator: dataState.serverTypeIdentificator,
|
||||
serverLocation: dataState.serverLocation,
|
||||
dnsApiToken: dataState.dnsApiToken,
|
||||
backblazeCredential: dataState.backblazeCredential,
|
||||
serverDomain: dataState.serverDomain,
|
||||
|
@ -139,6 +143,7 @@ class ServerInstallationNotFinished extends ServerInstallationState {
|
|||
required this.dnsMatches,
|
||||
required this.customSshKey,
|
||||
super.providerApiToken,
|
||||
super.serverLocation,
|
||||
super.serverTypeIdentificator,
|
||||
super.dnsApiToken,
|
||||
super.backblazeCredential,
|
||||
|
@ -155,6 +160,7 @@ class ServerInstallationNotFinished extends ServerInstallationState {
|
|||
dnsApiToken: data.dnsProviderKey,
|
||||
serverDomain: data.serverDomain,
|
||||
serverTypeIdentificator: data.serverTypeIdentifier,
|
||||
serverLocation: data.serverLocation,
|
||||
backblazeCredential: data.backupsCredential,
|
||||
serverDetails: data.serverDetails,
|
||||
rootUser: data.rootUser,
|
||||
|
@ -175,6 +181,7 @@ class ServerInstallationNotFinished extends ServerInstallationState {
|
|||
List<Object?> get props => [
|
||||
providerApiToken,
|
||||
serverTypeIdentificator,
|
||||
serverLocation,
|
||||
dnsApiToken,
|
||||
backblazeCredential,
|
||||
serverDomain,
|
||||
|
@ -190,6 +197,7 @@ class ServerInstallationNotFinished extends ServerInstallationState {
|
|||
|
||||
ServerInstallationNotFinished copyWith({
|
||||
final String? providerApiToken,
|
||||
final String? serverLocation,
|
||||
final String? serverTypeIdentificator,
|
||||
final String? dnsApiToken,
|
||||
final BackupsCredential? backblazeCredential,
|
||||
|
@ -206,6 +214,7 @@ class ServerInstallationNotFinished extends ServerInstallationState {
|
|||
}) =>
|
||||
ServerInstallationNotFinished(
|
||||
providerApiToken: providerApiToken ?? this.providerApiToken,
|
||||
serverLocation: serverLocation ?? this.serverLocation,
|
||||
serverTypeIdentificator:
|
||||
serverTypeIdentificator ?? this.serverTypeIdentificator,
|
||||
dnsApiToken: dnsApiToken ?? this.dnsApiToken,
|
||||
|
@ -227,6 +236,7 @@ class ServerInstallationNotFinished extends ServerInstallationState {
|
|||
|
||||
ServerInstallationFinished finish() => ServerInstallationFinished(
|
||||
providerApiToken: providerApiToken,
|
||||
serverLocation: serverLocation,
|
||||
serverTypeIdentificator: serverTypeIdentificator,
|
||||
dnsApiToken: dnsApiToken!,
|
||||
backblazeCredential: backblazeCredential!,
|
||||
|
@ -239,6 +249,7 @@ class ServerInstallationEmpty extends ServerInstallationNotFinished {
|
|||
const ServerInstallationEmpty()
|
||||
: super(
|
||||
providerApiToken: null,
|
||||
serverLocation: null,
|
||||
serverTypeIdentificator: null,
|
||||
dnsApiToken: null,
|
||||
backblazeCredential: null,
|
||||
|
@ -263,6 +274,7 @@ class ServerInstallationFinished extends ServerInstallationState {
|
|||
required ServerHostingDetails super.serverDetails,
|
||||
super.providerApiToken,
|
||||
super.serverTypeIdentificator,
|
||||
super.serverLocation,
|
||||
}) : super(
|
||||
rootUser: null,
|
||||
isServerStarted: true,
|
||||
|
@ -275,6 +287,7 @@ class ServerInstallationFinished extends ServerInstallationState {
|
|||
List<Object?> get props => [
|
||||
providerApiToken,
|
||||
serverTypeIdentificator,
|
||||
serverLocation,
|
||||
dnsApiToken,
|
||||
backblazeCredential,
|
||||
serverDomain,
|
||||
|
@ -315,6 +328,7 @@ class ServerInstallationRecovery extends ServerInstallationState {
|
|||
required this.recoveryCapabilities,
|
||||
super.providerApiToken,
|
||||
super.serverTypeIdentificator,
|
||||
super.serverLocation,
|
||||
super.dnsApiToken,
|
||||
super.backblazeCredential,
|
||||
super.serverDomain,
|
||||
|
@ -333,6 +347,7 @@ class ServerInstallationRecovery extends ServerInstallationState {
|
|||
List<Object?> get props => [
|
||||
providerApiToken,
|
||||
serverTypeIdentificator,
|
||||
serverLocation,
|
||||
dnsApiToken,
|
||||
backblazeCredential,
|
||||
serverDomain,
|
||||
|
@ -346,6 +361,7 @@ class ServerInstallationRecovery extends ServerInstallationState {
|
|||
|
||||
ServerInstallationRecovery copyWith({
|
||||
final String? providerApiToken,
|
||||
final String? serverLocation,
|
||||
final String? serverTypeIdentificator,
|
||||
final String? dnsApiToken,
|
||||
final BackupsCredential? backblazeCredential,
|
||||
|
@ -356,6 +372,7 @@ class ServerInstallationRecovery extends ServerInstallationState {
|
|||
}) =>
|
||||
ServerInstallationRecovery(
|
||||
providerApiToken: providerApiToken ?? this.providerApiToken,
|
||||
serverLocation: serverLocation ?? this.serverLocation,
|
||||
serverTypeIdentificator:
|
||||
serverTypeIdentificator ?? this.serverTypeIdentificator,
|
||||
dnsApiToken: dnsApiToken ?? this.dnsApiToken,
|
||||
|
@ -368,6 +385,7 @@ class ServerInstallationRecovery extends ServerInstallationState {
|
|||
|
||||
ServerInstallationFinished finish() => ServerInstallationFinished(
|
||||
providerApiToken: providerApiToken,
|
||||
serverLocation: serverLocation,
|
||||
serverTypeIdentificator: serverTypeIdentificator,
|
||||
dnsApiToken: dnsApiToken!,
|
||||
backblazeCredential: backblazeCredential!,
|
||||
|
|
|
@ -76,6 +76,7 @@ class ServerProviderVolume {
|
|||
required this.serverId,
|
||||
required this.linuxDevice,
|
||||
this.uuid,
|
||||
this.location,
|
||||
});
|
||||
|
||||
@HiveField(1)
|
||||
|
@ -90,6 +91,8 @@ class ServerProviderVolume {
|
|||
String? linuxDevice;
|
||||
@HiveField(6, defaultValue: null)
|
||||
String? uuid;
|
||||
@HiveField(7, defaultValue: null)
|
||||
String? location;
|
||||
}
|
||||
|
||||
@HiveType(typeId: 101)
|
||||
|
|
|
@ -83,13 +83,14 @@ class ServerProviderVolumeAdapter extends TypeAdapter<ServerProviderVolume> {
|
|||
serverId: fields[4] as int?,
|
||||
linuxDevice: fields[5] as String?,
|
||||
uuid: fields[6] as String?,
|
||||
location: fields[7] as String?,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void write(BinaryWriter writer, ServerProviderVolume obj) {
|
||||
writer
|
||||
..writeByte(6)
|
||||
..writeByte(7)
|
||||
..writeByte(1)
|
||||
..write(obj.id)
|
||||
..writeByte(2)
|
||||
|
@ -101,7 +102,9 @@ class ServerProviderVolumeAdapter extends TypeAdapter<ServerProviderVolume> {
|
|||
..writeByte(5)
|
||||
..write(obj.linuxDevice)
|
||||
..writeByte(6)
|
||||
..write(obj.uuid);
|
||||
..write(obj.uuid)
|
||||
..writeByte(7)
|
||||
..write(obj.location);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -9,6 +9,7 @@ class DigitalOceanVolume {
|
|||
this.name,
|
||||
this.sizeGigabytes,
|
||||
this.dropletIds,
|
||||
this.region,
|
||||
);
|
||||
|
||||
final String id;
|
||||
|
@ -20,6 +21,8 @@ class DigitalOceanVolume {
|
|||
@JsonKey(name: 'size_gigabytes')
|
||||
final int sizeGigabytes;
|
||||
|
||||
final DigitalOceanLocation region;
|
||||
|
||||
static DigitalOceanVolume fromJson(final Map<String, dynamic> json) =>
|
||||
_$DigitalOceanVolumeFromJson(json);
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ DigitalOceanVolume _$DigitalOceanVolumeFromJson(Map<String, dynamic> json) =>
|
|||
(json['droplet_ids'] as List<dynamic>?)
|
||||
?.map((e) => (e as num).toInt())
|
||||
.toList(),
|
||||
DigitalOceanLocation.fromJson(json['region'] as Map<String, dynamic>),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$DigitalOceanVolumeToJson(DigitalOceanVolume instance) =>
|
||||
|
@ -22,6 +23,7 @@ Map<String, dynamic> _$DigitalOceanVolumeToJson(DigitalOceanVolume instance) =>
|
|||
'name': instance.name,
|
||||
'droplet_ids': instance.dropletIds,
|
||||
'size_gigabytes': instance.sizeGigabytes,
|
||||
'region': instance.region,
|
||||
};
|
||||
|
||||
DigitalOceanLocation _$DigitalOceanLocationFromJson(
|
||||
|
|
|
@ -127,6 +127,9 @@ class HetznerLocation {
|
|||
this.zone,
|
||||
this.name,
|
||||
);
|
||||
|
||||
HetznerLocation.empty() : this('', '', '', '', '');
|
||||
|
||||
final String name;
|
||||
final String country;
|
||||
final String city;
|
||||
|
@ -192,6 +195,7 @@ class HetznerVolume {
|
|||
this.serverId,
|
||||
this.name,
|
||||
this.linuxDevice,
|
||||
this.location,
|
||||
);
|
||||
|
||||
/// ID of the Resource
|
||||
|
@ -210,6 +214,8 @@ class HetznerVolume {
|
|||
@JsonKey(name: 'linux_device')
|
||||
final String? linuxDevice;
|
||||
|
||||
final HetznerLocation location;
|
||||
|
||||
static HetznerVolume fromJson(final Map<String, dynamic> json) =>
|
||||
_$HetznerVolumeFromJson(json);
|
||||
}
|
||||
|
|
|
@ -139,6 +139,7 @@ HetznerVolume _$HetznerVolumeFromJson(Map<String, dynamic> json) =>
|
|||
(json['serverId'] as num?)?.toInt(),
|
||||
json['name'] as String,
|
||||
json['linux_device'] as String?,
|
||||
HetznerLocation.fromJson(json['location'] as Map<String, dynamic>),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$HetznerVolumeToJson(HetznerVolume instance) =>
|
||||
|
@ -148,4 +149,5 @@ Map<String, dynamic> _$HetznerVolumeToJson(HetznerVolume instance) =>
|
|||
'serverId': instance.serverId,
|
||||
'name': instance.name,
|
||||
'linux_device': instance.linuxDevice,
|
||||
'location': instance.location,
|
||||
};
|
||||
|
|
|
@ -14,6 +14,7 @@ class LaunchInstallationData {
|
|||
required this.successCallback,
|
||||
required this.storageSize,
|
||||
required this.customSshKey,
|
||||
required this.location,
|
||||
});
|
||||
|
||||
final User rootUser;
|
||||
|
@ -25,4 +26,5 @@ class LaunchInstallationData {
|
|||
final Function(ServerHostingDetails details) successCallback;
|
||||
final DiskSize storageSize;
|
||||
final String? customSshKey;
|
||||
final String location;
|
||||
}
|
||||
|
|
|
@ -5,12 +5,14 @@ class ServerBasicInfo {
|
|||
required this.reverseDns,
|
||||
required this.ip,
|
||||
required this.created,
|
||||
required this.location,
|
||||
});
|
||||
final int id;
|
||||
final String name;
|
||||
final String reverseDns;
|
||||
final String ip;
|
||||
final DateTime created;
|
||||
final String location;
|
||||
}
|
||||
|
||||
class ServerBasicInfoWithValidators extends ServerBasicInfo {
|
||||
|
@ -24,6 +26,7 @@ class ServerBasicInfoWithValidators extends ServerBasicInfo {
|
|||
reverseDns: serverBasicInfo.reverseDns,
|
||||
ip: serverBasicInfo.ip,
|
||||
created: serverBasicInfo.created,
|
||||
location: serverBasicInfo.location,
|
||||
isIpValid: isIpValid,
|
||||
isReverseDnsValid: isReverseDnsValid,
|
||||
);
|
||||
|
@ -34,6 +37,7 @@ class ServerBasicInfoWithValidators extends ServerBasicInfo {
|
|||
required super.reverseDns,
|
||||
required super.ip,
|
||||
required super.created,
|
||||
required super.location,
|
||||
required this.isIpValid,
|
||||
required this.isReverseDnsValid,
|
||||
});
|
||||
|
|
|
@ -7,13 +7,11 @@ class ServerProviderSettings {
|
|||
required this.provider,
|
||||
this.token,
|
||||
this.isAuthorized = false,
|
||||
this.location,
|
||||
});
|
||||
|
||||
final bool isAuthorized;
|
||||
final ServerProviderType provider;
|
||||
final String? token;
|
||||
final String? location;
|
||||
}
|
||||
|
||||
class DnsProviderSettings {
|
||||
|
|
|
@ -19,11 +19,9 @@ import 'package:selfprivacy/utils/password_generator.dart';
|
|||
|
||||
class ApiAdapter {
|
||||
ApiAdapter({
|
||||
final String? region,
|
||||
final bool isWithToken = true,
|
||||
final String? token,
|
||||
}) : _api = DigitalOceanApi(
|
||||
region: region,
|
||||
isWithToken: isWithToken,
|
||||
token: token ?? '',
|
||||
);
|
||||
|
@ -31,7 +29,6 @@ class ApiAdapter {
|
|||
DigitalOceanApi api({final bool getInitialized = true}) => getInitialized
|
||||
? _api
|
||||
: DigitalOceanApi(
|
||||
region: _api.region,
|
||||
isWithToken: false,
|
||||
);
|
||||
|
||||
|
@ -41,16 +38,14 @@ class ApiAdapter {
|
|||
class DigitalOceanServerProvider extends ServerProvider {
|
||||
DigitalOceanServerProvider() : _adapter = ApiAdapter(isWithToken: false);
|
||||
DigitalOceanServerProvider.load(
|
||||
final String? location,
|
||||
final bool isAuthorized,
|
||||
final String? token,
|
||||
) : _adapter = ApiAdapter(
|
||||
isWithToken: isAuthorized,
|
||||
region: location,
|
||||
token: token,
|
||||
);
|
||||
|
||||
ApiAdapter _adapter;
|
||||
final ApiAdapter _adapter;
|
||||
final Currency currency = Currency.fromType(CurrencyType.usd);
|
||||
|
||||
@override
|
||||
|
@ -90,6 +85,7 @@ class DigitalOceanServerProvider extends ServerProvider {
|
|||
created: DateTime.now(),
|
||||
ip: ipv4,
|
||||
name: server['name'],
|
||||
location: server['region']['slug'],
|
||||
);
|
||||
},
|
||||
).toList();
|
||||
|
@ -238,6 +234,7 @@ class DigitalOceanServerProvider extends ServerProvider {
|
|||
databasePassword: StringGenerators.dbPassword(),
|
||||
serverApiToken: serverApiToken,
|
||||
customSshKey: installationData.customSshKey,
|
||||
region: installationData.location,
|
||||
);
|
||||
|
||||
if (!serverResult.success || serverResult.data == null) {
|
||||
|
@ -264,12 +261,15 @@ class DigitalOceanServerProvider extends ServerProvider {
|
|||
|
||||
try {
|
||||
final int dropletId = serverResult.data!;
|
||||
final newVolume =
|
||||
(await createVolume(installationData.storageSize.gibibyte.toInt()))
|
||||
.data;
|
||||
final newVolume = (await createVolume(
|
||||
installationData.storageSize.gibibyte.toInt(),
|
||||
installationData.location,
|
||||
))
|
||||
.data;
|
||||
final bool attachedVolume = (await _adapter.api().attachVolume(
|
||||
newVolume!.name,
|
||||
dropletId,
|
||||
name: newVolume!.name,
|
||||
serverId: dropletId,
|
||||
region: installationData.location,
|
||||
))
|
||||
.data;
|
||||
|
||||
|
@ -350,9 +350,14 @@ class DigitalOceanServerProvider extends ServerProvider {
|
|||
(final el) => el.serverId == foundServer!.id,
|
||||
);
|
||||
|
||||
if (volumeToRemove.location == null) {
|
||||
throw Exception('Volume location is null!');
|
||||
}
|
||||
|
||||
await _adapter.api().detachVolume(
|
||||
volumeToRemove.name,
|
||||
volumeToRemove.serverId!,
|
||||
name: volumeToRemove.name,
|
||||
serverId: volumeToRemove.serverId!,
|
||||
region: volumeToRemove.location!,
|
||||
);
|
||||
|
||||
await Future.delayed(const Duration(seconds: 10));
|
||||
|
@ -400,33 +405,9 @@ class DigitalOceanServerProvider extends ServerProvider {
|
|||
return result;
|
||||
}
|
||||
|
||||
_adapter = ApiAdapter(region: api.region, isWithToken: true);
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<GenericResult<bool>> trySetServerLocation(
|
||||
final String location,
|
||||
) async {
|
||||
final bool apiInitialized = _adapter.api().isWithToken;
|
||||
final String token = _adapter._api.token;
|
||||
|
||||
if (!apiInitialized || token.isEmpty) {
|
||||
return GenericResult(
|
||||
success: true,
|
||||
data: false,
|
||||
message: 'Not authorized!',
|
||||
);
|
||||
}
|
||||
|
||||
_adapter = ApiAdapter(
|
||||
isWithToken: true,
|
||||
region: location,
|
||||
token: token,
|
||||
);
|
||||
return success;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<GenericResult<List<ServerProviderLocation>>>
|
||||
getAvailableLocations() async {
|
||||
|
@ -544,7 +525,9 @@ class DigitalOceanServerProvider extends ServerProvider {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<GenericResult<AdditionalPricing?>> getAdditionalPricing() async =>
|
||||
Future<GenericResult<AdditionalPricing?>> getAdditionalPricing(
|
||||
final String location,
|
||||
) async =>
|
||||
GenericResult(
|
||||
success: true,
|
||||
data: AdditionalPricing(
|
||||
|
@ -591,6 +574,7 @@ class DigitalOceanServerProvider extends ServerProvider {
|
|||
: null,
|
||||
linuxDevice: 'scsi-0DO_Volume_$volumeName',
|
||||
uuid: rawVolume.id,
|
||||
location: rawVolume.region.slug,
|
||||
);
|
||||
volumes.add(volume);
|
||||
}
|
||||
|
@ -612,10 +596,11 @@ class DigitalOceanServerProvider extends ServerProvider {
|
|||
@override
|
||||
Future<GenericResult<ServerProviderVolume?>> createVolume(
|
||||
final int gb,
|
||||
final String location,
|
||||
) async {
|
||||
ServerProviderVolume? volume;
|
||||
|
||||
final result = await _adapter.api().createVolume(gb);
|
||||
final result = await _adapter.api().createVolume(gb: gb, region: location);
|
||||
|
||||
if (!result.success || result.data == null) {
|
||||
return GenericResult(
|
||||
|
@ -687,8 +672,9 @@ class DigitalOceanServerProvider extends ServerProvider {
|
|||
final int serverId,
|
||||
) async =>
|
||||
_adapter.api().attachVolume(
|
||||
volume.name,
|
||||
serverId,
|
||||
name: volume.name,
|
||||
serverId: serverId,
|
||||
region: volume.location!,
|
||||
);
|
||||
|
||||
@override
|
||||
|
@ -696,8 +682,9 @@ class DigitalOceanServerProvider extends ServerProvider {
|
|||
final ServerProviderVolume volume,
|
||||
) async =>
|
||||
_adapter.api().detachVolume(
|
||||
volume.name,
|
||||
volume.serverId!,
|
||||
name: volume.name,
|
||||
serverId: volume.serverId!,
|
||||
region: volume.location!,
|
||||
);
|
||||
|
||||
@override
|
||||
|
@ -714,13 +701,15 @@ class DigitalOceanServerProvider extends ServerProvider {
|
|||
final DiskSize size,
|
||||
) async =>
|
||||
_adapter.api().resizeVolume(
|
||||
volume.uuid!,
|
||||
size.gibibyte.toInt(),
|
||||
uuid: volume.uuid!,
|
||||
gb: size.gibibyte.toInt(),
|
||||
region: volume.location!,
|
||||
);
|
||||
|
||||
@override
|
||||
Future<GenericResult<List<ServerMetadataEntity>>> getMetadata(
|
||||
final int serverId,
|
||||
final String location,
|
||||
) async {
|
||||
List<ServerMetadataEntity> metadata = [];
|
||||
final result = await _adapter.api().getServers();
|
||||
|
@ -741,7 +730,7 @@ class DigitalOceanServerProvider extends ServerProvider {
|
|||
message: resultVolumes.message,
|
||||
);
|
||||
}
|
||||
final resultPricePerGb = await getAdditionalPricing();
|
||||
final resultPricePerGb = await getAdditionalPricing(location);
|
||||
if (resultPricePerGb.data == null || !resultPricePerGb.success) {
|
||||
return GenericResult(
|
||||
success: false,
|
||||
|
|
|
@ -19,11 +19,9 @@ import 'package:selfprivacy/utils/password_generator.dart';
|
|||
|
||||
class ApiAdapter {
|
||||
ApiAdapter({
|
||||
final String? region,
|
||||
final bool isWithToken = true,
|
||||
final String? token,
|
||||
}) : _api = HetznerApi(
|
||||
region: region,
|
||||
isWithToken: isWithToken,
|
||||
token: token ?? '',
|
||||
);
|
||||
|
@ -31,7 +29,6 @@ class ApiAdapter {
|
|||
HetznerApi api({final bool getInitialized = true}) => getInitialized
|
||||
? _api
|
||||
: HetznerApi(
|
||||
region: _api.region,
|
||||
isWithToken: false,
|
||||
);
|
||||
|
||||
|
@ -41,16 +38,14 @@ class ApiAdapter {
|
|||
class HetznerServerProvider extends ServerProvider {
|
||||
HetznerServerProvider() : _adapter = ApiAdapter(isWithToken: false);
|
||||
HetznerServerProvider.load(
|
||||
final String? location,
|
||||
final bool isAuthorized,
|
||||
final String? token,
|
||||
) : _adapter = ApiAdapter(
|
||||
isWithToken: isAuthorized,
|
||||
region: location,
|
||||
token: token,
|
||||
);
|
||||
|
||||
ApiAdapter _adapter;
|
||||
final ApiAdapter _adapter;
|
||||
final Currency currency = Currency.fromType(CurrencyType.eur);
|
||||
int? cachedCoreAmount;
|
||||
|
||||
|
@ -87,6 +82,7 @@ class HetznerServerProvider extends ServerProvider {
|
|||
ip: hetznerServer.publicNet.ipv4!.ip,
|
||||
reverseDns: hetznerServer.publicNet.ipv4!.reverseDns,
|
||||
created: hetznerServer.created,
|
||||
location: hetznerServer.location.name,
|
||||
);
|
||||
} catch (e) {
|
||||
continue;
|
||||
|
@ -176,7 +172,8 @@ class HetznerServerProvider extends ServerProvider {
|
|||
final LaunchInstallationData installationData,
|
||||
) async {
|
||||
final volumeResult = await _adapter.api().createVolume(
|
||||
installationData.storageSize.gibibyte.toInt(),
|
||||
gb: installationData.storageSize.gibibyte.toInt(),
|
||||
region: installationData.location,
|
||||
);
|
||||
|
||||
if (!volumeResult.success || volumeResult.data == null) {
|
||||
|
@ -222,6 +219,7 @@ class HetznerServerProvider extends ServerProvider {
|
|||
databasePassword: StringGenerators.dbPassword(),
|
||||
serverApiToken: serverApiToken,
|
||||
customSshKey: installationData.customSshKey,
|
||||
region: installationData.location,
|
||||
);
|
||||
|
||||
if (!serverResult.success || serverResult.data == null) {
|
||||
|
@ -419,33 +417,9 @@ class HetznerServerProvider extends ServerProvider {
|
|||
return result;
|
||||
}
|
||||
|
||||
// _adapter = ApiAdapter(region: api.region, isWithToken: true);
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<GenericResult<bool>> trySetServerLocation(
|
||||
final String location,
|
||||
) async {
|
||||
final bool apiInitialized = _adapter.api().isWithToken;
|
||||
final String token = _adapter._api.token;
|
||||
if (!apiInitialized || token.isEmpty) {
|
||||
return GenericResult(
|
||||
success: true,
|
||||
data: false,
|
||||
message: 'Not authorized!',
|
||||
);
|
||||
}
|
||||
|
||||
_adapter = ApiAdapter(
|
||||
isWithToken: true,
|
||||
region: location,
|
||||
token: token,
|
||||
);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<GenericResult<List<ServerProviderLocation>>>
|
||||
getAvailableLocations() async {
|
||||
|
@ -566,8 +540,10 @@ class HetznerServerProvider extends ServerProvider {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<GenericResult<AdditionalPricing?>> getAdditionalPricing() async {
|
||||
final result = await _adapter.api().getPricing();
|
||||
Future<GenericResult<AdditionalPricing?>> getAdditionalPricing(
|
||||
final String location,
|
||||
) async {
|
||||
final result = await _adapter.api().getPricing(region: location);
|
||||
|
||||
if (!result.success || result.data == null) {
|
||||
return GenericResult(
|
||||
|
@ -617,12 +593,14 @@ class HetznerServerProvider extends ServerProvider {
|
|||
final volumeServer = rawVolume.serverId;
|
||||
final String volumeName = rawVolume.name;
|
||||
final volumeDevice = rawVolume.linuxDevice;
|
||||
final volumeLocation = rawVolume.location.name;
|
||||
final volume = ServerProviderVolume(
|
||||
id: volumeId,
|
||||
name: volumeName,
|
||||
sizeByte: volumeSize,
|
||||
serverId: volumeServer,
|
||||
linuxDevice: volumeDevice,
|
||||
location: volumeLocation,
|
||||
);
|
||||
volumes.add(volume);
|
||||
}
|
||||
|
@ -645,10 +623,11 @@ class HetznerServerProvider extends ServerProvider {
|
|||
@override
|
||||
Future<GenericResult<ServerProviderVolume?>> createVolume(
|
||||
final int gb,
|
||||
final String location,
|
||||
) async {
|
||||
ServerProviderVolume? volume;
|
||||
|
||||
final result = await _adapter.api().createVolume(gb);
|
||||
final result = await _adapter.api().createVolume(gb: gb, region: location);
|
||||
|
||||
if (!result.success || result.data == null) {
|
||||
return GenericResult(
|
||||
|
@ -702,6 +681,7 @@ class HetznerServerProvider extends ServerProvider {
|
|||
volume.serverId,
|
||||
volume.name,
|
||||
volume.linuxDevice,
|
||||
HetznerLocation.empty(),
|
||||
),
|
||||
size,
|
||||
);
|
||||
|
@ -718,6 +698,7 @@ class HetznerServerProvider extends ServerProvider {
|
|||
volume.serverId,
|
||||
volume.name,
|
||||
volume.linuxDevice,
|
||||
HetznerLocation.empty(),
|
||||
),
|
||||
serverId,
|
||||
);
|
||||
|
@ -733,6 +714,7 @@ class HetznerServerProvider extends ServerProvider {
|
|||
@override
|
||||
Future<GenericResult<List<ServerMetadataEntity>>> getMetadata(
|
||||
final int serverId,
|
||||
final String location,
|
||||
) async {
|
||||
List<ServerMetadataEntity> metadata = [];
|
||||
final resultServers = await _adapter.api().getServers();
|
||||
|
@ -753,7 +735,7 @@ class HetznerServerProvider extends ServerProvider {
|
|||
message: resultVolumes.message,
|
||||
);
|
||||
}
|
||||
final resultPricePerGb = await getAdditionalPricing();
|
||||
final resultPricePerGb = await getAdditionalPricing(location);
|
||||
if (resultPricePerGb.data == null || !resultPricePerGb.success) {
|
||||
return GenericResult(
|
||||
success: false,
|
||||
|
|
|
@ -60,12 +60,6 @@ abstract class ServerProvider {
|
|||
/// server provider respectfully.
|
||||
Future<GenericResult<bool>> tryInitApiByToken(final String token);
|
||||
|
||||
/// Tries to assign the location shortcode for future usage.
|
||||
///
|
||||
/// If API wasn't initialized with token by [tryInitApiByToken] beforehand,
|
||||
/// returns 'Not authorized!' error.
|
||||
Future<GenericResult<bool>> trySetServerLocation(final String location);
|
||||
|
||||
/// Returns all available server locations
|
||||
/// of the authorized user's server provider.
|
||||
Future<GenericResult<List<ServerProviderLocation>>> getAvailableLocations();
|
||||
|
@ -92,7 +86,9 @@ abstract class ServerProvider {
|
|||
|
||||
/// Returns [Price] information map of all additional resources, excluding
|
||||
/// main server type pricing
|
||||
Future<GenericResult<AdditionalPricing?>> getAdditionalPricing();
|
||||
Future<GenericResult<AdditionalPricing?>> getAdditionalPricing(
|
||||
final String location,
|
||||
);
|
||||
|
||||
/// Returns [ServerProviderVolume] of all available volumes
|
||||
/// assigned to the authorized user and attached to active machine.
|
||||
|
@ -103,7 +99,10 @@ abstract class ServerProvider {
|
|||
/// Tries to create an empty unattached [ServerProviderVolume].
|
||||
///
|
||||
/// If success, returns this volume information.
|
||||
Future<GenericResult<ServerProviderVolume?>> createVolume(final int gb);
|
||||
Future<GenericResult<ServerProviderVolume?>> createVolume(
|
||||
final int gb,
|
||||
final String location,
|
||||
);
|
||||
|
||||
/// Tries to delete the requested accessible [ServerProviderVolume].
|
||||
Future<GenericResult<void>> deleteVolume(final ServerProviderVolume volume);
|
||||
|
@ -126,10 +125,11 @@ abstract class ServerProvider {
|
|||
/// from any machine.
|
||||
Future<GenericResult<bool>> detachVolume(final ServerProviderVolume volume);
|
||||
|
||||
/// Returns metedata of an accessible machine by the provided identificator
|
||||
/// Returns metadata of an accessible machine by the provided identificator
|
||||
/// to show on ServerDetailsScreen.
|
||||
Future<GenericResult<List<ServerMetadataEntity>>> getMetadata(
|
||||
final int serverId,
|
||||
final String location,
|
||||
);
|
||||
|
||||
/// Returns information about cpu and bandwidth load within the provided
|
||||
|
|
|
@ -17,7 +17,6 @@ class ServerProviderFactory {
|
|||
case ServerProviderType.hetzner:
|
||||
return settings.isAuthorized
|
||||
? HetznerServerProvider.load(
|
||||
settings.location,
|
||||
settings.isAuthorized,
|
||||
settings.token,
|
||||
)
|
||||
|
@ -25,7 +24,6 @@ class ServerProviderFactory {
|
|||
case ServerProviderType.digitalOcean:
|
||||
return settings.isAuthorized
|
||||
? DigitalOceanServerProvider.load(
|
||||
settings.location,
|
||||
settings.isAuthorized,
|
||||
settings.token,
|
||||
)
|
||||
|
|
|
@ -172,7 +172,7 @@ class SelectTypePage extends StatelessWidget {
|
|||
final Future<List<ServerType>> serverTypes =
|
||||
serverInstallationCubit.fetchAvailableTypesByLocation(location);
|
||||
final Future<AdditionalPricing?> prices =
|
||||
serverInstallationCubit.fetchAvailableAdditionalPricing();
|
||||
serverInstallationCubit.fetchAvailableAdditionalPricing(location);
|
||||
return FutureBuilder(
|
||||
future: Future.wait([
|
||||
serverTypes,
|
||||
|
|
Loading…
Reference in a new issue