mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-23 09:16:54 +00:00
refactor(server-api): Generalize and encapsulate server metrics endpoints
This commit is contained in:
parent
e66b24d869
commit
a7cbde663e
|
@ -10,6 +10,7 @@ import 'package:selfprivacy/logic/models/disk_size.dart';
|
|||
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/user.dart';
|
||||
import 'package:selfprivacy/logic/models/metrics.dart';
|
||||
import 'package:selfprivacy/logic/models/price.dart';
|
||||
import 'package:selfprivacy/logic/models/server_basic_info.dart';
|
||||
import 'package:selfprivacy/logic/models/server_metadata.dart';
|
||||
|
@ -444,34 +445,14 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
|
|||
return server.copyWith(startTime: DateTime.now());
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> getMetrics(
|
||||
@override
|
||||
Future<ServerMetrics?> getMetrics(
|
||||
final int serverId,
|
||||
final DateTime start,
|
||||
final DateTime end,
|
||||
final String type,
|
||||
) async {
|
||||
final ServerHostingDetails? hetznerServer =
|
||||
getIt<ApiConfigModel>().serverDetails;
|
||||
|
||||
Map<String, dynamic> metrics = {};
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
final Map<String, dynamic> queryParameters = {
|
||||
'start': start.toUtc().toIso8601String(),
|
||||
'end': end.toUtc().toIso8601String(),
|
||||
'type': type
|
||||
};
|
||||
final Response res = await client.get(
|
||||
'/servers/${hetznerServer!.id}/metrics',
|
||||
queryParameters: queryParameters,
|
||||
);
|
||||
metrics = res.data;
|
||||
} catch (e) {
|
||||
print(e);
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
return metrics;
|
||||
ServerMetrics? metrics;
|
||||
return metrics!;
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -11,6 +11,7 @@ import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
|||
import 'package:selfprivacy/logic/models/json/hetzner_server_info.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/user.dart';
|
||||
import 'package:selfprivacy/logic/models/metrics.dart';
|
||||
import 'package:selfprivacy/logic/models/price.dart';
|
||||
import 'package:selfprivacy/logic/models/server_basic_info.dart';
|
||||
import 'package:selfprivacy/logic/models/server_metadata.dart';
|
||||
|
@ -486,14 +487,12 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
|
|||
return server.copyWith(startTime: DateTime.now());
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> getMetrics(
|
||||
Future<Map<String, dynamic>> requestRawMetrics(
|
||||
final int serverId,
|
||||
final DateTime start,
|
||||
final DateTime end,
|
||||
final String type,
|
||||
) async {
|
||||
final ServerHostingDetails? hetznerServer =
|
||||
getIt<ApiConfigModel>().serverDetails;
|
||||
|
||||
Map<String, dynamic> metrics = {};
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
|
@ -503,10 +502,10 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
|
|||
'type': type
|
||||
};
|
||||
final Response res = await client.get(
|
||||
'/servers/${hetznerServer!.id}/metrics',
|
||||
'/servers/$serverId/metrics',
|
||||
queryParameters: queryParameters,
|
||||
);
|
||||
metrics = res.data;
|
||||
metrics = res.data['metrics'];
|
||||
} catch (e) {
|
||||
print(e);
|
||||
} finally {
|
||||
|
@ -516,6 +515,70 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
|
|||
return metrics;
|
||||
}
|
||||
|
||||
List<TimeSeriesData> timeSeriesSerializer(
|
||||
final Map<String, dynamic> 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();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ServerMetrics?> getMetrics(
|
||||
final int serverId,
|
||||
final DateTime start,
|
||||
final DateTime end,
|
||||
) async {
|
||||
ServerMetrics? metrics;
|
||||
|
||||
final Map<String, dynamic> rawCpuMetrics = await requestRawMetrics(
|
||||
serverId,
|
||||
start,
|
||||
end,
|
||||
'cpu',
|
||||
);
|
||||
final Map<String, dynamic> rawNetworkMetrics = await requestRawMetrics(
|
||||
serverId,
|
||||
start,
|
||||
end,
|
||||
'network',
|
||||
);
|
||||
|
||||
if (rawNetworkMetrics.isEmpty || rawCpuMetrics.isEmpty) {
|
||||
return metrics;
|
||||
}
|
||||
|
||||
metrics = ServerMetrics(
|
||||
cpu: timeSeriesSerializer(
|
||||
rawCpuMetrics,
|
||||
'cpu',
|
||||
),
|
||||
ppsIn: timeSeriesSerializer(
|
||||
rawNetworkMetrics,
|
||||
'network.0.pps.in',
|
||||
),
|
||||
ppsOut: timeSeriesSerializer(
|
||||
rawNetworkMetrics,
|
||||
'network.0.pps.out',
|
||||
),
|
||||
bandwidthIn: timeSeriesSerializer(
|
||||
rawNetworkMetrics,
|
||||
'network.0.bandwidth.in',
|
||||
),
|
||||
bandwidthOut: timeSeriesSerializer(
|
||||
rawNetworkMetrics,
|
||||
'network.0.bandwidth.out',
|
||||
),
|
||||
end: end,
|
||||
start: start,
|
||||
stepsInSecond: rawCpuMetrics['step'],
|
||||
);
|
||||
|
||||
return metrics;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<ServerMetadataEntity>> getMetadata(final int serverId) async {
|
||||
List<ServerMetadataEntity> metadata = [];
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'package:selfprivacy/logic/api_maps/rest_maps/api_map.dart';
|
|||
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/user.dart';
|
||||
import 'package:selfprivacy/logic/models/metrics.dart';
|
||||
import 'package:selfprivacy/logic/models/server_basic_info.dart';
|
||||
import 'package:selfprivacy/logic/models/server_metadata.dart';
|
||||
import 'package:selfprivacy/logic/models/server_provider_location.dart';
|
||||
|
@ -41,6 +42,11 @@ abstract class ServerProviderApi extends ApiMap {
|
|||
Future<bool> isApiTokenValid(final String token);
|
||||
ProviderApiTokenValidation getApiTokenValidation();
|
||||
Future<List<ServerMetadataEntity>> getMetadata(final int serverId);
|
||||
Future<ServerMetrics?> getMetrics(
|
||||
final int serverId,
|
||||
final DateTime start,
|
||||
final DateTime end,
|
||||
);
|
||||
|
||||
abstract final String infectProviderName;
|
||||
}
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
import 'package:selfprivacy/config/get_it_config.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/hetzner/hetzner.dart';
|
||||
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
||||
import 'package:selfprivacy/logic/models/hetzner_metrics.dart';
|
||||
|
||||
import 'package:selfprivacy/logic/cubit/hetzner_metrics/hetzner_metrics_cubit.dart';
|
||||
|
||||
class MetricsLoadException implements Exception {
|
||||
MetricsLoadException(this.message);
|
||||
final String message;
|
||||
}
|
||||
|
||||
class HetznerMetricsRepository {
|
||||
Future<HetznerMetricsLoaded> getMetrics(final Period period) async {
|
||||
final DateTime end = DateTime.now();
|
||||
DateTime start;
|
||||
|
||||
switch (period) {
|
||||
case Period.hour:
|
||||
start = end.subtract(const Duration(hours: 1));
|
||||
break;
|
||||
case Period.day:
|
||||
start = end.subtract(const Duration(days: 1));
|
||||
break;
|
||||
case Period.month:
|
||||
start = end.subtract(const Duration(days: 15));
|
||||
break;
|
||||
}
|
||||
|
||||
final HetznerApi api = HetznerApi(
|
||||
/// TODO: Hetzner hardcode (???)
|
||||
hasLogger: false,
|
||||
region: getIt<ApiConfigModel>().serverLocation,
|
||||
);
|
||||
|
||||
final List<Map<String, dynamic>> results = await Future.wait([
|
||||
api.getMetrics(start, end, 'cpu'),
|
||||
api.getMetrics(start, end, 'network'),
|
||||
]);
|
||||
|
||||
final cpuMetricsData = results[0]['metrics'];
|
||||
final networkMetricsData = results[1]['metrics'];
|
||||
|
||||
if (cpuMetricsData == null || networkMetricsData == null) {
|
||||
throw MetricsLoadException('Metrics data is null');
|
||||
}
|
||||
|
||||
return HetznerMetricsLoaded(
|
||||
period: period,
|
||||
start: start,
|
||||
end: end,
|
||||
stepInSeconds: cpuMetricsData['step'],
|
||||
cpu: timeSeriesSerializer(cpuMetricsData, 'cpu'),
|
||||
ppsIn: timeSeriesSerializer(networkMetricsData, 'network.0.pps.in'),
|
||||
ppsOut: timeSeriesSerializer(networkMetricsData, 'network.0.pps.out'),
|
||||
bandwidthIn:
|
||||
timeSeriesSerializer(networkMetricsData, 'network.0.bandwidth.in'),
|
||||
bandwidthOut: timeSeriesSerializer(
|
||||
networkMetricsData,
|
||||
'network.0.bandwidth.out',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
List<TimeSeriesData> timeSeriesSerializer(
|
||||
final Map<String, dynamic> 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();
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
part of 'hetzner_metrics_cubit.dart';
|
||||
|
||||
abstract class HetznerMetricsState extends Equatable {
|
||||
const HetznerMetricsState();
|
||||
|
||||
abstract final Period period;
|
||||
}
|
||||
|
||||
class HetznerMetricsLoading extends HetznerMetricsState {
|
||||
const HetznerMetricsLoading(this.period);
|
||||
@override
|
||||
final Period period;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [period];
|
||||
}
|
||||
|
||||
class HetznerMetricsLoaded extends HetznerMetricsState {
|
||||
const HetznerMetricsLoaded({
|
||||
required this.period,
|
||||
required this.start,
|
||||
required this.end,
|
||||
required this.stepInSeconds,
|
||||
required this.cpu,
|
||||
required this.ppsIn,
|
||||
required this.ppsOut,
|
||||
required this.bandwidthIn,
|
||||
required this.bandwidthOut,
|
||||
});
|
||||
|
||||
@override
|
||||
final Period period;
|
||||
final DateTime start;
|
||||
final DateTime end;
|
||||
final num stepInSeconds;
|
||||
|
||||
final List<TimeSeriesData> cpu;
|
||||
final List<TimeSeriesData> ppsIn;
|
||||
final List<TimeSeriesData> ppsOut;
|
||||
final List<TimeSeriesData> bandwidthIn;
|
||||
final List<TimeSeriesData> bandwidthOut;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [period, start, end];
|
||||
}
|
|
@ -3,16 +3,16 @@ import 'dart:async';
|
|||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
||||
import 'package:selfprivacy/logic/models/hetzner_metrics.dart';
|
||||
import 'package:selfprivacy/logic/models/metrics.dart';
|
||||
|
||||
import 'package:selfprivacy/logic/cubit/hetzner_metrics/hetzner_metrics_repository.dart';
|
||||
import 'package:selfprivacy/logic/cubit/metrics/metrics_repository.dart';
|
||||
|
||||
part 'hetzner_metrics_state.dart';
|
||||
part 'metrics_state.dart';
|
||||
|
||||
class HetznerMetricsCubit extends Cubit<HetznerMetricsState> {
|
||||
HetznerMetricsCubit() : super(const HetznerMetricsLoading(Period.day));
|
||||
class MetricsCubit extends Cubit<MetricsState> {
|
||||
MetricsCubit() : super(const MetricsLoading(Period.day));
|
||||
|
||||
final HetznerMetricsRepository repository = HetznerMetricsRepository();
|
||||
final MetricsRepository repository = MetricsRepository();
|
||||
|
||||
Timer? timer;
|
||||
|
||||
|
@ -30,7 +30,7 @@ class HetznerMetricsCubit extends Cubit<HetznerMetricsState> {
|
|||
|
||||
void changePeriod(final Period period) async {
|
||||
closeTimer();
|
||||
emit(HetznerMetricsLoading(period));
|
||||
emit(MetricsLoading(period));
|
||||
load(period);
|
||||
}
|
||||
|
||||
|
@ -40,14 +40,14 @@ class HetznerMetricsCubit extends Cubit<HetznerMetricsState> {
|
|||
|
||||
void load(final Period period) async {
|
||||
try {
|
||||
final HetznerMetricsLoaded newState = await repository.getMetrics(period);
|
||||
final MetricsLoaded newState = await repository.getMetrics(period);
|
||||
timer = Timer(
|
||||
Duration(seconds: newState.stepInSeconds.toInt()),
|
||||
Duration(seconds: newState.metrics.stepsInSecond.toInt()),
|
||||
() => load(newState.period),
|
||||
);
|
||||
emit(newState);
|
||||
} on StateError {
|
||||
print('Tried to emit Hetzner metrics when cubit is closed');
|
||||
print('Tried to emit metrics when cubit is closed');
|
||||
} on MetricsLoadException {
|
||||
timer = Timer(
|
||||
Duration(seconds: state.period.stepPeriodInSeconds),
|
67
lib/logic/cubit/metrics/metrics_repository.dart
Normal file
67
lib/logic/cubit/metrics/metrics_repository.dart
Normal file
|
@ -0,0 +1,67 @@
|
|||
import 'package:selfprivacy/config/get_it_config.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/api_factory_creator.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/api_factory_settings.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider_factory.dart';
|
||||
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
||||
|
||||
import 'package:selfprivacy/logic/cubit/metrics/metrics_cubit.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
||||
import 'package:selfprivacy/logic/models/metrics.dart';
|
||||
|
||||
class MetricsLoadException implements Exception {
|
||||
MetricsLoadException(this.message);
|
||||
final String message;
|
||||
}
|
||||
|
||||
class MetricsRepository {
|
||||
ServerProviderApiFactory? serverProviderApiFactory;
|
||||
|
||||
void _buildServerProviderFactory() {
|
||||
final ServerProvider? providerType = getIt<ApiConfigModel>().serverProvider;
|
||||
final String? location = getIt<ApiConfigModel>().serverLocation;
|
||||
serverProviderApiFactory = ApiFactoryCreator.createServerProviderApiFactory(
|
||||
ServerProviderApiFactorySettings(
|
||||
provider: providerType ?? ServerProvider.unknown,
|
||||
location: location,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<MetricsLoaded> getMetrics(final Period period) async {
|
||||
if (serverProviderApiFactory == null) {
|
||||
_buildServerProviderFactory();
|
||||
}
|
||||
|
||||
final DateTime end = DateTime.now();
|
||||
DateTime start;
|
||||
|
||||
switch (period) {
|
||||
case Period.hour:
|
||||
start = end.subtract(const Duration(hours: 1));
|
||||
break;
|
||||
case Period.day:
|
||||
start = end.subtract(const Duration(days: 1));
|
||||
break;
|
||||
case Period.month:
|
||||
start = end.subtract(const Duration(days: 15));
|
||||
break;
|
||||
}
|
||||
|
||||
final serverId = getIt<ApiConfigModel>().serverDetails!.id;
|
||||
final ServerMetrics? metrics =
|
||||
await serverProviderApiFactory!.getServerProvider().getMetrics(
|
||||
serverId,
|
||||
start,
|
||||
end,
|
||||
);
|
||||
|
||||
if (metrics == null) {
|
||||
throw MetricsLoadException('Metrics data is null');
|
||||
}
|
||||
|
||||
return MetricsLoaded(
|
||||
period: period,
|
||||
metrics: metrics,
|
||||
);
|
||||
}
|
||||
}
|
31
lib/logic/cubit/metrics/metrics_state.dart
Normal file
31
lib/logic/cubit/metrics/metrics_state.dart
Normal file
|
@ -0,0 +1,31 @@
|
|||
part of 'metrics_cubit.dart';
|
||||
|
||||
abstract class MetricsState extends Equatable {
|
||||
const MetricsState();
|
||||
|
||||
abstract final Period period;
|
||||
}
|
||||
|
||||
class MetricsLoading extends MetricsState {
|
||||
const MetricsLoading(this.period);
|
||||
@override
|
||||
final Period period;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [period];
|
||||
}
|
||||
|
||||
class MetricsLoaded extends MetricsState {
|
||||
const MetricsLoaded({
|
||||
required this.period,
|
||||
required this.metrics,
|
||||
});
|
||||
|
||||
@override
|
||||
final Period period;
|
||||
|
||||
final ServerMetrics metrics;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [period, metrics];
|
||||
}
|
|
@ -98,13 +98,13 @@ class ApiProviderVolumeCubit
|
|||
}
|
||||
|
||||
getIt<NavigationService>().showSnackBar(
|
||||
'Hetzner resized, waiting 10 seconds',
|
||||
'Provider volume resized, waiting 10 seconds',
|
||||
);
|
||||
await Future.delayed(const Duration(seconds: 10));
|
||||
|
||||
await ServerApi().resizeVolume(volume.name);
|
||||
getIt<NavigationService>().showSnackBar(
|
||||
'Server api resized, waiting 20 seconds',
|
||||
'Server volume resized, waiting 20 seconds',
|
||||
);
|
||||
|
||||
await Future.delayed(const Duration(seconds: 20));
|
||||
|
|
|
@ -305,14 +305,13 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
|||
),
|
||||
);
|
||||
timer = Timer(pauseDuration, () async {
|
||||
final ServerHostingDetails hetznerServerDetails =
|
||||
await repository.restart();
|
||||
final ServerHostingDetails serverDetails = await repository.restart();
|
||||
await repository.saveIsServerResetedFirstTime(true);
|
||||
await repository.saveServerDetails(hetznerServerDetails);
|
||||
await repository.saveServerDetails(serverDetails);
|
||||
|
||||
final ServerInstallationNotFinished newState = dataState.copyWith(
|
||||
isServerResetedFirstTime: true,
|
||||
serverDetails: hetznerServerDetails,
|
||||
serverDetails: serverDetails,
|
||||
isLoading: false,
|
||||
);
|
||||
|
||||
|
@ -347,14 +346,13 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
|||
),
|
||||
);
|
||||
timer = Timer(pauseDuration, () async {
|
||||
final ServerHostingDetails hetznerServerDetails =
|
||||
await repository.restart();
|
||||
final ServerHostingDetails serverDetails = await repository.restart();
|
||||
await repository.saveIsServerResetedSecondTime(true);
|
||||
await repository.saveServerDetails(hetznerServerDetails);
|
||||
await repository.saveServerDetails(serverDetails);
|
||||
|
||||
final ServerInstallationNotFinished newState = dataState.copyWith(
|
||||
isServerResetedSecondTime: true,
|
||||
serverDetails: hetznerServerDetails,
|
||||
serverDetails: serverDetails,
|
||||
isLoading: false,
|
||||
);
|
||||
|
||||
|
@ -560,8 +558,7 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
|||
}
|
||||
}
|
||||
|
||||
Future<List<ServerBasicInfoWithValidators>>
|
||||
getServersOnHetznerAccount() async {
|
||||
Future<List<ServerBasicInfoWithValidators>> getAvailableServers() async {
|
||||
final ServerInstallationRecovery dataState =
|
||||
state as ServerInstallationRecovery;
|
||||
final List<ServerBasicInfo> servers =
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
class TimeSeriesData {
|
||||
TimeSeriesData(
|
||||
this.secondsSinceEpoch,
|
||||
this.value,
|
||||
);
|
||||
|
||||
final int secondsSinceEpoch;
|
||||
DateTime get time =>
|
||||
DateTime.fromMillisecondsSinceEpoch(secondsSinceEpoch * 1000);
|
||||
final double value;
|
||||
}
|
34
lib/logic/models/metrics.dart
Normal file
34
lib/logic/models/metrics.dart
Normal file
|
@ -0,0 +1,34 @@
|
|||
class TimeSeriesData {
|
||||
TimeSeriesData(
|
||||
this.secondsSinceEpoch,
|
||||
this.value,
|
||||
);
|
||||
|
||||
final int secondsSinceEpoch;
|
||||
DateTime get time =>
|
||||
DateTime.fromMillisecondsSinceEpoch(secondsSinceEpoch * 1000);
|
||||
final double value;
|
||||
}
|
||||
|
||||
class ServerMetrics {
|
||||
ServerMetrics({
|
||||
required this.stepsInSecond,
|
||||
required this.cpu,
|
||||
required this.ppsIn,
|
||||
required this.ppsOut,
|
||||
required this.bandwidthIn,
|
||||
required this.bandwidthOut,
|
||||
required this.start,
|
||||
required this.end,
|
||||
});
|
||||
|
||||
final num stepsInSecond;
|
||||
final List<TimeSeriesData> cpu;
|
||||
final List<TimeSeriesData> ppsIn;
|
||||
final List<TimeSeriesData> ppsOut;
|
||||
final List<TimeSeriesData> bandwidthIn;
|
||||
final List<TimeSeriesData> bandwidthOut;
|
||||
|
||||
final DateTime start;
|
||||
final DateTime end;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
||||
import 'package:selfprivacy/logic/models/hetzner_metrics.dart';
|
||||
import 'package:selfprivacy/logic/models/metrics.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
String bottomTitle(
|
||||
|
|
|
@ -3,11 +3,11 @@ part of '../server_details_screen.dart';
|
|||
class _Chart extends StatelessWidget {
|
||||
@override
|
||||
Widget build(final BuildContext context) {
|
||||
final HetznerMetricsCubit cubit = context.watch<HetznerMetricsCubit>();
|
||||
final MetricsCubit cubit = context.watch<MetricsCubit>();
|
||||
final Period period = cubit.state.period;
|
||||
final HetznerMetricsState state = cubit.state;
|
||||
final MetricsState state = cubit.state;
|
||||
List<Widget> charts;
|
||||
if (state is HetznerMetricsLoaded || state is HetznerMetricsLoading) {
|
||||
if (state is MetricsLoaded || state is MetricsLoading) {
|
||||
charts = [
|
||||
FilledCard(
|
||||
clipped: false,
|
||||
|
@ -26,10 +26,10 @@ class _Chart extends StatelessWidget {
|
|||
Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
if (state is HetznerMetricsLoaded) getCpuChart(state),
|
||||
if (state is MetricsLoaded) getCpuChart(state),
|
||||
AnimatedOpacity(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
opacity: state is HetznerMetricsLoading ? 1 : 0,
|
||||
opacity: state is MetricsLoading ? 1 : 0,
|
||||
child: const _GraphLoadingCardContent(),
|
||||
),
|
||||
],
|
||||
|
@ -72,10 +72,10 @@ class _Chart extends StatelessWidget {
|
|||
Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
if (state is HetznerMetricsLoaded) getBandwidthChart(state),
|
||||
if (state is MetricsLoaded) getBandwidthChart(state),
|
||||
AnimatedOpacity(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
opacity: state is HetznerMetricsLoading ? 1 : 0,
|
||||
opacity: state is MetricsLoading ? 1 : 0,
|
||||
child: const _GraphLoadingCardContent(),
|
||||
),
|
||||
],
|
||||
|
@ -122,29 +122,29 @@ class _Chart extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
Widget getCpuChart(final HetznerMetricsLoaded state) {
|
||||
final data = state.cpu;
|
||||
Widget getCpuChart(final MetricsLoaded state) {
|
||||
final data = state.metrics.cpu;
|
||||
|
||||
return SizedBox(
|
||||
height: 200,
|
||||
child: CpuChart(
|
||||
data: data,
|
||||
period: state.period,
|
||||
start: state.start,
|
||||
start: state.metrics.start,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getBandwidthChart(final HetznerMetricsLoaded state) {
|
||||
final ppsIn = state.bandwidthIn;
|
||||
final ppsOut = state.bandwidthOut;
|
||||
Widget getBandwidthChart(final MetricsLoaded state) {
|
||||
final ppsIn = state.metrics.bandwidthIn;
|
||||
final ppsOut = state.metrics.bandwidthOut;
|
||||
|
||||
return SizedBox(
|
||||
height: 200,
|
||||
child: NetworkChart(
|
||||
listData: [ppsIn, ppsOut],
|
||||
period: state.period,
|
||||
start: state.start,
|
||||
start: state.metrics.start,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:fl_chart/fl_chart.dart';
|
||||
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
||||
import 'package:selfprivacy/logic/models/hetzner_metrics.dart';
|
||||
import 'package:selfprivacy/logic/models/metrics.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:selfprivacy/ui/pages/server_details/charts/bottom_title.dart';
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:fl_chart/fl_chart.dart';
|
||||
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
||||
import 'package:selfprivacy/logic/models/disk_size.dart';
|
||||
import 'package:selfprivacy/logic/models/hetzner_metrics.dart';
|
||||
import 'package:selfprivacy/logic/models/metrics.dart';
|
||||
import 'package:selfprivacy/ui/pages/server_details/charts/bottom_title.dart';
|
||||
|
||||
class NetworkChart extends StatelessWidget {
|
||||
|
|
|
@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:selfprivacy/config/brand_colors.dart';
|
||||
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
||||
import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/hetzner_metrics/hetzner_metrics_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/metrics/metrics_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_detailed_info/server_detailed_info_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_volumes/server_volume_cubit.dart';
|
||||
|
@ -22,7 +22,6 @@ import 'package:selfprivacy/ui/pages/server_details/charts/cpu_chart.dart';
|
|||
import 'package:selfprivacy/ui/pages/server_details/charts/network_charts.dart';
|
||||
import 'package:selfprivacy/ui/pages/server_storage/storage_card.dart';
|
||||
import 'package:selfprivacy/utils/extensions/duration.dart';
|
||||
import 'package:selfprivacy/utils/extensions/string_extensions.dart';
|
||||
import 'package:selfprivacy/utils/named_font_weight.dart';
|
||||
import 'package:selfprivacy/utils/route_transitions/basic.dart';
|
||||
import 'package:timezone/timezone.dart';
|
||||
|
@ -93,7 +92,7 @@ class _ServerDetailsScreenState extends State<ServerDetailsScreen>
|
|||
),
|
||||
const SizedBox(height: 8),
|
||||
BlocProvider(
|
||||
create: (final context) => HetznerMetricsCubit()..restart(),
|
||||
create: (final context) => MetricsCubit()..restart(),
|
||||
child: _Chart(),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
|
|
@ -45,9 +45,8 @@ class _RecoveryConfirmServerState extends State<RecoveryConfirmServer> {
|
|||
hasFlashButton: false,
|
||||
children: [
|
||||
FutureBuilder<List<ServerBasicInfoWithValidators>>(
|
||||
future: context
|
||||
.read<ServerInstallationCubit>()
|
||||
.getServersOnHetznerAccount(),
|
||||
future:
|
||||
context.read<ServerInstallationCubit>().getAvailableServers(),
|
||||
builder: (final context, final snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
final servers = snapshot.data;
|
||||
|
|
Loading…
Reference in a new issue