Files
OmniCards/mobile/src/main/java/ru/omni_devel/cards/BackupScreen.kt
T
Fimkov e62b7f4741 feat: full md3 redesign and few tweaks
fully redesigned android and wearos app

auto sync with wearos

enabled minify
2026-06-19 12:06:49 +07:00

156 lines
6.0 KiB
Kotlin

package ru.omni_devel.cards
import android.net.Uri
import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.width
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Download
import androidx.compose.material.icons.filled.Restore
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import kotlinx.serialization.json.Json
@Composable
fun BackupScreen(
db: DbHelper,
onBack: () -> Unit,
) {
val context = LocalContext.current
var showRestoreDialog by remember { mutableStateOf(false) }
var pendingUri by remember { mutableStateOf<Uri?>(null) }
val createBackupLauncher = rememberLauncherForActivityResult(
ActivityResultContracts.CreateDocument("application/json")
) { uri ->
uri?.let {
try {
val json = Json.encodeToString(db.getCards())
context.contentResolver.openOutputStream(it)?.use { stream ->
stream.write(json.toByteArray())
}
Toast.makeText(context, context.getString(R.string.backup_successfully_saved), Toast.LENGTH_SHORT).show()
} catch (e: Exception) {
Toast.makeText(context, context.getString(R.string.failed_to_save_backup, e), Toast.LENGTH_LONG).show()
}
}
}
val restoreLauncher = rememberLauncherForActivityResult(
ActivityResultContracts.GetContent()
) { uri ->
uri?.let {
pendingUri = it
showRestoreDialog = true
}
}
if (showRestoreDialog) {
AlertDialog(
onDismissRequest = { showRestoreDialog = false },
title = { Text(stringResource(R.string.ask_do_restore)) },
text = { Text(stringResource(R.string.restore_caution)) },
confirmButton = {
TextButton(onClick = {
showRestoreDialog = 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)
db.clearDatabase()
db.addCards(cards)
}
Toast.makeText(context, context.getString(R.string.backup_successfully_restored), Toast.LENGTH_SHORT).show()
onBack()
} 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 = { showRestoreDialog = false }) {
Text(stringResource(R.string.no))
}
}
)
}
Column(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.surfaceContainer)
.statusBarsPadding()
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 6.dp, vertical = 4.dp),
verticalAlignment = Alignment.CenterVertically
) {
IconButton(onClick = onBack) {
Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null)
}
Text(stringResource(R.string.backup), style = MaterialTheme.typography.titleLarge)
}
Column(
modifier = Modifier.padding(horizontal = 20.dp, vertical = 12.dp),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
Button(
onClick = { createBackupLauncher.launch("omnicards-backup.json") },
modifier = Modifier
.fillMaxWidth()
.height(56.dp)
) {
Icon(Icons.Filled.Download, contentDescription = null)
Spacer(Modifier.width(8.dp))
Text(stringResource(R.string.do_backup))
}
OutlinedButton(
onClick = { restoreLauncher.launch("application/json") },
modifier = Modifier
.fillMaxWidth()
.height(56.dp)
) {
Icon(Icons.Filled.Restore, contentDescription = null)
Spacer(Modifier.width(8.dp))
Text(stringResource(R.string.do_restore))
}
}
}
}