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 steps', value: settings.steps, key: 'steps'},
{name: 'Show date', value: settings.showDate, key: 'showDate'},
{name: 'Automatic backup', value: settings.backup, key: 'backup'},
],
[settings],
)
@ -131,6 +132,15 @@ export default function SettingsPage() {
if (value) toast('Disable sound on rest timer alarms.')
else toast('Enabled sound for rest timer alarms.')
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],
@ -207,7 +217,7 @@ export default function SettingsPage() {
key: 'date',
},
]
}, [settings.date, darkColor, formatOptions, theme, lightColor])
}, [settings, darkColor, formatOptions, theme, lightColor])
const renderSelect = useCallback(
(item: Input<string>) => (

View File

@ -41,8 +41,8 @@ android {
missingDimensionStrategy "RNNotifications.reactNativeVersion", "reactNative60"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 36155
versionName "1.129"
versionCode 36156
versionName "1.130"
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
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()
modules.add(AlarmModule(reactContext))
modules.add(SettingsModule(reactContext))
modules.add(BackupModule(reactContext))
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 {dropMigrations1667190214743} from './migrations/1667190214743-drop-migrations'
import {splitColor1669420187764} from './migrations/1669420187764-split-color'
import {addBackup1678334268359} from './migrations/1678334268359-add-backup'
import {Plan} from './plan'
import Settings from './settings'
@ -59,5 +60,6 @@ export const AppDataSource = new DataSource({
addNoSound1667186456118,
dropMigrations1667190214743,
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",
"version": "1.129",
"version": "1.130",
"private": true,
"license": "GPL-3.0-only",
"scripts": {

View File

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