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:
parent
4db820f10a
commit
13b340f5be
|
@ -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>) => (
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
87
android/app/src/main/java/com/massive/BackupModule.kt
Normal file
87
android/app/src/main/java/com/massive/BackupModule.kt
Normal 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"
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
13
migrations/1678334268359-add-backup.ts
Normal file
13
migrations/1678334268359-add-backup.ts
Normal 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')
|
||||||
|
}
|
||||||
|
}
|
|
@ -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": {
|
||||||
|
|
|
@ -43,4 +43,7 @@ export default class Settings {
|
||||||
|
|
||||||
@Column('boolean')
|
@Column('boolean')
|
||||||
noSound: boolean
|
noSound: boolean
|
||||||
|
|
||||||
|
@Column('boolean')
|
||||||
|
backup: boolean
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user