Skip to content

Commit

Permalink
feat: restore backups on first installation #69
Browse files Browse the repository at this point in the history
  • Loading branch information
MSOB7YY committed Nov 28, 2023
1 parent 57d3758 commit c6cb134
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 69 deletions.
10 changes: 8 additions & 2 deletions lib/controller/backup_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ class BackupController {
String get _backupDirectoryPath => settings.defaultBackupLocation.value;

Future<void> createBackupFile(List<String> backupItemsPaths) async {
if (isCreatingBackup.value) return snackyy(title: lang.NOTE, message: lang.ANOTHER_PROCESS_IS_RUNNING);

if (!await requestManageStoragePermission()) {
return;
}
Expand All @@ -38,8 +40,10 @@ class BackupController {
final format = DateFormat('yyyy-MM-dd hh.mm.ss');
final date = format.format(DateTime.now().toLocal());

final backupDirPath = _backupDirectoryPath;

// creates directories and file
final dir = await Directory(_backupDirectoryPath).create();
final dir = await Directory(backupDirPath).create();
await File("${dir.path}/Namida Backup - $date.zip").create();
final sourceDir = Directory(AppDirs.USER_DATA);

Expand Down Expand Up @@ -83,7 +87,7 @@ class BackupController {
await ZipFile.createFromFiles(sourceDir: sourceDir, files: youtubeFilesOnly, zipFile: tempAllYoutube);
}

final zipFile = File("$_backupDirectoryPath/Namida Backup - $date.zip");
final zipFile = File("$backupDirPath/Namida Backup - $date.zip");
final allFiles = [
if (tempAllLocal != null) tempAllLocal,
if (tempAllYoutube != null) tempAllYoutube,
Expand Down Expand Up @@ -127,6 +131,8 @@ class BackupController {
}

Future<void> restoreBackupOnTap(bool auto) async {
if (isRestoringBackup.value) return snackyy(title: lang.NOTE, message: lang.ANOTHER_PROCESS_IS_RUNNING);

File? backupzip;
if (auto) {
final sortedFiles = await _getBackupFilesSorted.thready(_backupDirectoryPath);
Expand Down
2 changes: 1 addition & 1 deletion lib/core/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class AppDirs {

// ================= Internal Storage =================
static final SAVED_ARTWORKS = '$INTERNAL_STORAGE/Artworks/';
static final BACKUPS = '$INTERNAL_STORAGE/Backups/';
static final BACKUPS = '$INTERNAL_STORAGE/Backups'; // only one without ending slash.
static final COMPRESSED_IMAGES = '$INTERNAL_STORAGE/Compressed/';
static final M3UPlaylists = '$INTERNAL_STORAGE/M3U Playlists/';
static final YOUTUBE_DOWNLOADS = '$INTERNAL_STORAGE/Downloads/';
Expand Down
44 changes: 44 additions & 0 deletions lib/ui/pages/onboarding.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import 'package:namida/controller/backup_controller.dart';
import 'package:namida/controller/current_color.dart';
import 'package:namida/controller/indexer_controller.dart';
import 'package:namida/controller/navigator_controller.dart';
Expand All @@ -12,6 +13,7 @@ import 'package:namida/main.dart';
import 'package:namida/main_page_wrapper.dart';
import 'package:namida/ui/widgets/custom_widgets.dart';
import 'package:namida/ui/widgets/settings/advanced_settings.dart';
import 'package:namida/ui/widgets/settings/backup_restore_settings.dart';
import 'package:namida/ui/widgets/settings/extra_settings.dart';
import 'package:namida/ui/widgets/settings/indexer_settings.dart';
import 'package:namida/ui/widgets/settings/theme_settings.dart';
Expand Down Expand Up @@ -78,6 +80,31 @@ class _FirstRunConfigureScreenState extends State<FirstRunConfigureScreen> {
QueueController.inst.prepareLatestQueue();
}

void _onRestoreBackupIconTap() async {
await _requestPermission();
if (!didGrantStoragePermission) return;
const backupAndRestore = BackupAndRestore();
NamidaNavigator.inst.navigateDialog(
dialog: CustomBlurryDialog(
icon: Broken.refresh_circle,
normalTitleStyle: true,
title: lang.BACKUP_AND_RESTORE,
actions: [
NamidaButton(
text: lang.DONE,
onPressed: NamidaNavigator.inst.closeDialog,
),
],
child: Column(
children: [
backupAndRestore.getRestoreBackupWidget(),
backupAndRestore.getDefaultBackupLocationWidget(),
],
),
),
);
}

@override
Widget build(BuildContext context) {
const indexer = IndexerSettings();
Expand Down Expand Up @@ -107,6 +134,20 @@ class _FirstRunConfigureScreenState extends State<FirstRunConfigureScreen> {
icon: Broken.candle,
title: lang.CONFIGURE,
subtitle: lang.SETUP_FIRST_STARTUP,
trailing: Column(
children: [
NamidaIconButton(
tooltip: lang.RESTORE_BACKUP,
icon: Broken.back_square,
onPressed: _onRestoreBackupIconTap,
),
const SizedBox(height: 2.0),
ObxShow(
showIf: BackupController.inst.isRestoringBackup,
child: const LoadingIndicator(),
),
],
),
childRaw: Expanded(
child: Padding(
padding: const EdgeInsets.all(4.0),
Expand Down Expand Up @@ -199,6 +240,9 @@ class _FirstRunConfigureScreenState extends State<FirstRunConfigureScreen> {
width: context.width * 0.2,
onTap: () async {
await _requestPermission();
if (BackupController.inst.isRestoringBackup.value) {
return snackyy(title: lang.NOTE, message: lang.ANOTHER_PROCESS_IS_RUNNING);
}
_navigateToNamida();
},
borderRadius: 8.0,
Expand Down
149 changes: 83 additions & 66 deletions lib/ui/widgets/settings/backup_restore_settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import 'package:namida/core/enums.dart';
import 'package:namida/core/extensions.dart';
import 'package:namida/core/icon_fonts/broken_icons.dart';
import 'package:namida/core/translations/language.dart';
import 'package:namida/main.dart';
import 'package:namida/ui/widgets/custom_widgets.dart';
import 'package:namida/ui/widgets/circular_percentages.dart';
import 'package:namida/ui/widgets/settings/extra_settings.dart';
Expand Down Expand Up @@ -63,6 +64,82 @@ class BackupAndRestore extends SettingSubpageProvider {
);
}

Widget getRestoreBackupWidget() {
return getItemWrapper(
key: _BackupAndRestoreKeys.restore,
child: CustomListTile(
bgColor: getBgColor(_BackupAndRestoreKeys.restore),
title: lang.RESTORE_BACKUP,
icon: Broken.back_square,
trailingRaw: ObxShow(
showIf: BackupController.inst.isRestoringBackup,
child: const LoadingIndicator(),
),
onTap: () async {
if (BackupController.inst.isRestoringBackup.value) {
return snackyy(title: lang.NOTE, message: lang.ANOTHER_PROCESS_IS_RUNNING);
}

NamidaNavigator.inst.navigateDialog(
dialog: CustomBlurryDialog(
normalTitleStyle: true,
title: lang.RESTORE_BACKUP,
child: SingleChildScrollView(
child: Column(
children: [
CustomListTile(
title: lang.AUTOMATIC_BACKUP,
subtitle: lang.AUTOMATIC_BACKUP_SUBTITLE,
icon: Broken.autobrightness,
maxSubtitleLines: 22,
onTap: () async {
if (!await requestManageStoragePermission()) return;

NamidaNavigator.inst.closeDialog();
BackupController.inst.restoreBackupOnTap(true);
},
),
CustomListTile(
title: lang.MANUAL_BACKUP,
subtitle: lang.MANUAL_BACKUP_SUBTITLE,
maxSubtitleLines: 22,
icon: Broken.hashtag,
onTap: () {
NamidaNavigator.inst.closeDialog();
BackupController.inst.restoreBackupOnTap(false);
},
),
],
),
),
),
);
},
),
);
}

Widget getDefaultBackupLocationWidget() {
return getItemWrapper(
key: _BackupAndRestoreKeys.defaultLocation,
child: Obx(
() => CustomListTile(
bgColor: getBgColor(_BackupAndRestoreKeys.defaultLocation),
title: lang.DEFAULT_BACKUP_LOCATION,
icon: Broken.direct_inbox,
subtitle: settings.defaultBackupLocation.value,
onTap: () async {
final path = await FilePicker.platform.getDirectoryPath();

if (path != null) {
settings.save(defaultBackupLocation: path);
}
},
),
),
);
}

@override
Widget build(BuildContext context) {
return SettingsCard(
Expand All @@ -85,6 +162,10 @@ class BackupAndRestore extends SettingSubpageProvider {
child: const LoadingIndicator(),
),
onTap: () {
if (BackupController.inst.isCreatingBackup.value) {
return snackyy(title: lang.NOTE, message: lang.ANOTHER_PROCESS_IS_RUNNING);
}

bool isActive(List<String> items) => items.every((element) => settings.backupItemslist.contains(element));

void onItemTap(List<String> items) {
Expand Down Expand Up @@ -376,74 +457,10 @@ class BackupAndRestore extends SettingSubpageProvider {
),

// -- Restore Backup
getItemWrapper(
key: _BackupAndRestoreKeys.restore,
child: CustomListTile(
bgColor: getBgColor(_BackupAndRestoreKeys.restore),
title: lang.RESTORE_BACKUP,
icon: Broken.back_square,
trailingRaw: ObxShow(
showIf: BackupController.inst.isRestoringBackup,
child: const LoadingIndicator(),
),
onTap: () async {
NamidaNavigator.inst.navigateDialog(
dialog: CustomBlurryDialog(
normalTitleStyle: true,
title: lang.RESTORE_BACKUP,
child: SingleChildScrollView(
child: Column(
children: [
CustomListTile(
title: lang.AUTOMATIC_BACKUP,
subtitle: lang.AUTOMATIC_BACKUP_SUBTITLE,
icon: Broken.autobrightness,
maxSubtitleLines: 22,
onTap: () async {
if (!await requestManageStoragePermission()) return;

NamidaNavigator.inst.closeDialog();
BackupController.inst.restoreBackupOnTap(true);
},
),
CustomListTile(
title: lang.MANUAL_BACKUP,
subtitle: lang.MANUAL_BACKUP_SUBTITLE,
maxSubtitleLines: 22,
icon: Broken.hashtag,
onTap: () {
NamidaNavigator.inst.closeDialog();
BackupController.inst.restoreBackupOnTap(false);
},
),
],
),
),
),
);
},
),
),
getRestoreBackupWidget(),

// -- Default Backup Location
getItemWrapper(
key: _BackupAndRestoreKeys.defaultLocation,
child: Obx(
() => CustomListTile(
bgColor: getBgColor(_BackupAndRestoreKeys.defaultLocation),
title: lang.DEFAULT_BACKUP_LOCATION,
icon: Broken.direct_inbox,
subtitle: settings.defaultBackupLocation.value,
onTap: () async {
final path = await FilePicker.platform.getDirectoryPath();

if (path != null) {
settings.save(defaultBackupLocation: path);
}
},
),
),
),
getDefaultBackupLocationWidget(),

// -- Import Youtube History
getItemWrapper(
Expand Down

0 comments on commit c6cb134

Please sign in to comment.