feat: Implement clean wizard backups initialization

This commit is contained in:
NaiJi 2023-10-04 05:54:42 -03:00
parent 757bf27dc8
commit 0573dc8221
5 changed files with 69 additions and 34 deletions

View file

@ -288,13 +288,13 @@
}, },
"yearly_infinite": "All yearly backups will be kept" "yearly_infinite": "All yearly backups will be kept"
}, },
"steps": { "wizard": {
"hosting": "Storage Provider", "initialize_settings_title": "Backup Settings",
"period": "Automatic backups", "steps": {
"rotation": "Rotation settings" "hosting": "Storage Provider",
}, "settings": "Settings",
"settings": { "confirmation": "Confirmation"
"initialize_settings_title": "Backup Settings" }
} }
}, },
"storage": { "storage": {

View file

@ -65,8 +65,13 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
); );
} }
Future<void> initializeBackups() async { Future<void> initializeBackups(
final BackupsCredential backupsCredential,
final AutobackupQuotas quotas,
final Duration? autobackupPeriod,
) async {
emit(state.copyWith(preventActions: true)); emit(state.copyWith(preventActions: true));
await getIt<ApiConfigModel>().storeBackblazeCredential(backupsCredential);
final String? encryptionKey = final String? encryptionKey =
(await api.getBackupsConfiguration())?.encryptionKey; (await api.getBackupsConfiguration())?.encryptionKey;
if (encryptionKey == null) { if (encryptionKey == null) {
@ -125,6 +130,9 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
'Backups repository is now initializing. It may take a while.', 'Backups repository is now initializing. It may take a while.',
); );
await setAutobackupPeriod(autobackupPeriod);
await setAutobackupQuotas(quotas);
emit(state.copyWith(preventActions: false)); emit(state.copyWith(preventActions: false));
} }
@ -292,6 +300,37 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
await updateBackups(); await updateBackups();
} }
Future<void> recoverState(final BackupsCredential backupsCredential) async {
BackblazeBucket? bucket;
BackupConfiguration? backupConfig;
try {
backupConfig = await ServerApi().getBackupsConfiguration();
await getIt<ApiConfigModel>().storeBackblazeCredential(backupsCredential);
final bucket = await BackblazeApi()
.fetchBucket(state.backupsCredential!, backupConfig!);
await getIt<ApiConfigModel>().storeBackblazeBucket(bucket!);
} catch (e) {
print(e);
getIt<NavigationService>().showSnackBar('jobs.generic_error'.tr());
return;
}
final List<Backup> backups = await api.getBackups();
backups.sort((final a, final b) => b.time.compareTo(a.time));
emit(
state.copyWith(
backupsCredential: backupsCredential,
backblazeBucket: bucket,
isInitialized: backupConfig.isInitialized,
autobackupPeriod: backupConfig.autobackupPeriod ?? Duration.zero,
autobackupQuotas: backupConfig.autobackupQuotas,
backups: backups,
preventActions: false,
refreshing: false,
),
);
}
@override @override
void clear() async { void clear() async {
emit(const BackupsState()); emit(const BackupsState());

View file

@ -1,10 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:cubit_form/cubit_form.dart'; import 'package:cubit_form/cubit_form.dart';
import 'package:easy_localization/easy_localization.dart';
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/graphql_maps/server_api/server_api.dart';
import 'package:selfprivacy/logic/api_maps/rest_maps/backblaze.dart';
import 'package:selfprivacy/logic/models/backup.dart'; import 'package:selfprivacy/logic/models/backup.dart';
import 'package:selfprivacy/logic/models/hive/backups_credential.dart'; import 'package:selfprivacy/logic/models/hive/backups_credential.dart';
@ -13,10 +10,8 @@ part 'backups_wizard_state.dart';
class BackupsWizardCubit extends Cubit<BackupsWizardState> { class BackupsWizardCubit extends Cubit<BackupsWizardState> {
BackupsWizardCubit() : super(const BackupsWizardState()); BackupsWizardCubit() : super(const BackupsWizardState());
BackupConfiguration? serverBackupConfig;
Future<void> load() async { Future<void> load() async {
serverBackupConfig = await ServerApi().getBackupsConfiguration(); final serverBackupConfig = await ServerApi().getBackupsConfiguration();
/// If config already exists, then user only lacks credentials, /// If config already exists, then user only lacks credentials,
/// we don't need full re-initialization /// we don't need full re-initialization
@ -60,19 +55,7 @@ class BackupsWizardCubit extends Cubit<BackupsWizardState> {
); );
} }
void recoverBackupsInformation() async { void finish() async {
try {
await getIt<ApiConfigModel>()
.storeBackblazeCredential(state.backupsCredential!);
final bucket = await BackblazeApi()
.fetchBucket(state.backupsCredential!, serverBackupConfig!);
await getIt<ApiConfigModel>().storeBackblazeBucket(bucket!);
} catch (e) {
print(e);
getIt<NavigationService>().showSnackBar('jobs.generic_error'.tr());
return;
}
emit( emit(
state.copyWith( state.copyWith(
currentStep: BackupsWizardStep.finished, currentStep: BackupsWizardStep.finished,

View file

@ -1,16 +1,18 @@
import 'package:cubit_form/cubit_form.dart'; import 'package:cubit_form/cubit_form.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:selfprivacy/logic/cubit/backups/backups_cubit.dart';
import 'package:selfprivacy/logic/cubit/backups_wizard/backups_wizard_cubit.dart'; import 'package:selfprivacy/logic/cubit/backups_wizard/backups_wizard_cubit.dart';
import 'package:selfprivacy/ui/components/buttons/brand_button.dart'; import 'package:selfprivacy/ui/components/buttons/brand_button.dart';
import 'package:selfprivacy/ui/layouts/responsive_layout_with_infobox.dart'; import 'package:selfprivacy/ui/layouts/responsive_layout_with_infobox.dart';
class BackupConfirmationPage extends StatelessWidget { class BackupConfirmationPage extends StatelessWidget {
const BackupConfirmationPage({ const BackupConfirmationPage({
required this.onConfirmCallback,
super.key, super.key,
}); });
final Function() onConfirmCallback;
@override @override
Widget build(final BuildContext context) => ResponsiveLayoutWithInfobox( Widget build(final BuildContext context) => ResponsiveLayoutWithInfobox(
topChild: Column( topChild: Column(
@ -27,9 +29,10 @@ class BackupConfirmationPage extends StatelessWidget {
children: [ children: [
const SizedBox(height: 32), const SizedBox(height: 32),
BrandButton.rised( BrandButton.rised(
onPressed: () => context onPressed: () {
.read<BackupsWizardCubit>() onConfirmCallback();
.recoverBackupsInformation(), context.read<BackupsWizardCubit>().finish();
},
text: 'basis.connect'.tr(), text: 'basis.connect'.tr(),
), ),
const SizedBox(height: 10), const SizedBox(height: 10),

View file

@ -30,11 +30,22 @@ class BackupsInitializingPage extends StatelessWidget {
final currentStep = cubit.state.currentStep; final currentStep = cubit.state.currentStep;
switch (currentStep) { switch (currentStep) {
case BackupsWizardStep.confirmInitialization: case BackupsWizardStep.confirmInitialization:
actualInitializingPage = const BackupConfirmationPage(); actualInitializingPage = BackupConfirmationPage(
onConfirmCallback: () =>
context.read<BackupsCubit>().initializeBackups(
cubit.state.backupsCredential!,
cubit.state.autobackupQuotas!,
cubit.state.autobackupPeriod,
),
);
progressDrawerStep = 2; progressDrawerStep = 2;
break; break;
case BackupsWizardStep.confirmRecovery: case BackupsWizardStep.confirmRecovery:
actualInitializingPage = const BackupConfirmationPage(); actualInitializingPage = BackupConfirmationPage(
onConfirmCallback: () => context
.read<BackupsCubit>()
.recoverState(cubit.state.backupsCredential!),
);
progressDrawerStep = 2; progressDrawerStep = 2;
break; break;
case BackupsWizardStep.settingsInitialization: case BackupsWizardStep.settingsInitialization:
@ -73,7 +84,6 @@ class BackupsInitializingPage extends StatelessWidget {
return BlocListener<BackupsWizardCubit, BackupsWizardState>( return BlocListener<BackupsWizardCubit, BackupsWizardState>(
listener: (final context, final state) { listener: (final context, final state) {
if (cubit.state.currentStep == BackupsWizardStep.finished) { if (cubit.state.currentStep == BackupsWizardStep.finished) {
context.read<BackupsCubit>().load();
context.router.popUntilRoot(); context.router.popUntilRoot();
} }
}, },