mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-03-12 01:34:10 +00:00
Implement ServerJob cubit
This commit is contained in:
parent
7bbdaf2ebe
commit
37d5ee9913
11 changed files with 258 additions and 207 deletions
lib
config
logic/cubit
provider_volumes
server_installation
server_volumes
volumes
ui/pages
providers
server_storage
|
@ -10,7 +10,7 @@ import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/providers/providers_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/providers/providers_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/services/services_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/services/services_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/users/users_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/users/users_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/volumes/volumes_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/provider_volumes/provider_volume_cubit.dart';
|
||||||
|
|
||||||
class BlocAndProviderConfig extends StatelessWidget {
|
class BlocAndProviderConfig extends StatelessWidget {
|
||||||
const BlocAndProviderConfig({final super.key, this.child});
|
const BlocAndProviderConfig({final super.key, this.child});
|
||||||
|
@ -27,7 +27,7 @@ class BlocAndProviderConfig extends StatelessWidget {
|
||||||
final dnsRecordsCubit = DnsRecordsCubit(serverInstallationCubit);
|
final dnsRecordsCubit = DnsRecordsCubit(serverInstallationCubit);
|
||||||
final recoveryKeyCubit = RecoveryKeyCubit(serverInstallationCubit);
|
final recoveryKeyCubit = RecoveryKeyCubit(serverInstallationCubit);
|
||||||
final apiDevicesCubit = ApiDevicesCubit(serverInstallationCubit);
|
final apiDevicesCubit = ApiDevicesCubit(serverInstallationCubit);
|
||||||
final apiVolumesCubit = ApiVolumesCubit(serverInstallationCubit);
|
final apiVolumesCubit = ApiProviderVolumeCubit(serverInstallationCubit);
|
||||||
return MultiProvider(
|
return MultiProvider(
|
||||||
providers: [
|
providers: [
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
|
|
108
lib/logic/cubit/provider_volumes/provider_volume_cubit.dart
Normal file
108
lib/logic/cubit/provider_volumes/provider_volume_cubit.dart
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
import 'package:selfprivacy/config/get_it_config.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/server.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/api_factory_creator.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/app_config_dependent/authentication_dependend_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/json/server_disk_volume.dart';
|
||||||
|
import 'package:selfprivacy/ui/pages/server_storage/disk_status.dart';
|
||||||
|
|
||||||
|
part 'provider_volume_state.dart';
|
||||||
|
|
||||||
|
class ApiProviderVolumeCubit
|
||||||
|
extends ServerInstallationDependendCubit<ApiProviderVolumeState> {
|
||||||
|
ApiProviderVolumeCubit(final ServerInstallationCubit serverInstallationCubit)
|
||||||
|
: super(serverInstallationCubit, const ApiProviderVolumeState.initial()) {
|
||||||
|
final serverDetails = getIt<ApiConfigModel>().serverDetails;
|
||||||
|
providerApi = serverDetails == null
|
||||||
|
? null
|
||||||
|
: VolumeApiFactoryCreator.createVolumeProviderApiFactory(
|
||||||
|
getIt<ApiConfigModel>().serverDetails!.provider,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
VolumeProviderApiFactory? providerApi;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> load() async {
|
||||||
|
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
||||||
|
_refetch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<double?> getPricePerGb() async =>
|
||||||
|
providerApi!.getVolumeProvider().getPricePerGb();
|
||||||
|
|
||||||
|
Future<void> refresh() async {
|
||||||
|
emit(const ApiProviderVolumeState([], LoadingStatus.refreshing));
|
||||||
|
_refetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _refetch() async {
|
||||||
|
if (providerApi == null) {
|
||||||
|
return emit(const ApiProviderVolumeState([], LoadingStatus.error));
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<ServerVolume> volumes =
|
||||||
|
await providerApi!.getVolumeProvider().getVolumes();
|
||||||
|
|
||||||
|
if (volumes.isEmpty) {
|
||||||
|
return emit(const ApiProviderVolumeState([], LoadingStatus.error));
|
||||||
|
}
|
||||||
|
|
||||||
|
emit(ApiProviderVolumeState(volumes, LoadingStatus.success));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> attachVolume(final ServerVolume volume) async {
|
||||||
|
final ServerHostingDetails server = getIt<ApiConfigModel>().serverDetails!;
|
||||||
|
await providerApi!.getVolumeProvider().attachVolume(volume.id, server.id);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> detachVolume(final ServerVolume volume) async {
|
||||||
|
await providerApi!.getVolumeProvider().detachVolume(volume.id);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> resizeVolume(
|
||||||
|
final DiskVolume volume,
|
||||||
|
final int newSizeGb,
|
||||||
|
) async {
|
||||||
|
final bool resized = await providerApi!.getVolumeProvider().resizeVolume(
|
||||||
|
volume.providerVolume!.id,
|
||||||
|
newSizeGb,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!resized) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
await ServerApi().resizeVolume(volume.name);
|
||||||
|
refresh();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> createVolume() async {
|
||||||
|
final ServerVolume? volume =
|
||||||
|
await providerApi!.getVolumeProvider().createVolume();
|
||||||
|
await attachVolume(volume!);
|
||||||
|
|
||||||
|
await Future.delayed(const Duration(seconds: 10));
|
||||||
|
|
||||||
|
await ServerApi().mountVolume(volume.name);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> deleteVolume(final DiskVolume volume) async {
|
||||||
|
await providerApi!
|
||||||
|
.getVolumeProvider()
|
||||||
|
.deleteVolume(volume.providerVolume!.id);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void clear() {
|
||||||
|
emit(const ApiProviderVolumeState.initial());
|
||||||
|
}
|
||||||
|
}
|
24
lib/logic/cubit/provider_volumes/provider_volume_state.dart
Normal file
24
lib/logic/cubit/provider_volumes/provider_volume_state.dart
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
part of 'provider_volume_cubit.dart';
|
||||||
|
|
||||||
|
class ApiProviderVolumeState extends ServerInstallationDependendState {
|
||||||
|
const ApiProviderVolumeState(this._volumes, this.status);
|
||||||
|
|
||||||
|
const ApiProviderVolumeState.initial()
|
||||||
|
: this(const [], LoadingStatus.uninitialized);
|
||||||
|
final List<ServerVolume> _volumes;
|
||||||
|
final LoadingStatus status;
|
||||||
|
|
||||||
|
List<ServerVolume> get volumes => _volumes;
|
||||||
|
|
||||||
|
ApiProviderVolumeState copyWith({
|
||||||
|
final List<ServerVolume>? volumes,
|
||||||
|
final LoadingStatus? status,
|
||||||
|
}) =>
|
||||||
|
ApiProviderVolumeState(
|
||||||
|
volumes ?? _volumes,
|
||||||
|
status ?? this.status,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [_volumes];
|
||||||
|
}
|
|
@ -554,9 +554,6 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<ServerDiskVolume>> getServerDiskVolumes() async =>
|
|
||||||
ServerApi().getServerDiskVolumes();
|
|
||||||
|
|
||||||
Future<void> setAndValidateCloudflareToken(final String token) async {
|
Future<void> setAndValidateCloudflareToken(final String token) async {
|
||||||
final ServerInstallationRecovery dataState =
|
final ServerInstallationRecovery dataState =
|
||||||
state as ServerInstallationRecovery;
|
state as ServerInstallationRecovery;
|
||||||
|
|
36
lib/logic/cubit/server_volumes/server_volume_cubit.dart
Normal file
36
lib/logic/cubit/server_volumes/server_volume_cubit.dart
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/server.dart';
|
||||||
|
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/json/server_disk_volume.dart';
|
||||||
|
|
||||||
|
part 'server_volume_state.dart';
|
||||||
|
|
||||||
|
class ApiServerVolumeCubit
|
||||||
|
extends ServerInstallationDependendCubit<ApiServerVolumeState> {
|
||||||
|
ApiServerVolumeCubit(final ServerInstallationCubit serverInstallationCubit)
|
||||||
|
: super(serverInstallationCubit, const ApiServerVolumeState.initial());
|
||||||
|
|
||||||
|
final ServerApi serverApi = ServerApi();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> load() async {
|
||||||
|
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
||||||
|
_refetch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _refetch() async {
|
||||||
|
final List<ServerDiskVolume> volumes =
|
||||||
|
await serverApi.getServerDiskVolumes();
|
||||||
|
if (volumes.isNotEmpty) {
|
||||||
|
emit(ApiServerVolumeState(volumes, LoadingStatus.success));
|
||||||
|
} else {
|
||||||
|
emit(const ApiServerVolumeState([], LoadingStatus.error));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void clear() {
|
||||||
|
emit(const ApiServerVolumeState.initial());
|
||||||
|
}
|
||||||
|
}
|
24
lib/logic/cubit/server_volumes/server_volume_state.dart
Normal file
24
lib/logic/cubit/server_volumes/server_volume_state.dart
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
part of 'server_volume_cubit.dart';
|
||||||
|
|
||||||
|
class ApiServerVolumeState extends ServerInstallationDependendState {
|
||||||
|
const ApiServerVolumeState(this._volumes, this.status);
|
||||||
|
|
||||||
|
const ApiServerVolumeState.initial()
|
||||||
|
: this(const [], LoadingStatus.uninitialized);
|
||||||
|
final List<ServerDiskVolume> _volumes;
|
||||||
|
final LoadingStatus status;
|
||||||
|
|
||||||
|
List<ServerDiskVolume> get volumes => _volumes;
|
||||||
|
|
||||||
|
ApiServerVolumeState copyWith({
|
||||||
|
final List<ServerDiskVolume>? volumes,
|
||||||
|
final LoadingStatus? status,
|
||||||
|
}) =>
|
||||||
|
ApiServerVolumeState(
|
||||||
|
volumes ?? _volumes,
|
||||||
|
status ?? this.status,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [_volumes];
|
||||||
|
}
|
|
@ -1,160 +0,0 @@
|
||||||
import 'package:selfprivacy/config/get_it_config.dart';
|
|
||||||
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/server.dart';
|
|
||||||
import 'package:selfprivacy/logic/api_maps/rest_maps/api_factory_creator.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/app_config_dependent/authentication_dependend_cubit.dart';
|
|
||||||
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
|
||||||
import 'package:selfprivacy/logic/models/json/server_disk_volume.dart';
|
|
||||||
|
|
||||||
part 'volumes_state.dart';
|
|
||||||
|
|
||||||
class ApiVolumesCubit
|
|
||||||
extends ServerInstallationDependendCubit<ApiVolumesState> {
|
|
||||||
ApiVolumesCubit(final ServerInstallationCubit serverInstallationCubit)
|
|
||||||
: super(serverInstallationCubit, const ApiVolumesState.initial()) {
|
|
||||||
final serverDetails = getIt<ApiConfigModel>().serverDetails;
|
|
||||||
providerApi = serverDetails == null
|
|
||||||
? null
|
|
||||||
: VolumeApiFactoryCreator.createVolumeProviderApiFactory(
|
|
||||||
getIt<ApiConfigModel>().serverDetails!.provider,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
VolumeProviderApiFactory? providerApi;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> load() async {
|
|
||||||
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
|
||||||
_refetch();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<List<ServerVolume>> getVolumes() async {
|
|
||||||
if (providerApi == null) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return providerApi!.getVolumeProvider().getVolumes();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<double?> getPricePerGb() async =>
|
|
||||||
providerApi!.getVolumeProvider().getPricePerGb();
|
|
||||||
|
|
||||||
Future<void> refresh() async {
|
|
||||||
emit(const ApiVolumesState([], LoadingStatus.refreshing));
|
|
||||||
_refetch();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _refetch() async {
|
|
||||||
final List<ServerVolume> volumes = await getVolumes();
|
|
||||||
if (volumes.isNotEmpty) {
|
|
||||||
emit(ApiVolumesState(volumes, LoadingStatus.success));
|
|
||||||
} else {
|
|
||||||
emit(const ApiVolumesState([], LoadingStatus.error));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> attachVolume(final ServerVolume volume) async {
|
|
||||||
final ServerHostingDetails server = getIt<ApiConfigModel>().serverDetails!;
|
|
||||||
await providerApi!.getVolumeProvider().attachVolume(volume.id, server.id);
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> detachVolume(final ServerVolume volume) async {
|
|
||||||
await providerApi!.getVolumeProvider().detachVolume(volume.id);
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> resizeVolume(
|
|
||||||
final ServerDiskVolume volume,
|
|
||||||
final int newSizeGb,
|
|
||||||
) async {
|
|
||||||
final ServerVolume? providerVolume = await fetchProdiverVolume(volume);
|
|
||||||
final bool resized = await providerApi!.getVolumeProvider().resizeVolume(
|
|
||||||
providerVolume!.id,
|
|
||||||
newSizeGb,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!resized) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
await ServerApi().resizeVolume(volume.name);
|
|
||||||
refresh();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> createVolume() async {
|
|
||||||
final ServerVolume? volume =
|
|
||||||
await providerApi!.getVolumeProvider().createVolume();
|
|
||||||
await attachVolume(volume!);
|
|
||||||
|
|
||||||
await Future.delayed(const Duration(seconds: 10));
|
|
||||||
|
|
||||||
final ServerDiskVolume? diskVolume = await fetchServerDiskVolume(volume);
|
|
||||||
await ServerApi().mountVolume(diskVolume!.name);
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> deleteVolume(final ServerDiskVolume volume) async {
|
|
||||||
final ServerVolume? providerVolume = await fetchProdiverVolume(volume);
|
|
||||||
await providerApi!.getVolumeProvider().deleteVolume(providerVolume!.id);
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void clear() {
|
|
||||||
emit(const ApiVolumesState.initial());
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ServerVolume?> fetchProdiverVolume(
|
|
||||||
final ServerDiskVolume volume,
|
|
||||||
) async {
|
|
||||||
ServerVolume? fetchedVolume;
|
|
||||||
final List<ServerVolume> volumes =
|
|
||||||
await providerApi!.getVolumeProvider().getVolumes();
|
|
||||||
|
|
||||||
for (final ServerVolume providerVolume in volumes) {
|
|
||||||
if (providerVolume.linuxDevice == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String deviceId = providerVolume.linuxDevice!.split('/').last;
|
|
||||||
if (deviceId.contains(volume.model!) &&
|
|
||||||
deviceId.contains(volume.serial!)) {
|
|
||||||
fetchedVolume = providerVolume;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return fetchedVolume;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<ServerDiskVolume?> fetchServerDiskVolume(
|
|
||||||
final ServerVolume volume,
|
|
||||||
) async {
|
|
||||||
ServerDiskVolume? fetchedVolume;
|
|
||||||
if (volume.linuxDevice == null) {
|
|
||||||
return fetchedVolume;
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<ServerDiskVolume> volumes =
|
|
||||||
await ServerApi().getServerDiskVolumes();
|
|
||||||
|
|
||||||
for (final ServerDiskVolume serverDiskVolumes in volumes) {
|
|
||||||
if (serverDiskVolumes.model == null || serverDiskVolumes.serial == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String deviceId = volume.linuxDevice!.split('/').last;
|
|
||||||
if (deviceId.contains(serverDiskVolumes.model!) &&
|
|
||||||
deviceId.contains(serverDiskVolumes.serial!)) {
|
|
||||||
fetchedVolume = serverDiskVolumes;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return fetchedVolume;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
part of 'volumes_cubit.dart';
|
|
||||||
|
|
||||||
class ApiVolumesState extends ServerInstallationDependendState {
|
|
||||||
const ApiVolumesState(this._volumes, this.status);
|
|
||||||
|
|
||||||
const ApiVolumesState.initial() : this(const [], LoadingStatus.uninitialized);
|
|
||||||
final List<ServerVolume> _volumes;
|
|
||||||
final LoadingStatus status;
|
|
||||||
|
|
||||||
List<ServerVolume> get volumes => _volumes;
|
|
||||||
|
|
||||||
ApiVolumesState copyWith({
|
|
||||||
final List<ServerVolume>? volumes,
|
|
||||||
final LoadingStatus? status,
|
|
||||||
}) =>
|
|
||||||
ApiVolumesState(
|
|
||||||
volumes ?? _volumes,
|
|
||||||
status ?? this.status,
|
|
||||||
);
|
|
||||||
|
|
||||||
@override
|
|
||||||
List<Object?> get props => [_volumes];
|
|
||||||
}
|
|
|
@ -5,7 +5,8 @@ import 'package:selfprivacy/logic/cubit/backups/backups_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/dns_records/dns_records_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/dns_records/dns_records_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/providers/providers_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/providers/providers_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/volumes/volumes_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/provider_volumes/provider_volume_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/server_volumes/server_volume_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/models/disk_size.dart';
|
import 'package:selfprivacy/logic/models/disk_size.dart';
|
||||||
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
||||||
import 'package:selfprivacy/logic/models/json/server_disk_volume.dart';
|
import 'package:selfprivacy/logic/models/json/server_disk_volume.dart';
|
||||||
|
@ -76,22 +77,10 @@ class _ProvidersPageState extends State<ProvidersPage> {
|
||||||
cards.add(
|
cards.add(
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 30),
|
padding: const EdgeInsets.only(bottom: 30),
|
||||||
child: FutureBuilder(
|
child: StorageCard(
|
||||||
future: Future.wait([
|
diskStatus: toDiskStatus(
|
||||||
context.read<ServerInstallationCubit>().getServerDiskVolumes(),
|
context.read<ApiServerVolumeCubit>().state.volumes,
|
||||||
context.read<ApiVolumesCubit>().getVolumes(),
|
context.read<ApiProviderVolumeCubit>().state.volumes,
|
||||||
]),
|
|
||||||
builder: (
|
|
||||||
final BuildContext context,
|
|
||||||
final AsyncSnapshot<List<dynamic>> snapshot,
|
|
||||||
) =>
|
|
||||||
StorageCard(
|
|
||||||
diskStatus: snapshot.hasData
|
|
||||||
? toDiskStatus(
|
|
||||||
snapshot.data![0] as List<ServerDiskVolume>,
|
|
||||||
snapshot.data![1] as List<ServerVolume>,
|
|
||||||
)
|
|
||||||
: DiskStatus(),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/volumes/volumes_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/provider_volumes/provider_volume_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/models/disk_size.dart';
|
import 'package:selfprivacy/logic/models/disk_size.dart';
|
||||||
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_hero_screen/brand_hero_screen.dart';
|
import 'package:selfprivacy/ui/components/brand_hero_screen/brand_hero_screen.dart';
|
||||||
|
@ -39,7 +39,7 @@ class _ExtendingVolumePageState extends State<ExtendingVolumePage> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(final BuildContext context) => FutureBuilder(
|
Widget build(final BuildContext context) => FutureBuilder(
|
||||||
future: context.read<ApiVolumesCubit>().getPricePerGb(),
|
future: context.read<ApiProviderVolumeCubit>().getPricePerGb(),
|
||||||
builder: (
|
builder: (
|
||||||
final BuildContext context,
|
final BuildContext context,
|
||||||
final AsyncSnapshot<void> snapshot,
|
final AsyncSnapshot<void> snapshot,
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:selfprivacy/ui/components/brand_linear_indicator/brand_linear_indicator.dart';
|
||||||
|
|
||||||
|
class ServiceStorageConsumptionListItem extends StatelessWidget {
|
||||||
|
const ServiceStorageConsumptionListItem({
|
||||||
|
required this.title,
|
||||||
|
required this.percentage,
|
||||||
|
required this.storageConsumptionText,
|
||||||
|
required this.color,
|
||||||
|
required this.icon,
|
||||||
|
final super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String title;
|
||||||
|
final double percentage;
|
||||||
|
final String storageConsumptionText;
|
||||||
|
final Color color;
|
||||||
|
final IconData icon;
|
||||||
|
@override
|
||||||
|
Widget build(final BuildContext context) => Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
icon,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
title,
|
||||||
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
storageConsumptionText,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
BrandLinearIndicator(
|
||||||
|
value: percentage,
|
||||||
|
color: color,
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.surfaceVariant,
|
||||||
|
height: 7.0,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue