Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge #1

Merged
merged 15 commits into from
Nov 29, 2023
Merged
Prev Previous commit
feat: restore backups on first installation namidaco#69
  • Loading branch information
MSOB7YY committed Nov 28, 2023
commit c6cb1343f1320b596734e8e485c144bedf270ecb
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