Add setting to automatically backup - 1.130

Every day at 6am (also immediately when toggled)
we will copy the massive.db file to the Download
directory.
This commit is contained in:
Brandon Presley 2023-03-09 17:13:33 +13:00
parent 4db820f10a
commit 13b340f5be
8 changed files with 120 additions and 4 deletions

View File

@ -84,6 +84,7 @@ export default function SettingsPage() {
{name: 'Show unit', value: settings.showUnit, key: 'showUnit'}, {name: 'Show unit', value: settings.showUnit, key: 'showUnit'},
{name: 'Show steps', value: settings.steps, key: 'steps'}, {name: 'Show steps', value: settings.steps, key: 'steps'},
{name: 'Show date', value: settings.showDate, key: 'showDate'}, {name: 'Show date', value: settings.showDate, key: 'showDate'},
{name: 'Automatic backup', value: settings.backup, key: 'backup'},
], ],
[settings], [settings],
) )
@ -131,6 +132,15 @@ export default function SettingsPage() {
if (value) toast('Disable sound on rest timer alarms.') if (value) toast('Disable sound on rest timer alarms.')
else toast('Enabled sound for rest timer alarms.') else toast('Enabled sound for rest timer alarms.')
return return
case 'backup':
if (value) {
toast('Backup database daily.')
NativeModules.BackupModule.start()
} else {
toast('Stopped backing up daily')
NativeModules.BackupModule.stop()
}
return
} }
}, },
[ignoring, setValue, update], [ignoring, setValue, update],
@ -207,7 +217,7 @@ export default function SettingsPage() {
key: 'date', key: 'date',
}, },
] ]
}, [settings.date, darkColor, formatOptions, theme, lightColor]) }, [settings, darkColor, formatOptions, theme, lightColor])
const renderSelect = useCallback( const renderSelect = useCallback(
(item: Input<string>) => ( (item: Input<string>) => (

View File

@ -41,8 +41,8 @@ android {
missingDimensionStrategy "RNNotifications.reactNativeVersion", "reactNative60" missingDimensionStrategy "RNNotifications.reactNativeVersion", "reactNative60"
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 36155 versionCode 36156
versionName "1.129" versionName "1.130"
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
if (isNewArchitectureEnabled()) { if (isNewArchitectureEnabled()) {

View File

@ -0,0 +1,87 @@
package com.massive
import android.app.AlarmManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Build
import android.os.Environment
import androidx.annotation.RequiresApi
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.util.*
class BackupModule constructor(context: ReactApplicationContext?) :
ReactContextBaseJavaModule(context) {
val context: ReactApplicationContext = reactApplicationContext
private val copyReceiver = object : BroadcastReceiver() {
@RequiresApi(Build.VERSION_CODES.O)
override fun onReceive(context: Context?, intent: Intent?) {
val sourceFile = File(context?.getDatabasePath("massive.db")!!.path)
val targetDir =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
val targetFile = File(targetDir, "massive.db")
val input = FileInputStream(sourceFile)
val output = FileOutputStream(targetFile)
input.copyTo(output)
input.close()
output.close()
}
}
@RequiresApi(Build.VERSION_CODES.M)
@ReactMethod
fun start() {
val alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val intent = Intent(COPY_BROADCAST)
val pendingIntent =
PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
pendingIntent.send()
val calendar = Calendar.getInstance().apply {
timeInMillis = System.currentTimeMillis()
set(Calendar.HOUR_OF_DAY, 6)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
}
alarmMgr.setRepeating(
AlarmManager.RTC_WAKEUP,
calendar.timeInMillis,
AlarmManager.INTERVAL_DAY,
pendingIntent
)
}
@RequiresApi(Build.VERSION_CODES.M)
@ReactMethod
fun stop() {
val alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val intent = Intent(COPY_BROADCAST)
val pendingIntent =
PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
alarmMgr.cancel(pendingIntent)
}
init {
reactApplicationContext.registerReceiver(copyReceiver, IntentFilter(COPY_BROADCAST))
}
companion object {
const val COPY_BROADCAST = "copy-event"
}
override fun getName(): String {
return "BackupModule"
}
}

View File

@ -16,6 +16,7 @@ class MassivePackage : ReactPackage {
val modules: MutableList<NativeModule> = ArrayList() val modules: MutableList<NativeModule> = ArrayList()
modules.add(AlarmModule(reactContext)) modules.add(AlarmModule(reactContext))
modules.add(SettingsModule(reactContext)) modules.add(SettingsModule(reactContext))
modules.add(BackupModule(reactContext))
return modules return modules
} }
} }

View File

@ -24,6 +24,7 @@ import {addSetsCreated1667186451005} from './migrations/1667186451005-add-sets-c
import {addNoSound1667186456118} from './migrations/1667186456118-add-no-sound' import {addNoSound1667186456118} from './migrations/1667186456118-add-no-sound'
import {dropMigrations1667190214743} from './migrations/1667190214743-drop-migrations' import {dropMigrations1667190214743} from './migrations/1667190214743-drop-migrations'
import {splitColor1669420187764} from './migrations/1669420187764-split-color' import {splitColor1669420187764} from './migrations/1669420187764-split-color'
import {addBackup1678334268359} from './migrations/1678334268359-add-backup'
import {Plan} from './plan' import {Plan} from './plan'
import Settings from './settings' import Settings from './settings'
@ -59,5 +60,6 @@ export const AppDataSource = new DataSource({
addNoSound1667186456118, addNoSound1667186456118,
dropMigrations1667190214743, dropMigrations1667190214743,
splitColor1669420187764, splitColor1669420187764,
addBackup1678334268359,
], ],
}) })

View File

@ -0,0 +1,13 @@
import {MigrationInterface, QueryRunner} from 'typeorm'
export class addBackup1678334268359 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner
.query('ALTER TABLE settings ADD COLUMN backup BOOLEAN DEFAULT false')
.catch(() => null)
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.dropColumn('settings', 'backup')
}
}

View File

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

View File

@ -43,4 +43,7 @@ export default class Settings {
@Column('boolean') @Column('boolean')
noSound: boolean noSound: boolean
@Column('boolean')
backup: boolean
} }