mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-02-02 14:16:58 +00:00
refactor: Rewrite backups cubit to bloc, using ApiRepo streams
This commit is contained in:
parent
b1be3f24d6
commit
a5e7725733
|
@ -1,15 +1,15 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:selfprivacy/logic/bloc/backups/backups_bloc.dart';
|
||||
import 'package:selfprivacy/logic/cubit/connection_status/connection_status_bloc.dart';
|
||||
import 'package:selfprivacy/logic/cubit/devices/devices_cubit.dart';
|
||||
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/app_settings/app_settings_cubit.dart';
|
||||
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/client_jobs/client_jobs_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_jobs/server_jobs_bloc.dart';
|
||||
import 'package:selfprivacy/logic/bloc/server_jobs/server_jobs_bloc.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_volumes/server_volume_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/services/services_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/support_system/support_system_cubit.dart';
|
||||
|
@ -29,7 +29,7 @@ class BlocAndProviderConfig extends StatelessWidget {
|
|||
final supportSystemCubit = SupportSystemCubit();
|
||||
final usersCubit = UsersCubit(serverInstallationCubit);
|
||||
final servicesCubit = ServicesCubit(serverInstallationCubit);
|
||||
final backupsCubit = BackupsCubit(serverInstallationCubit);
|
||||
final backupsBloc = BackupsBloc();
|
||||
final dnsRecordsCubit = DnsRecordsCubit(serverInstallationCubit);
|
||||
final recoveryKeyCubit = RecoveryKeyCubit(serverInstallationCubit);
|
||||
final apiDevicesCubit = ApiDevicesCubit(serverInstallationCubit);
|
||||
|
@ -65,8 +65,7 @@ class BlocAndProviderConfig extends StatelessWidget {
|
|||
lazy: false,
|
||||
),
|
||||
BlocProvider(
|
||||
create: (final _) => backupsCubit,
|
||||
lazy: false,
|
||||
create: (final _) => backupsBloc,
|
||||
),
|
||||
BlocProvider(
|
||||
create: (final _) => dnsRecordsCubit,
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:selfprivacy/logic/get_it/navigation.dart';
|
|||
export 'package:selfprivacy/logic/get_it/api_config.dart';
|
||||
export 'package:selfprivacy/logic/get_it/console.dart';
|
||||
export 'package:selfprivacy/logic/get_it/navigation.dart';
|
||||
export 'package:selfprivacy/logic/get_it/api_connection_repository.dart';
|
||||
|
||||
final GetIt getIt = GetIt.instance;
|
||||
|
||||
|
|
396
lib/logic/bloc/backups/backups_bloc.dart
Normal file
396
lib/logic/bloc/backups/backups_bloc.dart
Normal file
|
@ -0,0 +1,396 @@
|
|||
import 'dart:async';
|
||||
|
||||
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/api_maps/rest_maps/backblaze.dart';
|
||||
import 'package:selfprivacy/logic/models/backup.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/backups_credential.dart';
|
||||
import 'package:selfprivacy/logic/models/initialize_repository_input.dart';
|
||||
import 'package:selfprivacy/logic/models/json/server_job.dart';
|
||||
import 'package:selfprivacy/logic/models/service.dart';
|
||||
|
||||
part 'backups_event.dart';
|
||||
part 'backups_state.dart';
|
||||
|
||||
class BackupsBloc extends Bloc<BackupsEvent, BackupsState> {
|
||||
BackupsBloc() : super(BackupsInitial()) {
|
||||
final connectionRepository = getIt<ApiConnectionRepository>();
|
||||
|
||||
_apiStatusSubscription = connectionRepository.connectionStatusStream
|
||||
.listen((final ConnectionStatus connectionStatus) {
|
||||
switch (connectionStatus) {
|
||||
case ConnectionStatus.nonexistent:
|
||||
add(const BackupsServerReset());
|
||||
isLoaded = false;
|
||||
break;
|
||||
case ConnectionStatus.connected:
|
||||
if (!isLoaded) {
|
||||
add(const BackupsServerLoaded());
|
||||
isLoaded = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
_apiDataSubscription = connectionRepository.dataStream.listen(
|
||||
(final ApiData apiData) {
|
||||
if (apiData.backups.data == null || apiData.backupConfig.data == null) {
|
||||
add(const BackupsServerReset());
|
||||
isLoaded = false;
|
||||
} else {
|
||||
add(
|
||||
BackupsStateChanged(
|
||||
apiData.backups.data!,
|
||||
apiData.backupConfig.data,
|
||||
),
|
||||
);
|
||||
isLoaded = true;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if (connectionRepository.connectionStatus == ConnectionStatus.connected) {
|
||||
add(const BackupsServerLoaded());
|
||||
isLoaded = true;
|
||||
}
|
||||
|
||||
on<BackupsServerLoaded>(
|
||||
_loadState,
|
||||
);
|
||||
on<BackupsServerReset>(
|
||||
_resetState,
|
||||
);
|
||||
on<BackupsStateChanged>(
|
||||
_updateState,
|
||||
);
|
||||
on<InitializeBackupsRepository>(
|
||||
_initializeRepository,
|
||||
);
|
||||
on<ForceSnapshotListUpdate>(
|
||||
_forceSnapshotListUpdate,
|
||||
);
|
||||
on<CreateBackups>(
|
||||
_createBackups,
|
||||
);
|
||||
on<RestoreBackup>(
|
||||
_restoreBackup,
|
||||
);
|
||||
on<SetAutobackupPeriod>(
|
||||
_setAutobackupPeriod,
|
||||
);
|
||||
on<SetAutobackupQuotas>(
|
||||
_setAutobackupQuotas,
|
||||
);
|
||||
on<ForgetSnapshot>(
|
||||
_forgetSnapshot,
|
||||
);
|
||||
}
|
||||
|
||||
final BackblazeApi backblaze = BackblazeApi();
|
||||
|
||||
Future<void> _loadState(
|
||||
final BackupsServerLoaded event,
|
||||
final Emitter<BackupsState> emit,
|
||||
) async {
|
||||
BackblazeBucket? bucket = getIt<ApiConfigModel>().backblazeBucket;
|
||||
final backups = getIt<ApiConnectionRepository>().apiData.backups;
|
||||
final backupConfig = getIt<ApiConnectionRepository>().apiData.backupConfig;
|
||||
if (backupConfig.data == null || backups.data == null) {
|
||||
emit(BackupsLoading());
|
||||
return;
|
||||
}
|
||||
if (bucket != null &&
|
||||
backupConfig.data!.encryptionKey != bucket.encryptionKey) {
|
||||
bucket = bucket.copyWith(
|
||||
encryptionKey: backupConfig.data!.encryptionKey,
|
||||
);
|
||||
await getIt<ApiConfigModel>().setBackblazeBucket(bucket);
|
||||
}
|
||||
if (backupConfig.data!.isInitialized) {
|
||||
emit(
|
||||
BackupsInitialized(
|
||||
backblazeBucket: bucket,
|
||||
backupConfig: backupConfig.data,
|
||||
backups: backups.data ?? [],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
emit(BackupsUnititialized());
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _resetState(
|
||||
final BackupsServerReset event,
|
||||
final Emitter<BackupsState> emit,
|
||||
) async {
|
||||
emit(BackupsInitial());
|
||||
}
|
||||
|
||||
Future<void> _initializeRepository(
|
||||
final InitializeBackupsRepository event,
|
||||
final Emitter<BackupsState> emit,
|
||||
) async {
|
||||
if (state is! BackupsUnititialized) {
|
||||
return;
|
||||
}
|
||||
emit(BackupsInitializing());
|
||||
final String? encryptionKey = getIt<ApiConnectionRepository>()
|
||||
.apiData
|
||||
.backupConfig
|
||||
.data
|
||||
?.encryptionKey;
|
||||
if (encryptionKey == null) {
|
||||
emit(BackupsUnititialized());
|
||||
getIt<NavigationService>()
|
||||
.showSnackBar("Couldn't get encryption key from your server.");
|
||||
return;
|
||||
}
|
||||
|
||||
final BackblazeBucket bucket;
|
||||
|
||||
if (state.backblazeBucket == null) {
|
||||
final String domain = getIt<ApiConnectionRepository>()
|
||||
.serverDomain!
|
||||
.domainName
|
||||
.replaceAll(RegExp(r'[^a-zA-Z0-9]'), '-');
|
||||
final int serverId = getIt<ApiConnectionRepository>().serverDetails!.id;
|
||||
String bucketName =
|
||||
'${DateTime.now().millisecondsSinceEpoch}-$serverId-$domain';
|
||||
if (bucketName.length > 49) {
|
||||
bucketName = bucketName.substring(0, 49);
|
||||
}
|
||||
final String bucketId = await backblaze.createBucket(bucketName);
|
||||
|
||||
final BackblazeApplicationKey key = await backblaze.createKey(bucketId);
|
||||
bucket = BackblazeBucket(
|
||||
bucketId: bucketId,
|
||||
bucketName: bucketName,
|
||||
applicationKey: key.applicationKey,
|
||||
applicationKeyId: key.applicationKeyId,
|
||||
encryptionKey: encryptionKey,
|
||||
);
|
||||
|
||||
await getIt<ApiConfigModel>().setBackblazeBucket(bucket);
|
||||
emit(state.copyWith(backblazeBucket: bucket));
|
||||
} else {
|
||||
bucket = state.backblazeBucket!;
|
||||
}
|
||||
|
||||
final GenericResult result =
|
||||
await getIt<ApiConnectionRepository>().api.initializeRepository(
|
||||
InitializeRepositoryInput(
|
||||
provider: BackupsProviderType.backblaze,
|
||||
locationId: bucket.bucketId,
|
||||
locationName: bucket.bucketName,
|
||||
login: bucket.applicationKeyId,
|
||||
password: bucket.applicationKey,
|
||||
),
|
||||
);
|
||||
if (result.success == false) {
|
||||
getIt<NavigationService>().showSnackBar(
|
||||
result.message ?? "Couldn't initialize repository on your server.");
|
||||
emit(BackupsUnititialized());
|
||||
return;
|
||||
}
|
||||
getIt<ApiConnectionRepository>().apiData.backupConfig.invalidate();
|
||||
getIt<ApiConnectionRepository>().apiData.backups.invalidate();
|
||||
await getIt<ApiConnectionRepository>().reload(null);
|
||||
|
||||
getIt<NavigationService>().showSnackBar(
|
||||
'Backups repository is now initializing. It may take a while.',
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _updateState(
|
||||
final BackupsStateChanged event,
|
||||
final Emitter<BackupsState> emit,
|
||||
) async {
|
||||
if (event.backupConfiguration == null ||
|
||||
event.backupConfiguration!.isInitialized == false) {
|
||||
emit(BackupsUnititialized());
|
||||
return;
|
||||
}
|
||||
final BackblazeBucket? bucket = getIt<ApiConfigModel>().backblazeBucket;
|
||||
emit(
|
||||
BackupsInitialized(
|
||||
backblazeBucket: bucket,
|
||||
backupConfig: event.backupConfiguration,
|
||||
backups: event.backups,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _forceSnapshotListUpdate(
|
||||
final ForceSnapshotListUpdate event,
|
||||
final Emitter<BackupsState> emit,
|
||||
) async {
|
||||
final currentState = state;
|
||||
if (currentState is BackupsInitialized) {
|
||||
emit(BackupsBusy.fromState(currentState));
|
||||
getIt<NavigationService>().showSnackBar('backup.refetching_list'.tr());
|
||||
await getIt<ApiConnectionRepository>().api.forceBackupListReload();
|
||||
getIt<ApiConnectionRepository>().apiData.backups.invalidate();
|
||||
emit(currentState);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _createBackups(
|
||||
final CreateBackups event,
|
||||
final Emitter<BackupsState> emit,
|
||||
) async {
|
||||
final currentState = state;
|
||||
if (currentState is BackupsInitialized) {
|
||||
emit(BackupsBusy.fromState(currentState));
|
||||
for (final service in event.services) {
|
||||
final GenericResult<ServerJob?> result =
|
||||
await getIt<ApiConnectionRepository>().api.startBackup(
|
||||
service.id,
|
||||
);
|
||||
if (result.success == false) {
|
||||
getIt<NavigationService>()
|
||||
.showSnackBar(result.message ?? 'Unknown error');
|
||||
}
|
||||
if (result.data != null) {
|
||||
getIt<ApiConnectionRepository>()
|
||||
.apiData
|
||||
.serverJobs
|
||||
.data
|
||||
?.add(result.data!);
|
||||
}
|
||||
}
|
||||
emit(currentState);
|
||||
getIt<ApiConnectionRepository>().emitData();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _restoreBackup(
|
||||
final RestoreBackup event,
|
||||
final Emitter<BackupsState> emit,
|
||||
) async {
|
||||
final currentState = state;
|
||||
if (currentState is BackupsInitialized) {
|
||||
emit(BackupsBusy.fromState(currentState));
|
||||
final GenericResult result =
|
||||
await getIt<ApiConnectionRepository>().api.restoreBackup(
|
||||
event.backupId,
|
||||
event.restoreStrategy,
|
||||
);
|
||||
if (result.success == false) {
|
||||
getIt<NavigationService>()
|
||||
.showSnackBar(result.message ?? 'Unknown error');
|
||||
}
|
||||
emit(currentState);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _setAutobackupPeriod(
|
||||
final SetAutobackupPeriod event,
|
||||
final Emitter<BackupsState> emit,
|
||||
) async {
|
||||
final currentState = state;
|
||||
if (currentState is BackupsInitialized) {
|
||||
emit(BackupsBusy.fromState(currentState));
|
||||
final GenericResult result =
|
||||
await getIt<ApiConnectionRepository>().api.setAutobackupPeriod(
|
||||
period: event.period?.inMinutes,
|
||||
);
|
||||
if (result.success == false) {
|
||||
getIt<NavigationService>()
|
||||
.showSnackBar(result.message ?? 'Unknown error');
|
||||
}
|
||||
if (result.success == true) {
|
||||
getIt<ApiConnectionRepository>().apiData.backupConfig.data =
|
||||
getIt<ApiConnectionRepository>()
|
||||
.apiData
|
||||
.backupConfig
|
||||
.data
|
||||
?.copyWith(
|
||||
autobackupPeriod: event.period,
|
||||
);
|
||||
}
|
||||
emit(currentState);
|
||||
getIt<ApiConnectionRepository>().emitData();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _setAutobackupQuotas(
|
||||
final SetAutobackupQuotas event,
|
||||
final Emitter<BackupsState> emit,
|
||||
) async {
|
||||
final currentState = state;
|
||||
if (currentState is BackupsInitialized) {
|
||||
emit(BackupsBusy.fromState(currentState));
|
||||
final GenericResult result =
|
||||
await getIt<ApiConnectionRepository>().api.setAutobackupQuotas(
|
||||
event.quotas,
|
||||
);
|
||||
if (result.success == false) {
|
||||
getIt<NavigationService>()
|
||||
.showSnackBar(result.message ?? 'Unknown error');
|
||||
}
|
||||
if (result.success == true) {
|
||||
getIt<ApiConnectionRepository>().apiData.backupConfig.data =
|
||||
getIt<ApiConnectionRepository>()
|
||||
.apiData
|
||||
.backupConfig
|
||||
.data
|
||||
?.copyWith(
|
||||
autobackupQuotas: event.quotas,
|
||||
);
|
||||
}
|
||||
emit(currentState);
|
||||
getIt<ApiConnectionRepository>().emitData();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _forgetSnapshot(
|
||||
final ForgetSnapshot event,
|
||||
final Emitter<BackupsState> emit,
|
||||
) async {
|
||||
final currentState = state;
|
||||
if (currentState is BackupsInitialized) {
|
||||
emit(BackupsBusy.fromState(currentState));
|
||||
final GenericResult result =
|
||||
await getIt<ApiConnectionRepository>().api.forgetSnapshot(
|
||||
event.backupId,
|
||||
);
|
||||
if (result.success == false) {
|
||||
getIt<NavigationService>()
|
||||
.showSnackBar(result.message ?? 'jobs.generic_error'.tr());
|
||||
} else if (result.data == false) {
|
||||
getIt<NavigationService>()
|
||||
.showSnackBar('backup.forget_snapshot_error'.tr());
|
||||
} else {
|
||||
final backups = getIt<ApiConnectionRepository>().apiData.backups.data;
|
||||
if (backups != null) {
|
||||
getIt<ApiConnectionRepository>().apiData.backups.data = backups
|
||||
.where((final Backup backup) => backup.id != event.backupId)
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
emit(currentState);
|
||||
getIt<ApiConnectionRepository>().emitData();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() {
|
||||
_apiStatusSubscription.cancel();
|
||||
_apiDataSubscription.cancel();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
@override
|
||||
void onChange(final Change<BackupsState> change) {
|
||||
super.onChange(change);
|
||||
}
|
||||
|
||||
late StreamSubscription _apiStatusSubscription;
|
||||
late StreamSubscription _apiDataSubscription;
|
||||
bool isLoaded = false;
|
||||
}
|
89
lib/logic/bloc/backups/backups_event.dart
Normal file
89
lib/logic/bloc/backups/backups_event.dart
Normal file
|
@ -0,0 +1,89 @@
|
|||
part of 'backups_bloc.dart';
|
||||
|
||||
sealed class BackupsEvent extends Equatable {
|
||||
const BackupsEvent();
|
||||
}
|
||||
|
||||
class BackupsServerLoaded extends BackupsEvent {
|
||||
const BackupsServerLoaded();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class BackupsServerReset extends BackupsEvent {
|
||||
const BackupsServerReset();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class InitializeBackupsRepository extends BackupsEvent {
|
||||
const InitializeBackupsRepository();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class BackupsStateChanged extends BackupsEvent {
|
||||
const BackupsStateChanged(this.backups, this.backupConfiguration);
|
||||
|
||||
final List<Backup> backups;
|
||||
final BackupConfiguration? backupConfiguration;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [backups, backupConfiguration];
|
||||
}
|
||||
|
||||
class ForceSnapshotListUpdate extends BackupsEvent {
|
||||
const ForceSnapshotListUpdate();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class CreateBackups extends BackupsEvent {
|
||||
const CreateBackups(this.services);
|
||||
|
||||
final List<Service> services;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [services];
|
||||
}
|
||||
|
||||
class RestoreBackup extends BackupsEvent {
|
||||
const RestoreBackup(this.backupId, this.restoreStrategy);
|
||||
|
||||
final String backupId;
|
||||
final BackupRestoreStrategy restoreStrategy;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [backupId, restoreStrategy];
|
||||
}
|
||||
|
||||
class SetAutobackupPeriod extends BackupsEvent {
|
||||
const SetAutobackupPeriod(this.period);
|
||||
|
||||
final Duration? period;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [period];
|
||||
}
|
||||
|
||||
class SetAutobackupQuotas extends BackupsEvent {
|
||||
const SetAutobackupQuotas(this.quotas);
|
||||
|
||||
final AutobackupQuotas quotas;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [quotas];
|
||||
}
|
||||
|
||||
class ForgetSnapshot extends BackupsEvent {
|
||||
const ForgetSnapshot(this.backupId);
|
||||
|
||||
final String backupId;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [backupId];
|
||||
}
|
168
lib/logic/bloc/backups/backups_state.dart
Normal file
168
lib/logic/bloc/backups/backups_state.dart
Normal file
|
@ -0,0 +1,168 @@
|
|||
part of 'backups_bloc.dart';
|
||||
|
||||
sealed class BackupsState extends Equatable {
|
||||
BackupsState({
|
||||
this.backblazeBucket,
|
||||
});
|
||||
final apiConnectionRepository = getIt<ApiConnectionRepository>();
|
||||
final BackblazeBucket? backblazeBucket;
|
||||
|
||||
@Deprecated('Infer the initializations status from state')
|
||||
bool get isInitialized => false;
|
||||
|
||||
@Deprecated('Infer the loading status from state')
|
||||
bool get refreshing => false;
|
||||
|
||||
@Deprecated('Infer the prevent actions status from state')
|
||||
bool get preventActions => true;
|
||||
|
||||
List<Backup> get backups => [];
|
||||
|
||||
List<Backup> serviceBackups(final String serviceId) => [];
|
||||
|
||||
Duration? get autobackupPeriod => null;
|
||||
|
||||
AutobackupQuotas? get autobackupQuotas => null;
|
||||
|
||||
BackupsState copyWith({required final BackblazeBucket backblazeBucket});
|
||||
}
|
||||
|
||||
class BackupsInitial extends BackupsState {
|
||||
BackupsInitial({
|
||||
super.backblazeBucket,
|
||||
});
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
|
||||
@override
|
||||
BackupsInitial copyWith({
|
||||
final BackblazeBucket? backblazeBucket,
|
||||
}) =>
|
||||
BackupsInitial(backblazeBucket: backblazeBucket ?? this.backblazeBucket);
|
||||
}
|
||||
|
||||
class BackupsLoading extends BackupsState {
|
||||
BackupsLoading({
|
||||
super.backblazeBucket,
|
||||
});
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
|
||||
@override
|
||||
@Deprecated('Infer the loading status from state')
|
||||
bool get refreshing => true;
|
||||
|
||||
@override
|
||||
BackupsLoading copyWith({
|
||||
final BackblazeBucket? backblazeBucket,
|
||||
}) =>
|
||||
BackupsLoading(backblazeBucket: backblazeBucket ?? this.backblazeBucket);
|
||||
}
|
||||
|
||||
class BackupsUnititialized extends BackupsState {
|
||||
BackupsUnititialized({
|
||||
super.backblazeBucket,
|
||||
});
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
|
||||
@override
|
||||
BackupsUnititialized copyWith({
|
||||
final BackblazeBucket? backblazeBucket,
|
||||
}) =>
|
||||
BackupsUnititialized(
|
||||
backblazeBucket: backblazeBucket ?? this.backblazeBucket);
|
||||
}
|
||||
|
||||
class BackupsInitializing extends BackupsState {
|
||||
BackupsInitializing({
|
||||
super.backblazeBucket,
|
||||
});
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
|
||||
@override
|
||||
BackupsInitializing copyWith({
|
||||
final BackblazeBucket? backblazeBucket,
|
||||
}) =>
|
||||
BackupsInitializing(
|
||||
backblazeBucket: backblazeBucket ?? this.backblazeBucket);
|
||||
}
|
||||
|
||||
class BackupsInitialized extends BackupsState {
|
||||
BackupsInitialized({
|
||||
final List<Backup> backups = const [],
|
||||
final BackupConfiguration? backupConfig,
|
||||
super.backblazeBucket,
|
||||
}) : _backupsHashCode = Object.hashAll(backups),
|
||||
_backupConfigHashCode = Object.hashAll([backupConfig]);
|
||||
|
||||
final int _backupsHashCode;
|
||||
final int _backupConfigHashCode;
|
||||
|
||||
List<Backup> get _backupList =>
|
||||
apiConnectionRepository.apiData.backups.data ?? [];
|
||||
|
||||
BackupConfiguration? get _backupConfig =>
|
||||
apiConnectionRepository.apiData.backupConfig.data;
|
||||
|
||||
@override
|
||||
AutobackupQuotas? get autobackupQuotas => _backupConfig?.autobackupQuotas;
|
||||
|
||||
@override
|
||||
Duration? get autobackupPeriod =>
|
||||
_backupConfig?.autobackupPeriod?.inMinutes == 0
|
||||
? null
|
||||
: _backupConfig?.autobackupPeriod;
|
||||
|
||||
@override
|
||||
@Deprecated('Infer the initializations status from state')
|
||||
bool get isInitialized => true;
|
||||
|
||||
@override
|
||||
@Deprecated('Infer the prevent actions status from state')
|
||||
bool get preventActions => false;
|
||||
|
||||
@override
|
||||
List<Backup> get backups {
|
||||
try {
|
||||
final List<Backup> list = _backupList;
|
||||
list.sort((final a, final b) => b.time.compareTo(a.time));
|
||||
return list;
|
||||
} on UnsupportedError {
|
||||
return _backupList;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
List<Backup> serviceBackups(final String serviceId) => backups
|
||||
.where((final backup) => backup.serviceId == serviceId)
|
||||
.toList(growable: false);
|
||||
|
||||
@override
|
||||
List<Object> get props => [_backupsHashCode, _backupConfigHashCode];
|
||||
|
||||
@override
|
||||
BackupsState copyWith({required final BackblazeBucket backblazeBucket}) =>
|
||||
BackupsInitialized(
|
||||
backups: backups,
|
||||
backupConfig: _backupConfig,
|
||||
backblazeBucket: backblazeBucket,
|
||||
);
|
||||
}
|
||||
|
||||
class BackupsBusy extends BackupsInitialized {
|
||||
BackupsBusy.fromState(final BackupsInitialized state)
|
||||
: super(
|
||||
backups: state.backups,
|
||||
backupConfig: state._backupConfig,
|
||||
backblazeBucket: state.backblazeBucket,
|
||||
);
|
||||
|
||||
@override
|
||||
@Deprecated('Infer the prevent actions status from state')
|
||||
bool get preventActions => true;
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
|
@ -3,7 +3,6 @@ import 'dart:async';
|
|||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:selfprivacy/config/get_it_config.dart';
|
||||
import 'package:selfprivacy/logic/get_it/api_connection_repository.dart';
|
||||
import 'package:selfprivacy/logic/models/json/server_job.dart';
|
||||
|
||||
export 'package:provider/provider.dart';
|
|
@ -1,278 +0,0 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:selfprivacy/config/get_it_config.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/backblaze.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server_api.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_connection_dependent/server_connection_dependent_cubit.dart';
|
||||
import 'package:selfprivacy/logic/get_it/api_connection_repository.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart';
|
||||
import 'package:selfprivacy/logic/models/backup.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/backups_credential.dart';
|
||||
import 'package:selfprivacy/logic/models/initialize_repository_input.dart';
|
||||
import 'package:selfprivacy/logic/models/service.dart';
|
||||
|
||||
part 'backups_state.dart';
|
||||
|
||||
class BackupsCubit extends ServerConnectionDependentCubit<BackupsState> {
|
||||
BackupsCubit(final ServerInstallationCubit serverInstallationCubit)
|
||||
: super(
|
||||
const BackupsState(preventActions: true),
|
||||
);
|
||||
|
||||
final ServerApi api = ServerApi();
|
||||
final BackblazeApi backblaze = BackblazeApi();
|
||||
|
||||
@override
|
||||
Future<void> load() async {
|
||||
final BackblazeBucket? bucket = getIt<ApiConfigModel>().backblazeBucket;
|
||||
final BackupConfiguration? backupConfig =
|
||||
await api.getBackupsConfiguration();
|
||||
final List<Backup> backups = await api.getBackups();
|
||||
backups.sort((final a, final b) => b.time.compareTo(a.time));
|
||||
emit(
|
||||
state.copyWith(
|
||||
backblazeBucket: bucket,
|
||||
isInitialized: backupConfig?.isInitialized,
|
||||
autobackupPeriod: backupConfig?.autobackupPeriod ?? Duration.zero,
|
||||
autobackupQuotas: backupConfig?.autobackupQuotas,
|
||||
backups: backups,
|
||||
preventActions: false,
|
||||
refreshing: false,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> initializeBackups() async {
|
||||
emit(state.copyWith(preventActions: true));
|
||||
final String? encryptionKey =
|
||||
(await api.getBackupsConfiguration())?.encryptionKey;
|
||||
if (encryptionKey == null) {
|
||||
getIt<NavigationService>()
|
||||
.showSnackBar("Couldn't get encryption key from your server.");
|
||||
emit(state.copyWith(preventActions: false));
|
||||
return;
|
||||
}
|
||||
|
||||
final BackblazeBucket bucket;
|
||||
|
||||
if (state.backblazeBucket == null) {
|
||||
final String domain = getIt<ApiConnectionRepository>()
|
||||
.serverDomain!
|
||||
.domainName
|
||||
.replaceAll(RegExp(r'[^a-zA-Z0-9]'), '-');
|
||||
final int serverId = getIt<ApiConnectionRepository>().serverDetails!.id;
|
||||
String bucketName =
|
||||
'${DateTime.now().millisecondsSinceEpoch}-$serverId-$domain';
|
||||
if (bucketName.length > 49) {
|
||||
bucketName = bucketName.substring(0, 49);
|
||||
}
|
||||
final String bucketId = await backblaze.createBucket(bucketName);
|
||||
|
||||
final BackblazeApplicationKey key = await backblaze.createKey(bucketId);
|
||||
bucket = BackblazeBucket(
|
||||
bucketId: bucketId,
|
||||
bucketName: bucketName,
|
||||
applicationKey: key.applicationKey,
|
||||
applicationKeyId: key.applicationKeyId,
|
||||
encryptionKey: encryptionKey,
|
||||
);
|
||||
|
||||
await getIt<ApiConfigModel>().storeBackblazeBucket(bucket);
|
||||
emit(state.copyWith(backblazeBucket: bucket));
|
||||
} else {
|
||||
bucket = state.backblazeBucket!;
|
||||
}
|
||||
|
||||
final GenericResult result = await api.initializeRepository(
|
||||
InitializeRepositoryInput(
|
||||
provider: BackupsProviderType.backblaze,
|
||||
locationId: bucket.bucketId,
|
||||
locationName: bucket.bucketName,
|
||||
login: bucket.applicationKeyId,
|
||||
password: bucket.applicationKey,
|
||||
),
|
||||
);
|
||||
if (result.success == false) {
|
||||
getIt<NavigationService>()
|
||||
.showSnackBar(result.message ?? 'Unknown error');
|
||||
emit(state.copyWith(preventActions: false));
|
||||
return;
|
||||
}
|
||||
await updateBackups();
|
||||
getIt<NavigationService>().showSnackBar(
|
||||
'Backups repository is now initializing. It may take a while.',
|
||||
);
|
||||
|
||||
emit(state.copyWith(preventActions: false));
|
||||
}
|
||||
|
||||
Future<void> reuploadKey() async {
|
||||
emit(state.copyWith(preventActions: true));
|
||||
BackblazeBucket? bucket = getIt<ApiConfigModel>().backblazeBucket;
|
||||
if (bucket == null) {
|
||||
emit(state.copyWith(isInitialized: false));
|
||||
} else {
|
||||
String login = bucket.applicationKeyId;
|
||||
String password = bucket.applicationKey;
|
||||
if (login.isEmpty || password.isEmpty) {
|
||||
final BackblazeApplicationKey key =
|
||||
await backblaze.createKey(bucket.bucketId);
|
||||
login = key.applicationKeyId;
|
||||
password = key.applicationKey;
|
||||
bucket = BackblazeBucket(
|
||||
bucketId: bucket.bucketId,
|
||||
bucketName: bucket.bucketName,
|
||||
encryptionKey: bucket.encryptionKey,
|
||||
applicationKey: password,
|
||||
applicationKeyId: login,
|
||||
);
|
||||
await getIt<ApiConfigModel>().storeBackblazeBucket(bucket);
|
||||
emit(state.copyWith(backblazeBucket: bucket));
|
||||
}
|
||||
final GenericResult result = await api.initializeRepository(
|
||||
InitializeRepositoryInput(
|
||||
provider: BackupsProviderType.backblaze,
|
||||
locationId: bucket.bucketId,
|
||||
locationName: bucket.bucketName,
|
||||
login: login,
|
||||
password: password,
|
||||
),
|
||||
);
|
||||
if (result.success == false) {
|
||||
getIt<NavigationService>()
|
||||
.showSnackBar(result.message ?? 'Unknown error');
|
||||
emit(state.copyWith(preventActions: false));
|
||||
return;
|
||||
} else {
|
||||
emit(state.copyWith(preventActions: false));
|
||||
getIt<NavigationService>().showSnackBar('backup.reuploaded_key'.tr());
|
||||
await updateBackups();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated("we don't have states")
|
||||
Duration refreshTimeFromState() => const Duration(seconds: 60);
|
||||
|
||||
Future<void> updateBackups({final bool useTimer = false}) async {
|
||||
emit(state.copyWith(refreshing: true));
|
||||
final backups = await api.getBackups();
|
||||
backups.sort((final a, final b) => b.time.compareTo(a.time));
|
||||
final backupConfig = await api.getBackupsConfiguration();
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
backups: backups,
|
||||
refreshTimer: refreshTimeFromState(),
|
||||
refreshing: false,
|
||||
isInitialized: backupConfig?.isInitialized ?? false,
|
||||
autobackupPeriod: backupConfig?.autobackupPeriod,
|
||||
autobackupQuotas: backupConfig?.autobackupQuotas,
|
||||
),
|
||||
);
|
||||
if (useTimer) {
|
||||
Timer(state.refreshTimer, () => updateBackups(useTimer: true));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> forceUpdateBackups() async {
|
||||
emit(state.copyWith(preventActions: true));
|
||||
getIt<NavigationService>().showSnackBar('backup.refetching_list'.tr());
|
||||
await api.forceBackupListReload();
|
||||
emit(state.copyWith(preventActions: false));
|
||||
}
|
||||
|
||||
Future<void> createMultipleBackups(final List<Service> services) async {
|
||||
emit(state.copyWith(preventActions: true));
|
||||
for (final service in services) {
|
||||
await api.startBackup(service.id);
|
||||
}
|
||||
await updateBackups();
|
||||
emit(state.copyWith(preventActions: false));
|
||||
}
|
||||
|
||||
Future<void> createBackup(final String serviceId) async {
|
||||
emit(state.copyWith(preventActions: true));
|
||||
await api.startBackup(serviceId);
|
||||
await updateBackups();
|
||||
emit(state.copyWith(preventActions: false));
|
||||
}
|
||||
|
||||
Future<void> restoreBackup(
|
||||
final String backupId,
|
||||
final BackupRestoreStrategy strategy,
|
||||
) async {
|
||||
emit(state.copyWith(preventActions: true));
|
||||
await api.restoreBackup(backupId, strategy);
|
||||
emit(state.copyWith(preventActions: false));
|
||||
}
|
||||
|
||||
Future<void> setAutobackupPeriod(final Duration? period) async {
|
||||
emit(state.copyWith(preventActions: true));
|
||||
final result = await api.setAutobackupPeriod(period: period?.inMinutes);
|
||||
if (result.success == false) {
|
||||
getIt<NavigationService>()
|
||||
.showSnackBar(result.message ?? 'Unknown error');
|
||||
emit(state.copyWith(preventActions: false));
|
||||
} else {
|
||||
getIt<NavigationService>()
|
||||
.showSnackBar('backup.autobackup_period_set'.tr());
|
||||
emit(
|
||||
state.copyWith(
|
||||
preventActions: false,
|
||||
autobackupPeriod: period ?? Duration.zero,
|
||||
),
|
||||
);
|
||||
}
|
||||
await updateBackups();
|
||||
}
|
||||
|
||||
Future<void> setAutobackupQuotas(final AutobackupQuotas quotas) async {
|
||||
emit(state.copyWith(preventActions: true));
|
||||
final result = await api.setAutobackupQuotas(quotas);
|
||||
if (result.success == false) {
|
||||
getIt<NavigationService>()
|
||||
.showSnackBar(result.message ?? 'Unknown error');
|
||||
emit(state.copyWith(preventActions: false));
|
||||
} else {
|
||||
getIt<NavigationService>().showSnackBar('backup.quotas_set'.tr());
|
||||
emit(
|
||||
state.copyWith(
|
||||
preventActions: false,
|
||||
autobackupQuotas: quotas,
|
||||
),
|
||||
);
|
||||
}
|
||||
await updateBackups();
|
||||
}
|
||||
|
||||
Future<void> forgetSnapshot(final String snapshotId) async {
|
||||
final result = await api.forgetSnapshot(snapshotId);
|
||||
if (!result.success) {
|
||||
getIt<NavigationService>().showSnackBar('jobs.generic_error'.tr());
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.data == false) {
|
||||
getIt<NavigationService>()
|
||||
.showSnackBar('backup.forget_snapshot_error'.tr());
|
||||
}
|
||||
|
||||
// Optimistic update
|
||||
final backups = state.backups;
|
||||
final index =
|
||||
backups.indexWhere((final snapshot) => snapshot.id == snapshotId);
|
||||
if (index != -1) {
|
||||
backups.removeAt(index);
|
||||
emit(state.copyWith(backups: backups));
|
||||
}
|
||||
|
||||
await updateBackups();
|
||||
}
|
||||
|
||||
@override
|
||||
void clear() async {
|
||||
emit(const BackupsState());
|
||||
}
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
part of 'backups_cubit.dart';
|
||||
|
||||
class BackupsState extends ServerInstallationDependendState {
|
||||
const BackupsState({
|
||||
this.isInitialized = false,
|
||||
this.backups = const [],
|
||||
this.preventActions = true,
|
||||
this.refreshTimer = const Duration(seconds: 60),
|
||||
this.refreshing = true,
|
||||
this.autobackupPeriod,
|
||||
this.backblazeBucket,
|
||||
this.autobackupQuotas,
|
||||
});
|
||||
|
||||
final bool isInitialized;
|
||||
final List<Backup> backups;
|
||||
final bool preventActions;
|
||||
final Duration refreshTimer;
|
||||
final bool refreshing;
|
||||
final Duration? autobackupPeriod;
|
||||
final BackblazeBucket? backblazeBucket;
|
||||
final AutobackupQuotas? autobackupQuotas;
|
||||
|
||||
List<Backup> serviceBackups(final String serviceId) => backups
|
||||
.where((final backup) => backup.serviceId == serviceId)
|
||||
.toList(growable: false);
|
||||
|
||||
@override
|
||||
List<Object> get props => [
|
||||
isInitialized,
|
||||
backups,
|
||||
preventActions,
|
||||
refreshTimer,
|
||||
refreshing,
|
||||
];
|
||||
|
||||
BackupsState copyWith({
|
||||
final bool? isInitialized,
|
||||
final List<Backup>? backups,
|
||||
final bool? preventActions,
|
||||
final Duration? refreshTimer,
|
||||
final bool? refreshing,
|
||||
final Duration? autobackupPeriod,
|
||||
final BackblazeBucket? backblazeBucket,
|
||||
final AutobackupQuotas? autobackupQuotas,
|
||||
}) =>
|
||||
BackupsState(
|
||||
isInitialized: isInitialized ?? this.isInitialized,
|
||||
backups: backups ?? this.backups,
|
||||
preventActions: preventActions ?? this.preventActions,
|
||||
refreshTimer: refreshTimer ?? this.refreshTimer,
|
||||
refreshing: refreshing ?? this.refreshing,
|
||||
// The autobackupPeriod might be null, so if the duration is set to 0, we
|
||||
// set it to null.
|
||||
autobackupPeriod: autobackupPeriod?.inSeconds == 0
|
||||
? null
|
||||
: autobackupPeriod ?? this.autobackupPeriod,
|
||||
backblazeBucket: backblazeBucket ?? this.backblazeBucket,
|
||||
autobackupQuotas: autobackupQuotas ?? this.autobackupQuotas,
|
||||
);
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:selfprivacy/config/get_it_config.dart';
|
||||
import 'package:selfprivacy/logic/get_it/api_connection_repository.dart';
|
||||
|
||||
part 'connection_status_event.dart';
|
||||
part 'connection_status_state.dart';
|
||||
|
|
|
@ -2,7 +2,6 @@ import 'package:cubit_form/cubit_form.dart';
|
|||
import 'package:selfprivacy/config/get_it_config.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/desired_dns_record.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_connection_dependent/server_connection_dependent_cubit.dart';
|
||||
import 'package:selfprivacy/logic/get_it/api_connection_repository.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
||||
import 'package:selfprivacy/logic/models/json/dns_records.dart';
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ import 'dart:async';
|
|||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:selfprivacy/config/get_it_config.dart';
|
||||
import 'package:selfprivacy/logic/get_it/api_connection_repository.dart';
|
||||
|
||||
export 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ import 'package:selfprivacy/config/get_it_config.dart';
|
|||
import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server_api.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/backblaze.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/tls_options.dart';
|
||||
import 'package:selfprivacy/logic/get_it/api_connection_repository.dart';
|
||||
import 'package:selfprivacy/logic/models/disk_size.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/backups_credential.dart';
|
||||
|
@ -234,7 +233,7 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
|||
try {
|
||||
bucket = await BackblazeApi()
|
||||
.fetchBucket(backblazeCredential, configuration);
|
||||
await getIt<ApiConfigModel>().storeBackblazeBucket(bucket!);
|
||||
await getIt<ApiConfigModel>().setBackblazeBucket(bucket!);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
}
|
||||
|
|
|
@ -470,7 +470,7 @@ class ServerInstallationRepository {
|
|||
Future<void> saveServerDetails(
|
||||
final ServerHostingDetails serverDetails,
|
||||
) async {
|
||||
await getIt<ApiConfigModel>().storeServerDetails(serverDetails);
|
||||
await getIt<ApiConfigModel>().setServerDetails(serverDetails);
|
||||
}
|
||||
|
||||
Future<void> deleteServerDetails() async {
|
||||
|
@ -483,18 +483,18 @@ class ServerInstallationRepository {
|
|||
}
|
||||
|
||||
Future<void> saveDnsProviderType(final DnsProviderType type) async {
|
||||
await getIt<ApiConfigModel>().storeDnsProviderType(type);
|
||||
await getIt<ApiConfigModel>().setDnsProviderType(type);
|
||||
}
|
||||
|
||||
Future<void> saveServerProviderKey(final String key) async {
|
||||
await getIt<ApiConfigModel>().storeServerProviderKey(key);
|
||||
await getIt<ApiConfigModel>().setServerProviderKey(key);
|
||||
}
|
||||
|
||||
Future<void> saveServerType(final ServerType serverType) async {
|
||||
await getIt<ApiConfigModel>().storeServerTypeIdentifier(
|
||||
await getIt<ApiConfigModel>().setServerTypeIdentifier(
|
||||
serverType.identifier,
|
||||
);
|
||||
await getIt<ApiConfigModel>().storeServerLocation(
|
||||
await getIt<ApiConfigModel>().setServerLocation(
|
||||
serverType.location.identifier,
|
||||
);
|
||||
}
|
||||
|
@ -507,7 +507,7 @@ class ServerInstallationRepository {
|
|||
Future<void> saveBackblazeKey(
|
||||
final BackupsCredential backblazeCredential,
|
||||
) async {
|
||||
await getIt<ApiConfigModel>().storeBackblazeCredential(backblazeCredential);
|
||||
await getIt<ApiConfigModel>().setBackblazeCredential(backblazeCredential);
|
||||
}
|
||||
|
||||
Future<void> deleteBackblazeKey() async {
|
||||
|
@ -516,7 +516,7 @@ class ServerInstallationRepository {
|
|||
}
|
||||
|
||||
Future<void> setDnsApiToken(final String key) async {
|
||||
await getIt<ApiConfigModel>().storeDnsProviderKey(key);
|
||||
await getIt<ApiConfigModel>().setDnsProviderKey(key);
|
||||
}
|
||||
|
||||
Future<void> deleteDnsProviderKey() async {
|
||||
|
@ -525,7 +525,7 @@ class ServerInstallationRepository {
|
|||
}
|
||||
|
||||
Future<void> saveDomain(final ServerDomain serverDomain) async {
|
||||
await getIt<ApiConfigModel>().storeServerDomain(serverDomain);
|
||||
await getIt<ApiConfigModel>().setServerDomain(serverDomain);
|
||||
}
|
||||
|
||||
Future<void> deleteDomain() async {
|
||||
|
|
|
@ -6,7 +6,6 @@ import 'package:selfprivacy/config/get_it_config.dart';
|
|||
import 'package:selfprivacy/config/hive_config.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server_api.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_connection_dependent/server_connection_dependent_cubit.dart';
|
||||
import 'package:selfprivacy/logic/get_it/api_connection_repository.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/user.dart';
|
||||
|
||||
export 'package:provider/provider.dart';
|
||||
|
|
|
@ -42,47 +42,47 @@ class ApiConfigModel {
|
|||
_serverProvider = value;
|
||||
}
|
||||
|
||||
Future<void> storeDnsProviderType(final DnsProviderType value) async {
|
||||
Future<void> setDnsProviderType(final DnsProviderType value) async {
|
||||
await _box.put(BNames.dnsProvider, value);
|
||||
_dnsProvider = value;
|
||||
}
|
||||
|
||||
Future<void> storeServerProviderKey(final String value) async {
|
||||
Future<void> setServerProviderKey(final String value) async {
|
||||
await _box.put(BNames.hetznerKey, value);
|
||||
_serverProviderKey = value;
|
||||
}
|
||||
|
||||
Future<void> storeDnsProviderKey(final String value) async {
|
||||
Future<void> setDnsProviderKey(final String value) async {
|
||||
await _box.put(BNames.cloudFlareKey, value);
|
||||
_dnsProviderKey = value;
|
||||
}
|
||||
|
||||
Future<void> storeServerTypeIdentifier(final String typeIdentifier) async {
|
||||
Future<void> setServerTypeIdentifier(final String typeIdentifier) async {
|
||||
await _box.put(BNames.serverTypeIdentifier, typeIdentifier);
|
||||
_serverType = typeIdentifier;
|
||||
}
|
||||
|
||||
Future<void> storeServerLocation(final String serverLocation) async {
|
||||
Future<void> setServerLocation(final String serverLocation) async {
|
||||
await _box.put(BNames.serverLocation, serverLocation);
|
||||
_serverLocation = serverLocation;
|
||||
}
|
||||
|
||||
Future<void> storeBackblazeCredential(final BackupsCredential value) async {
|
||||
Future<void> setBackblazeCredential(final BackupsCredential value) async {
|
||||
await _box.put(BNames.backblazeCredential, value);
|
||||
_backblazeCredential = value;
|
||||
}
|
||||
|
||||
Future<void> storeServerDomain(final ServerDomain value) async {
|
||||
Future<void> setServerDomain(final ServerDomain value) async {
|
||||
await _box.put(BNames.serverDomain, value);
|
||||
_serverDomain = value;
|
||||
}
|
||||
|
||||
Future<void> storeServerDetails(final ServerHostingDetails value) async {
|
||||
Future<void> setServerDetails(final ServerHostingDetails value) async {
|
||||
await _box.put(BNames.serverDetails, value);
|
||||
_serverDetails = value;
|
||||
}
|
||||
|
||||
Future<void> storeBackblazeBucket(final BackblazeBucket value) async {
|
||||
Future<void> setBackblazeBucket(final BackblazeBucket value) async {
|
||||
await _box.put(BNames.backblazeBucket, value);
|
||||
_backblazeBucket = value;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:pub_semver/pub_semver.dart';
|
|||
import 'package:selfprivacy/config/get_it_config.dart';
|
||||
import 'package:selfprivacy/config/hive_config.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server_api.dart';
|
||||
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_job.dart';
|
||||
|
@ -15,7 +16,7 @@ class ApiConnectionRepository {
|
|||
Box box = Hive.box(BNames.serverInstallationBox);
|
||||
final ServerApi api = ServerApi();
|
||||
|
||||
final ApiData _apiData = ApiData();
|
||||
final ApiData _apiData = ApiData(ServerApi());
|
||||
|
||||
ApiData get apiData => _apiData;
|
||||
|
||||
|
@ -66,15 +67,18 @@ class ApiConnectionRepository {
|
|||
_connectionStatusStream.add(connectionStatus);
|
||||
return;
|
||||
} else {
|
||||
connectionStatus = ConnectionStatus.connected;
|
||||
_connectionStatusStream.add(connectionStatus);
|
||||
_apiData.apiVersion.data = apiVersion;
|
||||
_dataStream.add(_apiData);
|
||||
}
|
||||
|
||||
_apiData.serverJobs.data = await api.getServerJobs();
|
||||
_apiData.backupConfig.data = await api.getBackupsConfiguration();
|
||||
_apiData.backups.data = await api.getBackups();
|
||||
_dataStream.add(_apiData);
|
||||
|
||||
connectionStatus = ConnectionStatus.connected;
|
||||
_connectionStatusStream.add(connectionStatus);
|
||||
|
||||
// Use timer to periodically check for new jobs
|
||||
_timer = Timer.periodic(
|
||||
const Duration(seconds: 10),
|
||||
|
@ -82,7 +86,7 @@ class ApiConnectionRepository {
|
|||
);
|
||||
}
|
||||
|
||||
void reload(final Timer timer) async {
|
||||
Future<void> reload(final Timer? timer) async {
|
||||
final serverDetails = getIt<ApiConfigModel>().serverDetails;
|
||||
if (serverDetails == null) {
|
||||
return;
|
||||
|
@ -98,26 +102,42 @@ class ApiConnectionRepository {
|
|||
_connectionStatusStream.add(connectionStatus);
|
||||
_apiData.apiVersion.data = apiVersion;
|
||||
}
|
||||
final Version version = Version.parse(apiVersion);
|
||||
await _apiData.serverJobs
|
||||
.refetchData(version, () => _dataStream.add(_apiData));
|
||||
await _apiData.backups
|
||||
.refetchData(version, () => _dataStream.add(_apiData));
|
||||
await _apiData.backupConfig
|
||||
.refetchData(version, () => _dataStream.add(_apiData));
|
||||
}
|
||||
|
||||
if (VersionConstraint.parse(_apiData.apiVersion.requiredApiVersion)
|
||||
.allows(Version.parse(apiVersion))) {
|
||||
final jobs = await api.getServerJobs();
|
||||
if (Object.hashAll(_apiData.serverJobs.data ?? []) !=
|
||||
Object.hashAll(jobs)) {
|
||||
_apiData.serverJobs.data = [...jobs];
|
||||
_dataStream.add(_apiData);
|
||||
}
|
||||
}
|
||||
void emitData() {
|
||||
_dataStream.add(_apiData);
|
||||
}
|
||||
}
|
||||
|
||||
class ApiData {
|
||||
ApiData()
|
||||
: serverJobs = ApiDataElement<List<ServerJob>>(null),
|
||||
apiVersion = ApiDataElement<String>(null);
|
||||
ApiData(final ServerApi api)
|
||||
: apiVersion = ApiDataElement<String>(
|
||||
fetchData: () async => api.getApiVersion(),
|
||||
),
|
||||
serverJobs = ApiDataElement<List<ServerJob>>(
|
||||
fetchData: () async => api.getServerJobs(),
|
||||
ttl: 10,
|
||||
),
|
||||
backupConfig = ApiDataElement<BackupConfiguration>(
|
||||
fetchData: () async => api.getBackupsConfiguration(),
|
||||
requiredApiVersion: '>=2.4.2',
|
||||
),
|
||||
backups = ApiDataElement<List<Backup>>(
|
||||
fetchData: () async => api.getBackups(),
|
||||
requiredApiVersion: '>=2.4.2',
|
||||
);
|
||||
|
||||
ApiDataElement<List<ServerJob>> serverJobs;
|
||||
ApiDataElement<String> apiVersion;
|
||||
ApiDataElement<BackupConfiguration> backupConfig;
|
||||
ApiDataElement<List<Backup>> backups;
|
||||
}
|
||||
|
||||
enum ConnectionStatus {
|
||||
|
@ -129,8 +149,9 @@ enum ConnectionStatus {
|
|||
}
|
||||
|
||||
class ApiDataElement<T> {
|
||||
ApiDataElement(
|
||||
final T? data, {
|
||||
ApiDataElement({
|
||||
required this.fetchData,
|
||||
final T? data,
|
||||
this.requiredApiVersion = '>=2.3.0',
|
||||
this.ttl = 60,
|
||||
}) : _data = data,
|
||||
|
@ -139,9 +160,40 @@ class ApiDataElement<T> {
|
|||
T? _data;
|
||||
final String requiredApiVersion;
|
||||
|
||||
final Future<T?> Function() fetchData;
|
||||
|
||||
Future<void> refetchData(
|
||||
final Version version, final Function callback) async {
|
||||
if (VersionConstraint.parse(requiredApiVersion).allows(version)) {
|
||||
print('Fetching data for $runtimeType');
|
||||
if (isExpired) {
|
||||
print('Data is expired');
|
||||
final newData = await fetchData();
|
||||
print(newData);
|
||||
if (T is List) {
|
||||
if (Object.hashAll(newData as Iterable<Object?>) !=
|
||||
Object.hashAll(_data as Iterable<Object?>)) {
|
||||
_data = [...newData] as T?;
|
||||
}
|
||||
} else {
|
||||
if (newData.hashCode != _data.hashCode) {
|
||||
_data = newData;
|
||||
}
|
||||
}
|
||||
callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// TTL of the data in seconds
|
||||
final int ttl;
|
||||
|
||||
Type get type => T;
|
||||
|
||||
void invalidate() {
|
||||
_lastUpdated = DateTime.fromMillisecondsSinceEpoch(0);
|
||||
}
|
||||
|
||||
/// Timestamp of when the data was last updated
|
||||
DateTime _lastUpdated;
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:equatable/equatable.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/backups.graphql.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/schema.graphql.dart';
|
||||
|
@ -40,7 +41,7 @@ extension BackupReasonExtension on Enum$BackupReason {
|
|||
};
|
||||
}
|
||||
|
||||
class BackupConfiguration {
|
||||
class BackupConfiguration extends Equatable {
|
||||
BackupConfiguration.fromGraphQL(
|
||||
final Query$BackupConfiguration$backup$configuration configuration,
|
||||
) : this(
|
||||
|
@ -58,7 +59,7 @@ class BackupConfiguration {
|
|||
),
|
||||
);
|
||||
|
||||
BackupConfiguration({
|
||||
const BackupConfiguration({
|
||||
required this.autobackupPeriod,
|
||||
required this.encryptionKey,
|
||||
required this.isInitialized,
|
||||
|
@ -75,9 +76,39 @@ class BackupConfiguration {
|
|||
final String? locationName;
|
||||
final BackupsProviderType provider;
|
||||
final AutobackupQuotas autobackupQuotas;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
autobackupPeriod,
|
||||
encryptionKey,
|
||||
isInitialized,
|
||||
locationId,
|
||||
locationName,
|
||||
provider,
|
||||
autobackupQuotas,
|
||||
];
|
||||
|
||||
BackupConfiguration copyWith({
|
||||
final Duration? autobackupPeriod,
|
||||
final String? encryptionKey,
|
||||
final bool? isInitialized,
|
||||
final String? locationId,
|
||||
final String? locationName,
|
||||
final BackupsProviderType? provider,
|
||||
final AutobackupQuotas? autobackupQuotas,
|
||||
}) =>
|
||||
BackupConfiguration(
|
||||
autobackupPeriod: autobackupPeriod ?? this.autobackupPeriod,
|
||||
encryptionKey: encryptionKey ?? this.encryptionKey,
|
||||
isInitialized: isInitialized ?? this.isInitialized,
|
||||
locationId: locationId ?? this.locationId,
|
||||
locationName: locationName ?? this.locationName,
|
||||
provider: provider ?? this.provider,
|
||||
autobackupQuotas: autobackupQuotas ?? this.autobackupQuotas,
|
||||
);
|
||||
}
|
||||
|
||||
class AutobackupQuotas {
|
||||
class AutobackupQuotas extends Equatable {
|
||||
AutobackupQuotas.fromGraphQL(
|
||||
final Query$BackupConfiguration$backup$configuration$autobackupQuotas
|
||||
autobackupQuotas,
|
||||
|
@ -89,7 +120,7 @@ class AutobackupQuotas {
|
|||
yearly: autobackupQuotas.yearly,
|
||||
);
|
||||
|
||||
AutobackupQuotas({
|
||||
const AutobackupQuotas({
|
||||
required this.last,
|
||||
required this.daily,
|
||||
required this.weekly,
|
||||
|
@ -117,6 +148,15 @@ class AutobackupQuotas {
|
|||
monthly: monthly ?? this.monthly,
|
||||
yearly: yearly ?? this.yearly,
|
||||
);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
last,
|
||||
daily,
|
||||
weekly,
|
||||
monthly,
|
||||
yearly,
|
||||
];
|
||||
}
|
||||
|
||||
enum BackupRestoreStrategy {
|
||||
|
|
|
@ -29,4 +29,19 @@ class BackblazeBucket {
|
|||
|
||||
@override
|
||||
String toString() => bucketName;
|
||||
|
||||
BackblazeBucket copyWith({
|
||||
final String? bucketId,
|
||||
final String? applicationKeyId,
|
||||
final String? applicationKey,
|
||||
final String? bucketName,
|
||||
final String? encryptionKey,
|
||||
}) =>
|
||||
BackblazeBucket(
|
||||
bucketId: bucketId ?? this.bucketId,
|
||||
applicationKeyId: applicationKeyId ?? this.applicationKeyId,
|
||||
applicationKey: applicationKey ?? this.applicationKey,
|
||||
bucketName: bucketName ?? this.bucketName,
|
||||
encryptionKey: encryptionKey ?? this.encryptionKey,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||
import 'package:selfprivacy/config/brand_theme.dart';
|
||||
import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_jobs/server_jobs_bloc.dart';
|
||||
import 'package:selfprivacy/logic/bloc/server_jobs/server_jobs_bloc.dart';
|
||||
import 'package:selfprivacy/logic/models/json/server_job.dart';
|
||||
import 'package:selfprivacy/ui/components/buttons/brand_button.dart';
|
||||
import 'package:selfprivacy/ui/components/brand_loader/brand_loader.dart';
|
||||
|
|
|
@ -2,9 +2,9 @@ import 'package:auto_route/auto_route.dart';
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:selfprivacy/logic/bloc/backups/backups_bloc.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/backups/backups_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_jobs/server_jobs_bloc.dart';
|
||||
import 'package:selfprivacy/logic/bloc/server_jobs/server_jobs_bloc.dart';
|
||||
import 'package:selfprivacy/logic/cubit/services/services_cubit.dart';
|
||||
import 'package:selfprivacy/logic/models/backup.dart';
|
||||
import 'package:selfprivacy/logic/models/json/server_job.dart';
|
||||
|
@ -31,14 +31,13 @@ class BackupDetailsPage extends StatelessWidget {
|
|||
Widget build(final BuildContext context) {
|
||||
final bool isReady = context.watch<ServerInstallationCubit>().state
|
||||
is ServerInstallationFinished;
|
||||
final BackupsState backupsState = context.watch<BackupsCubit>().state;
|
||||
final BackupsState backupsState = context.watch<BackupsBloc>().state;
|
||||
final bool isBackupInitialized = backupsState.isInitialized;
|
||||
final StateType providerState = isReady && isBackupInitialized
|
||||
? StateType.stable
|
||||
: StateType.uninitialized;
|
||||
final bool preventActions = backupsState.preventActions;
|
||||
final List<Backup> backups = backupsState.backups;
|
||||
final bool refreshing = backupsState.refreshing;
|
||||
final List<Service> services =
|
||||
context.watch<ServicesCubit>().state.servicesThatCanBeBackedUp;
|
||||
final Duration? autobackupPeriod = backupsState.autobackupPeriod;
|
||||
|
@ -75,8 +74,10 @@ class BackupDetailsPage extends StatelessWidget {
|
|||
BrandButton.rised(
|
||||
onPressed: preventActions
|
||||
? null
|
||||
: () async {
|
||||
await context.read<BackupsCubit>().initializeBackups();
|
||||
: () {
|
||||
context
|
||||
.read<BackupsBloc>()
|
||||
.add(const InitializeBackupsRepository());
|
||||
},
|
||||
text: 'backup.initialize'.tr(),
|
||||
),
|
||||
|
@ -335,8 +336,10 @@ class BackupDetailsPage extends StatelessWidget {
|
|||
actionButtonTitle:
|
||||
'backup.forget_snapshot'.tr(),
|
||||
actionButtonOnPressed: () => {
|
||||
context.read<BackupsCubit>().forgetSnapshot(
|
||||
backup.id,
|
||||
context.read<BackupsBloc>().add(
|
||||
ForgetSnapshot(
|
||||
backup.id,
|
||||
),
|
||||
),
|
||||
},
|
||||
);
|
||||
|
@ -391,18 +394,6 @@ class BackupDetailsPage extends StatelessWidget {
|
|||
const SizedBox(height: 8),
|
||||
const Divider(),
|
||||
const SizedBox(height: 8),
|
||||
ListTile(
|
||||
title: Text(
|
||||
'backup.refresh'.tr(),
|
||||
),
|
||||
onTap: refreshing
|
||||
? null
|
||||
: () => {context.read<BackupsCubit>().updateBackups()},
|
||||
enabled: !refreshing,
|
||||
leading: const Icon(
|
||||
Icons.refresh_outlined,
|
||||
),
|
||||
),
|
||||
if (providerState != StateType.uninitialized)
|
||||
Column(
|
||||
children: [
|
||||
|
@ -425,7 +416,11 @@ class BackupDetailsPage extends StatelessWidget {
|
|||
),
|
||||
onTap: preventActions
|
||||
? null
|
||||
: () => {context.read<BackupsCubit>().forceUpdateBackups()},
|
||||
: () => {
|
||||
context
|
||||
.read<BackupsBloc>()
|
||||
.add(const ForceSnapshotListUpdate())
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
const Divider(),
|
||||
|
@ -447,9 +442,9 @@ class BackupDetailsPage extends StatelessWidget {
|
|||
Icons.warning_amber_outlined,
|
||||
color: overrideColor,
|
||||
),
|
||||
onTap: preventActions
|
||||
? null
|
||||
: () => {context.read<BackupsCubit>().reuploadKey()},
|
||||
// onTap: preventActions
|
||||
// ? null
|
||||
// : () => {context.read<BackupsCubit>().reuploadKey()},
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -3,7 +3,7 @@ import 'package:easy_localization/easy_localization.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:selfprivacy/logic/cubit/backups/backups_cubit.dart';
|
||||
import 'package:selfprivacy/logic/bloc/backups/backups_bloc.dart';
|
||||
import 'package:selfprivacy/logic/cubit/services/services_cubit.dart';
|
||||
import 'package:selfprivacy/logic/models/backup.dart';
|
||||
import 'package:selfprivacy/logic/models/service.dart';
|
||||
|
@ -25,10 +25,10 @@ class BackupsListPage extends StatelessWidget {
|
|||
// If the service is null, get all backups from state. If not null, call the
|
||||
// serviceBackups(serviceId) on the backups state.
|
||||
final List<Backup> backups = service == null
|
||||
? context.watch<BackupsCubit>().state.backups
|
||||
: context.watch<BackupsCubit>().state.serviceBackups(service!.id);
|
||||
? context.watch<BackupsBloc>().state.backups
|
||||
: context.watch<BackupsBloc>().state.serviceBackups(service!.id);
|
||||
final bool preventActions =
|
||||
context.watch<BackupsCubit>().state.preventActions;
|
||||
context.watch<BackupsBloc>().state.preventActions;
|
||||
return BrandHeroScreen(
|
||||
heroTitle: 'backup.snapshots_title'.tr(),
|
||||
hasFlashButton: true,
|
||||
|
@ -76,9 +76,9 @@ class BackupsListPage extends StatelessWidget {
|
|||
description: 'backup.forget_snapshot_alert'.tr(),
|
||||
actionButtonTitle: 'backup.forget_snapshot'.tr(),
|
||||
actionButtonOnPressed: () => {
|
||||
context.read<BackupsCubit>().forgetSnapshot(
|
||||
backup.id,
|
||||
),
|
||||
context
|
||||
.read<BackupsBloc>()
|
||||
.add(ForgetSnapshot(backup.id)),
|
||||
},
|
||||
);
|
||||
},
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:selfprivacy/logic/bloc/backups/backups_bloc.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/backups/backups_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_jobs/server_jobs_bloc.dart';
|
||||
import 'package:selfprivacy/logic/bloc/server_jobs/server_jobs_bloc.dart';
|
||||
import 'package:selfprivacy/utils/extensions/duration.dart';
|
||||
|
||||
class ChangeAutobackupsPeriodModal extends StatefulWidget {
|
||||
|
@ -34,13 +34,13 @@ class _ChangeAutobackupsPeriodModalState
|
|||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
selectedPeriod = context.read<BackupsCubit>().state.autobackupPeriod;
|
||||
selectedPeriod = context.read<BackupsBloc>().state.autobackupPeriod;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(final BuildContext context) {
|
||||
final Duration? initialAutobackupPeriod =
|
||||
context.watch<BackupsCubit>().state.autobackupPeriod;
|
||||
context.watch<BackupsBloc>().state.autobackupPeriod;
|
||||
return ListView(
|
||||
controller: widget.scrollController,
|
||||
padding: const EdgeInsets.all(16),
|
||||
|
@ -91,8 +91,8 @@ class _ChangeAutobackupsPeriodModalState
|
|||
? null
|
||||
: () {
|
||||
context
|
||||
.read<BackupsCubit>()
|
||||
.setAutobackupPeriod(selectedPeriod);
|
||||
.read<BackupsBloc>()
|
||||
.add(SetAutobackupPeriod(selectedPeriod));
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:selfprivacy/logic/bloc/backups/backups_bloc.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/backups/backups_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_jobs/server_jobs_bloc.dart';
|
||||
import 'package:selfprivacy/logic/bloc/server_jobs/server_jobs_bloc.dart';
|
||||
import 'package:selfprivacy/logic/models/backup.dart';
|
||||
|
||||
class ChangeRotationQuotasModal extends StatefulWidget {
|
||||
|
@ -27,7 +27,7 @@ enum QuotaUnits {
|
|||
}
|
||||
|
||||
class _ChangeRotationQuotasModalState extends State<ChangeRotationQuotasModal> {
|
||||
AutobackupQuotas selectedQuotas = AutobackupQuotas(
|
||||
AutobackupQuotas selectedQuotas = const AutobackupQuotas(
|
||||
last: 3,
|
||||
daily: 7,
|
||||
weekly: 4,
|
||||
|
@ -40,7 +40,7 @@ class _ChangeRotationQuotasModalState extends State<ChangeRotationQuotasModal> {
|
|||
void initState() {
|
||||
super.initState();
|
||||
selectedQuotas =
|
||||
context.read<BackupsCubit>().state.autobackupQuotas ?? selectedQuotas;
|
||||
context.read<BackupsBloc>().state.autobackupQuotas ?? selectedQuotas;
|
||||
}
|
||||
|
||||
String generateSubtitle(final int value, final QuotaUnits unit) {
|
||||
|
@ -83,7 +83,7 @@ class _ChangeRotationQuotasModalState extends State<ChangeRotationQuotasModal> {
|
|||
@override
|
||||
Widget build(final BuildContext context) {
|
||||
final AutobackupQuotas? initialAutobackupQuotas =
|
||||
context.watch<BackupsCubit>().state.autobackupQuotas;
|
||||
context.watch<BackupsBloc>().state.autobackupQuotas;
|
||||
return ListView(
|
||||
controller: widget.scrollController,
|
||||
padding: const EdgeInsets.all(16),
|
||||
|
@ -190,8 +190,8 @@ class _ChangeRotationQuotasModalState extends State<ChangeRotationQuotasModal> {
|
|||
? null
|
||||
: () {
|
||||
context
|
||||
.read<BackupsCubit>()
|
||||
.setAutobackupQuotas(selectedQuotas);
|
||||
.read<BackupsBloc>()
|
||||
.add(SetAutobackupQuotas(selectedQuotas));
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(
|
||||
|
|
|
@ -2,9 +2,9 @@ import 'dart:async';
|
|||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:selfprivacy/logic/bloc/backups/backups_bloc.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/backups/backups_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_jobs/server_jobs_bloc.dart';
|
||||
import 'package:selfprivacy/logic/bloc/server_jobs/server_jobs_bloc.dart';
|
||||
import 'package:selfprivacy/ui/components/info_box/info_box.dart';
|
||||
import 'package:selfprivacy/utils/platform_adapter.dart';
|
||||
|
||||
|
@ -34,7 +34,7 @@ class _CopyEncryptionKeyModalState extends State<CopyEncryptionKeyModal> {
|
|||
@override
|
||||
Widget build(final BuildContext context) {
|
||||
final String? encryptionKey =
|
||||
context.watch<BackupsCubit>().state.backblazeBucket?.encryptionKey;
|
||||
context.watch<BackupsBloc>().state.backblazeBucket?.encryptionKey;
|
||||
if (encryptionKey == null) {
|
||||
return ListView(
|
||||
controller: widget.scrollController,
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:selfprivacy/logic/cubit/backups/backups_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_jobs/server_jobs_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/models/json/server_job.dart';
|
||||
import 'package:selfprivacy/logic/models/service.dart';
|
||||
|
||||
|
@ -147,8 +147,8 @@ class _CreateBackupsModalState extends State<CreateBackupsModal> {
|
|||
? null
|
||||
: () {
|
||||
context
|
||||
.read<BackupsCubit>()
|
||||
.createMultipleBackups(selectedServices);
|
||||
.read<BackupsBloc>()
|
||||
.add(CreateBackups(selectedServices));
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(
|
||||
|
|
|
@ -2,8 +2,8 @@ import 'package:easy_localization/easy_localization.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:selfprivacy/config/get_it_config.dart';
|
||||
import 'package:selfprivacy/logic/cubit/backups/backups_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_jobs/server_jobs_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/cubit/services/services_cubit.dart';
|
||||
import 'package:selfprivacy/logic/models/backup.dart';
|
||||
import 'package:selfprivacy/logic/models/json/server_job.dart';
|
||||
|
@ -153,10 +153,8 @@ class _SnapshotModalState extends State<SnapshotModal> {
|
|||
onPressed: isServiceBusy
|
||||
? null
|
||||
: () {
|
||||
context.read<BackupsCubit>().restoreBackup(
|
||||
widget.snapshot.id,
|
||||
selectedStrategy,
|
||||
);
|
||||
context.read<BackupsBloc>().add(RestoreBackup(
|
||||
widget.snapshot.id, selectedStrategy));
|
||||
Navigator.of(context).pop();
|
||||
getIt<NavigationService>()
|
||||
.showSnackBar('backup.restore_started'.tr());
|
||||
|
|
|
@ -5,7 +5,6 @@ import 'package:selfprivacy/logic/api_maps/tls_options.dart';
|
|||
import 'package:selfprivacy/logic/cubit/app_settings/app_settings_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/devices/devices_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/recovery_key/recovery_key_cubit.dart';
|
||||
import 'package:selfprivacy/logic/get_it/api_connection_repository.dart';
|
||||
import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import 'package:auto_route/auto_route.dart';
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:selfprivacy/config/brand_theme.dart';
|
||||
import 'package:selfprivacy/logic/cubit/backups/backups_cubit.dart';
|
||||
import 'package:selfprivacy/logic/bloc/backups/backups_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';
|
||||
|
@ -30,7 +30,7 @@ class _ProvidersPageState extends State<ProvidersPage> {
|
|||
final bool isReady = context.watch<ServerInstallationCubit>().state
|
||||
is ServerInstallationFinished;
|
||||
final bool isBackupInitialized =
|
||||
context.watch<BackupsCubit>().state.isInitialized;
|
||||
context.watch<BackupsBloc>().state.isInitialized;
|
||||
final DnsRecordsStatus dnsStatus =
|
||||
context.watch<DnsRecordsCubit>().state.dnsState;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_jobs/server_jobs_bloc.dart';
|
||||
import 'package:selfprivacy/logic/bloc/server_jobs/server_jobs_bloc.dart';
|
||||
import 'package:selfprivacy/logic/cubit/services/services_cubit.dart';
|
||||
import 'package:selfprivacy/logic/models/disk_size.dart';
|
||||
import 'package:selfprivacy/logic/models/service.dart';
|
||||
|
|
Loading…
Reference in a new issue