Files
OmniCards/mobile/src/main/java/ru/omni_devel/cards/BackupActivity.kt
T

159 lines
5.7 KiB
Kotlin

package ru.omni_devel.cards
import android.net.Uri
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.LocalActivity
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Save
import androidx.compose.material.icons.outlined.Restore
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import kotlinx.serialization.json.Json
import ru.omni_devel.cards.ui.theme.OmniCardsTheme
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.res.stringResource
class BackupActivity : ComponentActivity() {
private lateinit var db: DbHelper
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
db = DbHelper(this, null)
setContent {
OmniCardsTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
BackupPage(innerPadding = innerPadding, getDbFun = {
return@BackupPage db
})
}
}
}
}
}
@Composable
fun BackupPage(innerPadding: PaddingValues, getDbFun: () -> DbHelper) {
val context = LocalContext.current
val activityContext = LocalActivity.current
val showImportDialog = rememberSaveable { mutableStateOf(false) }
var pendingUri by rememberSaveable { mutableStateOf<Uri?>(null) }
val createBackupLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.CreateDocument("application/json")
) { uri ->
uri?.let {
try {
val jsonData = Json.encodeToString(getDbFun().getCards())
context.contentResolver.openOutputStream(it)?.use { outputStream ->
outputStream.write(jsonData.toByteArray())
Toast.makeText(context, context.getString(R.string.backup_successfully_saved), Toast.LENGTH_SHORT).show()
activityContext!!.finish()
}
} catch (e: Exception) {
Toast.makeText(context, context.getString(R.string.failed_to_save_backup, e), Toast.LENGTH_LONG).show()
}
}
}
val restoreFromBackupLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.GetContent()
) { uri ->
uri?.let {
pendingUri = it
showImportDialog.value = true
}
}
if (showImportDialog.value) {
AlertDialog(
title = { Text(stringResource(R.string.ask_do_restore)) },
text = { Text(stringResource(R.string.restore_caution)) },
confirmButton = {
TextButton(
onClick = {
showImportDialog.value = false
pendingUri?.let { uri ->
try {
context.contentResolver.openInputStream(uri)?.use { stream ->
val json = stream.bufferedReader().use { it.readText() }
val cards = Json.decodeFromString<List<CardInfo>>(json)
val db = getDbFun()
db.clearDatabase()
db.addCards(cards)
Toast.makeText(context, context.getString(R.string.backup_successfully_restored), Toast.LENGTH_SHORT).show()
activityContext!!.finish()
}
} catch (e: Exception) {
Toast.makeText(context, context.getString(R.string.failed_to_restore_backup, e), Toast.LENGTH_LONG).show()
}
}
}
) {
Text(stringResource(R.string.yes))
}
},
dismissButton = {
TextButton(
onClick = {
showImportDialog.value = false
}
) {
Text(stringResource(R.string.no))
}
},
onDismissRequest = { showImportDialog.value = false },
)
}
Page(stringResource(R.string.backup), innerPadding) {
AdaptiveButton(
modifier = Modifier.fillMaxWidth(),
icon = Icons.Outlined.Save,
onClick = {
createBackupLauncher.launch("omnicards-backup.json")
}
) {
Text(stringResource(R.string.do_backup))
}
AdaptiveButton(
modifier = Modifier.fillMaxWidth(),
icon = Icons.Outlined.Restore,
onClick = {
restoreFromBackupLauncher.launch("application/json")
}
) {
Text(stringResource(R.string.do_restore))
}
}
}