Fix automatic backups - 1.181 🚀

- The broadcast intent wasn't receiving the target directory
- Add separate button for storing the backup location
This commit is contained in:
Brandon Presley 2023-11-13 15:15:18 +13:00
parent d0c0a52ab4
commit b6afbfcc17
7 changed files with 55 additions and 16 deletions

View File

@ -86,6 +86,13 @@ export default function SettingsPage() {
.execute();
}, []);
const backupString = useMemo(() => {
if (!settings.backupDir) return null;
console.log(settings.backupDir);
const split = decodeURIComponent(settings.backupDir).split(":");
return split.pop();
}, [settings.backupDir]);
const soundString = useMemo(() => {
if (!settings.sound) return null;
const split = settings.sound.split("/");
@ -108,15 +115,8 @@ export default function SettingsPage() {
await AppDataSource.initialize();
await setRepo.createQueryBuilder().update().set({ image: null }).execute();
await update("sound", null);
const { alarm, backup } = await settingsRepo.findOne({ where: {} });
console.log({ backup });
const directory = await DocumentPicker.pickDirectory();
if (backup) NativeModules.BackupModule.start(directory.uri);
else NativeModules.BackupModule.stop();
NativeModules.SettingsModule.ignoringBattery((isIgnoring: boolean) => {
if (alarm && !isIgnoring) NativeModules.SettingsModule.ignoreBattery();
reset({ index: 0, routes: [{ name: "Settings" }] });
});
await update("backup", false);
reset({ index: 0, routes: [{ name: "Settings" }] });
}, [reset, update]);
const today = new Date();
@ -363,6 +363,9 @@ export default function SettingsPage() {
await update("backup", value);
if (value) {
const result = await DocumentPicker.pickDirectory();
setValue("backupDir", result.uri);
await update("backupDir", result.uri);
console.log(`${SettingsPage.name}.backup:`, { result });
toast("Backup database daily.");
NativeModules.BackupModule.start(result.uri);
} else {
@ -374,6 +377,25 @@ export default function SettingsPage() {
/>
),
},
{
name: `Backup directory: ${backupString || "Downloads"}`,
renderItem: (name: string) => (
<Button
style={{ alignSelf: "flex-start" }}
onPress={async () => {
const result = await DocumentPicker.pickDirectory();
setValue("backupDir", result.uri);
await update("backupDir", result.uri);
toast("Changed backup directory.");
if (!settings.backup) return;
NativeModules.BackupModule.stop();
NativeModules.BackupModule.start(result.uri);
}}
>
{name}
</Button>
),
},
{
name: `Alarm sound: ${soundString || "Default"}`,
renderItem: (name: string) => (

View File

@ -85,8 +85,8 @@ android {
applicationId "com.massive"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 36206
versionName "1.180"
versionCode 36207
versionName "1.181"
}
signingConfigs {
release {

View File

@ -5,6 +5,7 @@ import android.app.PendingIntent
import android.content.*
import android.net.Uri
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.documentfile.provider.DocumentFile
import com.facebook.react.bridge.ReactApplicationContext
@ -16,11 +17,12 @@ import java.util.*
class BackupModule constructor(context: ReactApplicationContext?) :
ReactContextBaseJavaModule(context) {
val context: ReactApplicationContext = reactApplicationContext
private var targetDir: String? = null
private val copyReceiver = object : BroadcastReceiver() {
@RequiresApi(Build.VERSION_CODES.O)
override fun onReceive(context: Context?, intent: Intent?) {
val targetDir = intent?.getStringExtra("targetDir");
Log.d("BackupModule", "onReceive $targetDir")
val treeUri: Uri = Uri.parse(targetDir)
val documentFile = context?.let { DocumentFile.fromTreeUri(it, treeUri) }
val file = documentFile?.createFile("application/octet-stream", "massive.db")
@ -38,11 +40,12 @@ class BackupModule constructor(context: ReactApplicationContext?) :
@RequiresApi(Build.VERSION_CODES.M)
@ReactMethod
fun start(baseUri: String) {
targetDir = baseUri
Log.d("BackupModule", "start $baseUri")
val alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val intent = Intent(COPY_BROADCAST)
intent.putExtra("targetDir", baseUri)
val pendingIntent =
PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
PendingIntent.getBroadcast(context, baseUri.hashCode(), intent, PendingIntent.FLAG_IMMUTABLE)
pendingIntent.send()
val calendar = Calendar.getInstance().apply {
@ -61,7 +64,7 @@ class BackupModule constructor(context: ReactApplicationContext?) :
}
@RequiresApi(Build.VERSION_CODES.M)
@ReactMethod
@ReactMethod(isBlockingSynchronousMethod = true)
fun stop() {
val alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val intent = Intent(COPY_BROADCAST)

View File

@ -34,6 +34,7 @@ import { Plan } from "./plan";
import Settings from "./settings";
import Weight from "./weight";
import { settingsStartup1699783784680 } from "./migrations/1699783784680-settings-startup";
import { settingsBackupDir1699839054226 } from "./migrations/1699839054226-settings-backup-dir";
export const AppDataSource = new DataSource({
type: "react-native",
@ -74,5 +75,6 @@ export const AppDataSource = new DataSource({
exercisesFix1699613077628,
settingsDuration1699743753975,
settingsStartup1699783784680,
settingsBackupDir1699839054226,
],
});

View File

@ -0,0 +1,9 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class settingsBackupDir1699839054226 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query("ALTER TABLE settings ADD COLUMN backupDir TEXT");
}
public async down(queryRunner: QueryRunner): Promise<void> {}
}

View File

@ -1,6 +1,6 @@
{
"name": "massive",
"version": "1.180",
"version": "1.181",
"private": true,
"license": "GPL-3.0-only",
"scripts": {

View File

@ -47,6 +47,9 @@ export default class Settings {
@Column("boolean")
backup: boolean;
@Column("text")
backupDir: string;
@Column("int")
duration: number;