mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-08 17:11:14 +00:00
refactor: Introduce VolumesBloc, remove ServerVolumeCubit
This commit is contained in:
parent
3222a9b500
commit
3b9d616045
|
@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||
import 'package:selfprivacy/logic/bloc/backups/backups_bloc.dart';
|
||||
import 'package:selfprivacy/logic/bloc/server_jobs/server_jobs_bloc.dart';
|
||||
import 'package:selfprivacy/logic/bloc/services/services_bloc.dart';
|
||||
import 'package:selfprivacy/logic/bloc/volumes/volumes_bloc.dart';
|
||||
import 'package:selfprivacy/logic/cubit/app_settings/app_settings_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/connection_status/connection_status_bloc.dart';
|
||||
|
@ -12,7 +13,6 @@ import 'package:selfprivacy/logic/cubit/provider_volumes/provider_volume_cubit.d
|
|||
import 'package:selfprivacy/logic/cubit/recovery_key/recovery_key_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';
|
||||
import 'package:selfprivacy/logic/cubit/support_system/support_system_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/users/users_cubit.dart';
|
||||
|
||||
|
@ -34,11 +34,11 @@ class BlocAndProviderConfigState extends State<BlocAndProviderConfig> {
|
|||
late final DnsRecordsCubit dnsRecordsCubit;
|
||||
late final RecoveryKeyCubit recoveryKeyCubit;
|
||||
late final ApiDevicesCubit apiDevicesCubit;
|
||||
late final ApiProviderVolumeCubit apiVolumesCubit;
|
||||
late final ApiServerVolumeCubit apiServerVolumesCubit;
|
||||
late final ProviderVolumeCubit apiVolumesCubit;
|
||||
late final ServerJobsBloc serverJobsBloc;
|
||||
late final ConnectionStatusBloc connectionStatusBloc;
|
||||
late final ServerDetailsCubit serverDetailsCubit;
|
||||
late final VolumesBloc volumesBloc;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -51,11 +51,11 @@ class BlocAndProviderConfigState extends State<BlocAndProviderConfig> {
|
|||
dnsRecordsCubit = DnsRecordsCubit();
|
||||
recoveryKeyCubit = RecoveryKeyCubit();
|
||||
apiDevicesCubit = ApiDevicesCubit();
|
||||
apiVolumesCubit = ApiProviderVolumeCubit();
|
||||
apiServerVolumesCubit = ApiServerVolumeCubit(apiVolumesCubit);
|
||||
apiVolumesCubit = ProviderVolumeCubit();
|
||||
serverJobsBloc = ServerJobsBloc();
|
||||
connectionStatusBloc = ConnectionStatusBloc();
|
||||
serverDetailsCubit = ServerDetailsCubit();
|
||||
volumesBloc = VolumesBloc();
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -101,9 +101,6 @@ class BlocAndProviderConfigState extends State<BlocAndProviderConfig> {
|
|||
BlocProvider(
|
||||
create: (final _) => apiVolumesCubit,
|
||||
),
|
||||
BlocProvider(
|
||||
create: (final _) => apiServerVolumesCubit,
|
||||
),
|
||||
BlocProvider(
|
||||
create: (final _) => serverJobsBloc,
|
||||
),
|
||||
|
@ -111,6 +108,7 @@ class BlocAndProviderConfigState extends State<BlocAndProviderConfig> {
|
|||
BlocProvider(
|
||||
create: (final _) => serverDetailsCubit,
|
||||
),
|
||||
BlocProvider(create: (final _) => volumesBloc),
|
||||
BlocProvider(
|
||||
create: (final _) => JobsCubit(
|
||||
usersCubit: usersCubit,
|
||||
|
|
|
@ -11,6 +11,7 @@ mixin VolumeApi on GraphQLApiMap {
|
|||
if (response.hasException) {
|
||||
print(response.exception.toString());
|
||||
}
|
||||
// TODO: Rewrite to use fromGraphQL
|
||||
volumes = response.data!['storage']['volumes']
|
||||
.map<ServerDiskVolume>((final e) => ServerDiskVolume.fromJson(e))
|
||||
.toList();
|
||||
|
|
163
lib/logic/bloc/volumes/volumes_bloc.dart
Normal file
163
lib/logic/bloc/volumes/volumes_bloc.dart
Normal file
|
@ -0,0 +1,163 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:bloc_concurrency/bloc_concurrency.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:selfprivacy/config/get_it_config.dart';
|
||||
import 'package:selfprivacy/logic/models/disk_status.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/price.dart';
|
||||
import 'package:selfprivacy/logic/providers/providers_controller.dart';
|
||||
|
||||
part 'volumes_event.dart';
|
||||
part 'volumes_state.dart';
|
||||
|
||||
class VolumesBloc extends Bloc<VolumesEvent, VolumesState> {
|
||||
VolumesBloc() : super(VolumesInitial()) {
|
||||
on<VolumesServerLoaded>(
|
||||
_loadState,
|
||||
transformer: droppable(),
|
||||
);
|
||||
on<VolumesServerReset>(
|
||||
_resetState,
|
||||
transformer: droppable(),
|
||||
);
|
||||
on<VolumesServerStateChanged>(
|
||||
_updateState,
|
||||
transformer: droppable(),
|
||||
);
|
||||
|
||||
final connectionRepository = getIt<ApiConnectionRepository>();
|
||||
|
||||
_apiStatusSubscription = connectionRepository.connectionStatusStream
|
||||
.listen((final ConnectionStatus connectionStatus) {
|
||||
switch (connectionStatus) {
|
||||
case ConnectionStatus.nonexistent:
|
||||
add(const VolumesServerReset());
|
||||
isLoaded = false;
|
||||
break;
|
||||
case ConnectionStatus.connected:
|
||||
if (!isLoaded) {
|
||||
add(const VolumesServerLoaded());
|
||||
isLoaded = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
_apiDataSubscription = connectionRepository.dataStream.listen(
|
||||
(final ApiData apiData) {
|
||||
if (apiData.volumes.data == null) {
|
||||
add(const VolumesServerReset());
|
||||
} else {
|
||||
add(
|
||||
VolumesServerStateChanged(
|
||||
apiData.volumes.data!,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
late StreamSubscription _apiStatusSubscription;
|
||||
late StreamSubscription _apiDataSubscription;
|
||||
bool isLoaded = false;
|
||||
|
||||
Future<Price?> getPricePerGb() async {
|
||||
if (ProvidersController.currentServerProvider == null) {
|
||||
return null;
|
||||
}
|
||||
Price? price;
|
||||
final pricingResult =
|
||||
await ProvidersController.currentServerProvider!.getAdditionalPricing();
|
||||
if (pricingResult.data == null || !pricingResult.success) {
|
||||
getIt<NavigationService>().showSnackBar('server.pricing_error'.tr());
|
||||
return price;
|
||||
}
|
||||
price = pricingResult.data!.perVolumeGb;
|
||||
return price;
|
||||
}
|
||||
|
||||
Future<void> _loadState(
|
||||
final VolumesServerLoaded event,
|
||||
final Emitter<VolumesState> emit,
|
||||
) async {
|
||||
if (ProvidersController.currentServerProvider == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
emit(VolumesLoading());
|
||||
|
||||
final volumesResult =
|
||||
await ProvidersController.currentServerProvider!.getVolumes();
|
||||
|
||||
if (!volumesResult.success || volumesResult.data.isEmpty) {
|
||||
emit(VolumesInitial());
|
||||
return;
|
||||
}
|
||||
|
||||
final serverVolumes = getIt<ApiConnectionRepository>().apiData.volumes.data;
|
||||
|
||||
if (serverVolumes == null) {
|
||||
emit(VolumesLoading(providerVolumes: volumesResult.data));
|
||||
return;
|
||||
} else {
|
||||
emit(
|
||||
VolumesLoaded(
|
||||
diskStatus: DiskStatus.fromVolumes(
|
||||
serverVolumes,
|
||||
volumesResult.data,
|
||||
),
|
||||
providerVolumes: volumesResult.data,
|
||||
serverVolumesHashCode: Object.hashAll(serverVolumes),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _resetState(
|
||||
final VolumesServerReset event,
|
||||
final Emitter<VolumesState> emit,
|
||||
) async {
|
||||
emit(VolumesInitial());
|
||||
}
|
||||
|
||||
@override
|
||||
void onChange(final Change<VolumesState> change) {
|
||||
super.onChange(change);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _apiStatusSubscription.cancel();
|
||||
await _apiDataSubscription.cancel();
|
||||
await super.close();
|
||||
}
|
||||
|
||||
Future<void> invalidateCache() async {
|
||||
getIt<ApiConnectionRepository>().apiData.volumes.invalidate();
|
||||
}
|
||||
|
||||
Future<void> _updateState(
|
||||
final VolumesServerStateChanged event,
|
||||
final Emitter<VolumesState> emit,
|
||||
) async {
|
||||
final serverVolumes = event.volumes;
|
||||
final providerVolumes = state.providerVolumes;
|
||||
emit(
|
||||
VolumesLoaded(
|
||||
diskStatus: DiskStatus.fromVolumes(
|
||||
serverVolumes,
|
||||
providerVolumes,
|
||||
),
|
||||
providerVolumes: providerVolumes,
|
||||
serverVolumesHashCode: Object.hashAll(serverVolumes),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
30
lib/logic/bloc/volumes/volumes_event.dart
Normal file
30
lib/logic/bloc/volumes/volumes_event.dart
Normal file
|
@ -0,0 +1,30 @@
|
|||
part of 'volumes_bloc.dart';
|
||||
|
||||
abstract class VolumesEvent extends Equatable {
|
||||
const VolumesEvent();
|
||||
}
|
||||
|
||||
class VolumesServerLoaded extends VolumesEvent {
|
||||
const VolumesServerLoaded();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class VolumesServerReset extends VolumesEvent {
|
||||
const VolumesServerReset();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class VolumesServerStateChanged extends VolumesEvent {
|
||||
const VolumesServerStateChanged(
|
||||
this.volumes,
|
||||
);
|
||||
|
||||
final List<ServerDiskVolume> volumes;
|
||||
|
||||
@override
|
||||
List<Object> get props => [volumes];
|
||||
}
|
97
lib/logic/bloc/volumes/volumes_state.dart
Normal file
97
lib/logic/bloc/volumes/volumes_state.dart
Normal file
|
@ -0,0 +1,97 @@
|
|||
part of 'volumes_bloc.dart';
|
||||
|
||||
abstract class VolumesState extends Equatable {
|
||||
const VolumesState({
|
||||
required this.diskStatus,
|
||||
required final serverVolumesHashCode,
|
||||
this.providerVolumes = const [],
|
||||
}) : _serverVolumesHashCode = serverVolumesHashCode;
|
||||
|
||||
final DiskStatus diskStatus;
|
||||
final List<ServerProviderVolume> providerVolumes;
|
||||
List<DiskVolume> get volumes => diskStatus.diskVolumes;
|
||||
final int? _serverVolumesHashCode;
|
||||
|
||||
DiskVolume getVolume(final String volumeName) => volumes.firstWhere(
|
||||
(final volume) => volume.name == volumeName,
|
||||
orElse: () => DiskVolume(),
|
||||
);
|
||||
|
||||
bool get isProviderVolumesLoaded => providerVolumes.isNotEmpty;
|
||||
|
||||
VolumesState copyWith({
|
||||
required final int? serverVolumesHashCode,
|
||||
final DiskStatus? diskStatus,
|
||||
final List<ServerProviderVolume>? providerVolumes,
|
||||
});
|
||||
}
|
||||
|
||||
class VolumesInitial extends VolumesState {
|
||||
VolumesInitial()
|
||||
: super(
|
||||
diskStatus: DiskStatus(),
|
||||
serverVolumesHashCode: null,
|
||||
);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [providerVolumes, _serverVolumesHashCode];
|
||||
|
||||
@override
|
||||
VolumesInitial copyWith({
|
||||
required final int? serverVolumesHashCode,
|
||||
final DiskStatus? diskStatus,
|
||||
final List<ServerProviderVolume>? providerVolumes,
|
||||
}) =>
|
||||
VolumesInitial();
|
||||
}
|
||||
|
||||
class VolumesLoading extends VolumesState {
|
||||
VolumesLoading({
|
||||
super.serverVolumesHashCode,
|
||||
final DiskStatus? diskStatus,
|
||||
final List<ServerProviderVolume>? providerVolumes,
|
||||
}) : super(
|
||||
diskStatus: diskStatus ?? DiskStatus(),
|
||||
providerVolumes: providerVolumes ?? const [],
|
||||
);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [providerVolumes, _serverVolumesHashCode];
|
||||
|
||||
@override
|
||||
VolumesLoading copyWith({
|
||||
required final int? serverVolumesHashCode,
|
||||
final DiskStatus? diskStatus,
|
||||
final List<ServerProviderVolume>? providerVolumes,
|
||||
}) =>
|
||||
VolumesLoading(
|
||||
diskStatus: diskStatus ?? this.diskStatus,
|
||||
providerVolumes: providerVolumes ?? this.providerVolumes,
|
||||
serverVolumesHashCode: serverVolumesHashCode ?? _serverVolumesHashCode!,
|
||||
);
|
||||
}
|
||||
|
||||
class VolumesLoaded extends VolumesState {
|
||||
const VolumesLoaded({
|
||||
required super.serverVolumesHashCode,
|
||||
required super.diskStatus,
|
||||
final List<ServerProviderVolume>? providerVolumes,
|
||||
}) : super(
|
||||
providerVolumes: providerVolumes ?? const [],
|
||||
);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [providerVolumes, _serverVolumesHashCode];
|
||||
|
||||
@override
|
||||
VolumesLoaded copyWith({
|
||||
final DiskStatus? diskStatus,
|
||||
final List<ServerProviderVolume>? providerVolumes,
|
||||
final int? serverVolumesHashCode,
|
||||
}) =>
|
||||
VolumesLoaded(
|
||||
diskStatus: diskStatus ?? this.diskStatus,
|
||||
providerVolumes: providerVolumes ?? this.providerVolumes,
|
||||
serverVolumesHashCode: serverVolumesHashCode ?? _serverVolumesHashCode!,
|
||||
);
|
||||
}
|
|
@ -13,9 +13,9 @@ import 'package:selfprivacy/logic/providers/providers_controller.dart';
|
|||
|
||||
part 'provider_volume_state.dart';
|
||||
|
||||
class ApiProviderVolumeCubit
|
||||
extends ServerConnectionDependentCubit<ApiProviderVolumeState> {
|
||||
ApiProviderVolumeCubit() : super(const ApiProviderVolumeState.initial());
|
||||
class ProviderVolumeCubit
|
||||
extends ServerConnectionDependentCubit<ProviderVolumeState> {
|
||||
ProviderVolumeCubit() : super(const ProviderVolumeState.initial());
|
||||
final ServerApi serverApi = ServerApi();
|
||||
|
||||
@override
|
||||
|
@ -36,24 +36,24 @@ class ApiProviderVolumeCubit
|
|||
}
|
||||
|
||||
Future<void> refresh() async {
|
||||
emit(const ApiProviderVolumeState([], LoadingStatus.refreshing, false));
|
||||
emit(const ProviderVolumeState([], LoadingStatus.refreshing, false));
|
||||
unawaited(_refetch());
|
||||
}
|
||||
|
||||
Future<void> _refetch() async {
|
||||
if (ProvidersController.currentServerProvider == null) {
|
||||
return emit(const ApiProviderVolumeState([], LoadingStatus.error, false));
|
||||
return emit(const ProviderVolumeState([], LoadingStatus.error, false));
|
||||
}
|
||||
|
||||
final volumesResult =
|
||||
await ProvidersController.currentServerProvider!.getVolumes();
|
||||
|
||||
if (!volumesResult.success || volumesResult.data.isEmpty) {
|
||||
return emit(const ApiProviderVolumeState([], LoadingStatus.error, false));
|
||||
return emit(const ProviderVolumeState([], LoadingStatus.error, false));
|
||||
}
|
||||
|
||||
emit(
|
||||
ApiProviderVolumeState(
|
||||
ProviderVolumeState(
|
||||
volumesResult.data,
|
||||
LoadingStatus.success,
|
||||
false,
|
||||
|
@ -61,18 +61,18 @@ class ApiProviderVolumeCubit
|
|||
);
|
||||
}
|
||||
|
||||
Future<void> attachVolume(final DiskVolume volume) async {
|
||||
final ServerHostingDetails server = getIt<ApiConfigModel>().serverDetails!;
|
||||
await ProvidersController.currentServerProvider!
|
||||
.attachVolume(volume.providerVolume!, server.id);
|
||||
unawaited(refresh());
|
||||
}
|
||||
|
||||
Future<void> detachVolume(final DiskVolume volume) async {
|
||||
await ProvidersController.currentServerProvider!
|
||||
.detachVolume(volume.providerVolume!);
|
||||
unawaited(refresh());
|
||||
}
|
||||
// Future<void> attachVolume(final DiskVolume volume) async {
|
||||
// final ServerHostingDetails server = getIt<ApiConfigModel>().serverDetails!;
|
||||
// await ProvidersController.currentServerProvider!
|
||||
// .attachVolume(volume.providerVolume!, server.id);
|
||||
// unawaited(refresh());
|
||||
// }
|
||||
//
|
||||
// Future<void> detachVolume(final DiskVolume volume) async {
|
||||
// await ProvidersController.currentServerProvider!
|
||||
// .detachVolume(volume.providerVolume!);
|
||||
// unawaited(refresh());
|
||||
// }
|
||||
|
||||
Future<bool> resizeVolume(
|
||||
final DiskVolume volume,
|
||||
|
@ -119,29 +119,29 @@ class ApiProviderVolumeCubit
|
|||
return true;
|
||||
}
|
||||
|
||||
Future<void> createVolume(final DiskSize size) async {
|
||||
final ServerProviderVolume? volume = (await ProvidersController
|
||||
.currentServerProvider!
|
||||
.createVolume(size.gibibyte.toInt()))
|
||||
.data;
|
||||
|
||||
final diskVolume = DiskVolume(providerVolume: volume);
|
||||
await attachVolume(diskVolume);
|
||||
|
||||
await Future.delayed(const Duration(seconds: 10));
|
||||
|
||||
await ServerApi().mountVolume(volume!.name);
|
||||
unawaited(refresh());
|
||||
}
|
||||
|
||||
Future<void> deleteVolume(final DiskVolume volume) async {
|
||||
await ProvidersController.currentServerProvider!
|
||||
.deleteVolume(volume.providerVolume!);
|
||||
unawaited(refresh());
|
||||
}
|
||||
// Future<void> createVolume(final DiskSize size) async {
|
||||
// final ServerProviderVolume? volume = (await ProvidersController
|
||||
// .currentServerProvider!
|
||||
// .createVolume(size.gibibyte.toInt()))
|
||||
// .data;
|
||||
//
|
||||
// final diskVolume = DiskVolume(providerVolume: volume);
|
||||
// await attachVolume(diskVolume);
|
||||
//
|
||||
// await Future.delayed(const Duration(seconds: 10));
|
||||
//
|
||||
// await ServerApi().mountVolume(volume!.name);
|
||||
// unawaited(refresh());
|
||||
// }
|
||||
//
|
||||
// Future<void> deleteVolume(final DiskVolume volume) async {
|
||||
// await ProvidersController.currentServerProvider!
|
||||
// .deleteVolume(volume.providerVolume!);
|
||||
// unawaited(refresh());
|
||||
// }
|
||||
|
||||
@override
|
||||
void clear() {
|
||||
emit(const ApiProviderVolumeState.initial());
|
||||
emit(const ProviderVolumeState.initial());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
part of 'provider_volume_cubit.dart';
|
||||
|
||||
class ApiProviderVolumeState extends ServerInstallationDependendState {
|
||||
const ApiProviderVolumeState(this._volumes, this.status, this.isResizing);
|
||||
class ProviderVolumeState extends ServerInstallationDependendState {
|
||||
const ProviderVolumeState(this._volumes, this.status, this.isResizing);
|
||||
|
||||
const ApiProviderVolumeState.initial()
|
||||
const ProviderVolumeState.initial()
|
||||
: this(const [], LoadingStatus.uninitialized, false);
|
||||
final List<ServerProviderVolume> _volumes;
|
||||
final LoadingStatus status;
|
||||
|
@ -11,12 +11,12 @@ class ApiProviderVolumeState extends ServerInstallationDependendState {
|
|||
|
||||
List<ServerProviderVolume> get volumes => _volumes;
|
||||
|
||||
ApiProviderVolumeState copyWith({
|
||||
ProviderVolumeState copyWith({
|
||||
final List<ServerProviderVolume>? volumes,
|
||||
final LoadingStatus? status,
|
||||
final bool? isResizing,
|
||||
}) =>
|
||||
ApiProviderVolumeState(
|
||||
ProviderVolumeState(
|
||||
volumes ?? _volumes,
|
||||
status ?? this.status,
|
||||
isResizing ?? this.isResizing,
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server_api.dart';
|
||||
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
||||
import 'package:selfprivacy/logic/cubit/provider_volumes/provider_volume_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_connection_dependent/server_connection_dependent_cubit.dart';
|
||||
import 'package:selfprivacy/logic/models/disk_status.dart';
|
||||
import 'package:selfprivacy/logic/models/json/server_disk_volume.dart';
|
||||
|
||||
part 'server_volume_state.dart';
|
||||
|
||||
class ApiServerVolumeCubit
|
||||
extends ServerConnectionDependentCubit<ApiServerVolumeState> {
|
||||
ApiServerVolumeCubit(
|
||||
this.providerVolumeCubit,
|
||||
) : super(ApiServerVolumeState.initial()) {
|
||||
// TODO: Remove this connection between cubits
|
||||
_providerVolumeSubscription =
|
||||
providerVolumeCubit.stream.listen(checkProviderVolumes);
|
||||
}
|
||||
|
||||
final ServerApi serverApi = ServerApi();
|
||||
|
||||
@override
|
||||
Future<void> load() async {
|
||||
unawaited(reload());
|
||||
}
|
||||
|
||||
late StreamSubscription<ApiProviderVolumeState> _providerVolumeSubscription;
|
||||
final ApiProviderVolumeCubit providerVolumeCubit;
|
||||
|
||||
void checkProviderVolumes(final ApiProviderVolumeState state) {
|
||||
emit(
|
||||
ApiServerVolumeState(
|
||||
this.state._volumes,
|
||||
this.state.status,
|
||||
DiskStatus.fromVolumes(this.state._volumes, state.volumes),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
Future<void> reload() async {
|
||||
final volumes = await serverApi.getServerDiskVolumes();
|
||||
var status = LoadingStatus.error;
|
||||
|
||||
if (volumes.isNotEmpty) {
|
||||
status = LoadingStatus.success;
|
||||
}
|
||||
|
||||
emit(
|
||||
ApiServerVolumeState(
|
||||
volumes,
|
||||
status,
|
||||
DiskStatus.fromVolumes(
|
||||
volumes,
|
||||
providerVolumeCubit.state.volumes,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void clear() {
|
||||
emit(ApiServerVolumeState.initial());
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() {
|
||||
_providerVolumeSubscription.cancel();
|
||||
return super.close();
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
part of 'server_volume_cubit.dart';
|
||||
|
||||
class ApiServerVolumeState extends ServerInstallationDependendState {
|
||||
const ApiServerVolumeState(
|
||||
this._volumes,
|
||||
this.status,
|
||||
this._diskStatus,
|
||||
);
|
||||
|
||||
ApiServerVolumeState.initial()
|
||||
: this(const [], LoadingStatus.uninitialized, DiskStatus());
|
||||
|
||||
final List<ServerDiskVolume> _volumes;
|
||||
final DiskStatus _diskStatus;
|
||||
final LoadingStatus status;
|
||||
|
||||
List<DiskVolume> get volumes => _diskStatus.diskVolumes;
|
||||
DiskStatus get diskStatus => _diskStatus;
|
||||
|
||||
DiskVolume getVolume(final String volumeName) => volumes.firstWhere(
|
||||
(final volume) => volume.name == volumeName,
|
||||
orElse: () => DiskVolume(),
|
||||
);
|
||||
|
||||
ApiServerVolumeState copyWith({
|
||||
final List<ServerDiskVolume>? volumes,
|
||||
final LoadingStatus? status,
|
||||
final DiskStatus? diskStatus,
|
||||
}) =>
|
||||
ApiServerVolumeState(
|
||||
volumes ?? _volumes,
|
||||
status ?? this.status,
|
||||
diskStatus ?? _diskStatus,
|
||||
);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [_volumes, status];
|
||||
}
|
|
@ -8,6 +8,7 @@ import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server_api.da
|
|||
import 'package:selfprivacy/logic/models/backup.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
||||
import 'package:selfprivacy/logic/models/json/server_disk_volume.dart';
|
||||
import 'package:selfprivacy/logic/models/json/server_job.dart';
|
||||
import 'package:selfprivacy/logic/models/service.dart';
|
||||
|
||||
|
@ -95,10 +96,11 @@ class ApiConnectionRepository {
|
|||
_dataStream.add(_apiData);
|
||||
}
|
||||
|
||||
_apiData.serverJobs.data = await api.getServerJobs();
|
||||
_apiData.backupConfig.data = await api.getBackupsConfiguration();
|
||||
_apiData.backups.data = await api.getBackups();
|
||||
_apiData.services.data = await api.getAllServices();
|
||||
_apiData.serverJobs.data = await _apiData.serverJobs.fetchData();
|
||||
_apiData.backupConfig.data = await _apiData.backupConfig.fetchData();
|
||||
_apiData.backups.data = await _apiData.backups.fetchData();
|
||||
_apiData.services.data = await _apiData.services.fetchData();
|
||||
_apiData.volumes.data = await _apiData.volumes.fetchData();
|
||||
_dataStream.add(_apiData);
|
||||
|
||||
connectionStatus = ConnectionStatus.connected;
|
||||
|
@ -136,6 +138,8 @@ class ApiConnectionRepository {
|
|||
.refetchData(version, () => _dataStream.add(_apiData));
|
||||
await _apiData.services
|
||||
.refetchData(version, () => _dataStream.add(_apiData));
|
||||
await _apiData.volumes
|
||||
.refetchData(version, () => _dataStream.add(_apiData));
|
||||
}
|
||||
|
||||
void emitData() {
|
||||
|
@ -163,6 +167,9 @@ class ApiData {
|
|||
services = ApiDataElement<List<Service>>(
|
||||
fetchData: () async => api.getAllServices(),
|
||||
requiredApiVersion: '>=2.4.3',
|
||||
),
|
||||
volumes = ApiDataElement<List<ServerDiskVolume>>(
|
||||
fetchData: () async => api.getServerDiskVolumes(),
|
||||
);
|
||||
|
||||
ApiDataElement<List<ServerJob>> serverJobs;
|
||||
|
@ -170,6 +177,7 @@ class ApiData {
|
|||
ApiDataElement<BackupConfiguration> backupConfig;
|
||||
ApiDataElement<List<Backup>> backups;
|
||||
ApiDataElement<List<Service>> services;
|
||||
ApiDataElement<List<ServerDiskVolume>> volumes;
|
||||
}
|
||||
|
||||
enum ConnectionStatus {
|
||||
|
|
|
@ -9,7 +9,6 @@ class DiskVolume {
|
|||
this.sizeUsed = const DiskSize(byte: 0),
|
||||
this.root = false,
|
||||
this.isResizable = false,
|
||||
this.serverDiskVolume,
|
||||
this.providerVolume,
|
||||
});
|
||||
|
||||
|
@ -27,7 +26,6 @@ class DiskVolume {
|
|||
),
|
||||
root: volume.root,
|
||||
isResizable: providerVolume != null,
|
||||
serverDiskVolume: volume,
|
||||
providerVolume: providerVolume,
|
||||
);
|
||||
|
||||
|
@ -51,7 +49,6 @@ class DiskVolume {
|
|||
String name;
|
||||
bool root;
|
||||
bool isResizable;
|
||||
ServerDiskVolume? serverDiskVolume;
|
||||
ServerProviderVolume? providerVolume;
|
||||
|
||||
/// from 0.0 to 1.0
|
||||
|
@ -75,7 +72,6 @@ class DiskVolume {
|
|||
name: name ?? this.name,
|
||||
root: root ?? this.root,
|
||||
isResizable: isResizable ?? this.isResizable,
|
||||
serverDiskVolume: serverDiskVolume ?? this.serverDiskVolume,
|
||||
providerVolume: providerVolume ?? this.providerVolume,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ class ServerHostingDetails {
|
|||
@HiveField(2)
|
||||
final DateTime? startTime;
|
||||
|
||||
// TODO: Check if it is still needed
|
||||
@HiveField(4)
|
||||
final ServerProviderVolume volume;
|
||||
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import 'package:equatable/equatable.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'server_disk_volume.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class ServerDiskVolume {
|
||||
class ServerDiskVolume extends Equatable {
|
||||
factory ServerDiskVolume.fromJson(final Map<String, dynamic> json) =>
|
||||
_$ServerDiskVolumeFromJson(json);
|
||||
ServerDiskVolume({
|
||||
const ServerDiskVolume({
|
||||
required this.freeSpace,
|
||||
required this.model,
|
||||
required this.name,
|
||||
|
@ -25,4 +26,16 @@ class ServerDiskVolume {
|
|||
final String totalSpace;
|
||||
final String type;
|
||||
final String usedSpace;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
freeSpace,
|
||||
model,
|
||||
name,
|
||||
root,
|
||||
serial,
|
||||
totalSpace,
|
||||
type,
|
||||
usedSpace,
|
||||
];
|
||||
}
|
||||
|
|
|
@ -3,9 +3,9 @@ import 'package:easy_localization/easy_localization.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:selfprivacy/config/brand_theme.dart';
|
||||
import 'package:selfprivacy/logic/bloc/backups/backups_bloc.dart';
|
||||
import 'package:selfprivacy/logic/bloc/volumes/volumes_bloc.dart';
|
||||
import 'package:selfprivacy/logic/cubit/dns_records/dns_records_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_volumes/server_volume_cubit.dart';
|
||||
import 'package:selfprivacy/logic/models/state_types.dart';
|
||||
import 'package:selfprivacy/ui/components/brand_header/brand_header.dart';
|
||||
import 'package:selfprivacy/ui/components/brand_icons/brand_icons.dart';
|
||||
|
@ -34,7 +34,7 @@ class _ProvidersPageState extends State<ProvidersPage> {
|
|||
final DnsRecordsStatus dnsStatus =
|
||||
context.watch<DnsRecordsCubit>().state.dnsState;
|
||||
|
||||
final diskStatus = context.watch<ApiServerVolumeCubit>().state.diskStatus;
|
||||
final diskStatus = context.watch<VolumesBloc>().state.diskStatus;
|
||||
|
||||
final ServerInstallationState appConfig =
|
||||
context.watch<ServerInstallationCubit>().state;
|
||||
|
|
|
@ -2,12 +2,12 @@ import 'package:auto_route/auto_route.dart';
|
|||
import 'package:cubit_form/cubit_form.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:selfprivacy/logic/bloc/volumes/volumes_bloc.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/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';
|
||||
import 'package:selfprivacy/logic/models/auto_upgrade_settings.dart';
|
||||
import 'package:selfprivacy/logic/models/job.dart';
|
||||
import 'package:selfprivacy/ui/components/brand_icons/brand_icons.dart';
|
||||
|
@ -81,7 +81,7 @@ class _ServerDetailsScreenState extends State<ServerDetailsScreen>
|
|||
heroSubtitle: 'server.description'.tr(),
|
||||
children: [
|
||||
StorageCard(
|
||||
diskStatus: context.watch<ApiServerVolumeCubit>().state.diskStatus,
|
||||
diskStatus: context.watch<VolumesBloc>().state.diskStatus,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
const _ServerSettings(),
|
||||
|
|
|
@ -2,8 +2,8 @@ import 'package:auto_route/auto_route.dart';
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:selfprivacy/logic/bloc/volumes/volumes_bloc.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_status.dart';
|
||||
import 'package:selfprivacy/logic/models/price.dart';
|
||||
|
@ -59,7 +59,7 @@ class _ExtendingVolumePageState extends State<ExtendingVolumePage> {
|
|||
|
||||
@override
|
||||
Widget build(final BuildContext context) => FutureBuilder(
|
||||
future: context.read<ApiProviderVolumeCubit>().getPricePerGb(),
|
||||
future: context.read<ProviderVolumeCubit>().getPricePerGb(),
|
||||
builder: (
|
||||
final BuildContext context,
|
||||
final AsyncSnapshot<void> snapshot,
|
||||
|
@ -92,7 +92,7 @@ class _ExtendingVolumePageState extends State<ExtendingVolumePage> {
|
|||
}
|
||||
|
||||
final isAlreadyResizing =
|
||||
context.watch<ApiProviderVolumeCubit>().state.isResizing;
|
||||
context.watch<ProviderVolumeCubit>().state.isResizing;
|
||||
|
||||
return BrandHeroScreen(
|
||||
hasBackButton: true,
|
||||
|
@ -163,12 +163,12 @@ class _ExtendingVolumePageState extends State<ExtendingVolumePage> {
|
|||
),
|
||||
actionButtonTitle: 'basis.continue'.tr(),
|
||||
actionButtonOnPressed: () {
|
||||
context.read<ApiProviderVolumeCubit>().resizeVolume(
|
||||
context.read<ProviderVolumeCubit>().resizeVolume(
|
||||
widget.diskVolumeToResize,
|
||||
DiskSize.fromGibibyte(
|
||||
_currentSliderGbValue.truncate().toDouble(),
|
||||
),
|
||||
context.read<ApiServerVolumeCubit>().reload,
|
||||
context.read<VolumesBloc>().invalidateCache,
|
||||
);
|
||||
context.router.popUntilRoot();
|
||||
},
|
||||
|
|
|
@ -3,8 +3,8 @@ import 'package:easy_localization/easy_localization.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:selfprivacy/logic/bloc/services/services_bloc.dart';
|
||||
import 'package:selfprivacy/logic/bloc/volumes/volumes_bloc.dart';
|
||||
import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_volumes/server_volume_cubit.dart';
|
||||
import 'package:selfprivacy/logic/models/job.dart';
|
||||
import 'package:selfprivacy/logic/models/service.dart';
|
||||
import 'package:selfprivacy/ui/components/cards/filled_card.dart';
|
||||
|
@ -113,8 +113,7 @@ class _ServicePageState extends State<ServicePage> {
|
|||
onTap: () => context.pushRoute(
|
||||
ServicesMigrationRoute(
|
||||
services: [service],
|
||||
diskStatus:
|
||||
context.read<ApiServerVolumeCubit>().state.diskStatus,
|
||||
diskStatus: context.read<VolumesBloc>().state.diskStatus,
|
||||
),
|
||||
),
|
||||
leading: const Icon(Icons.drive_file_move_outlined),
|
||||
|
@ -127,7 +126,7 @@ class _ServicePageState extends State<ServicePage> {
|
|||
namedArgs: {
|
||||
'usage': service.storageUsage.used.toString(),
|
||||
'volume': context
|
||||
.read<ApiServerVolumeCubit>()
|
||||
.read<VolumesBloc>()
|
||||
.state
|
||||
.getVolume(service.storageUsage.volume ?? '')
|
||||
.displayName,
|
||||
|
|
Loading…
Reference in a new issue