From eceaba78be93537df932ddbeb180eddc4fb24a9e Mon Sep 17 00:00:00 2001
From: Myzel394 <50424412+Myzel394@users.noreply.github.com>
Date: Sun, 22 Oct 2023 16:07:33 +0200
Subject: [PATCH 01/11] feat: Add json serializability for AppSettings
---
.../java/app/myzel394/alibi/db/AppSettings.kt | 53 +++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/app/src/main/java/app/myzel394/alibi/db/AppSettings.kt b/app/src/main/java/app/myzel394/alibi/db/AppSettings.kt
index 35566c5..33c951d 100644
--- a/app/src/main/java/app/myzel394/alibi/db/AppSettings.kt
+++ b/app/src/main/java/app/myzel394/alibi/db/AppSettings.kt
@@ -7,6 +7,7 @@ import com.arthenica.ffmpegkit.FFmpegKit
import com.arthenica.ffmpegkit.ReturnCode
import kotlinx.coroutines.delay
import kotlinx.serialization.Serializable
+import org.json.JSONObject
import java.io.File
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter.ISO_DATE_TIME
@@ -40,8 +41,28 @@ data class AppSettings(
DARK,
}
+ fun toJSONObject(): JSONObject {
+ return JSONObject(
+ mapOf(
+ "audioRecorderSettings" to audioRecorderSettings.toJSONObject(),
+ "hasSeenOnboarding" to hasSeenOnboarding,
+ "showAdvancedSettings" to showAdvancedSettings,
+ "theme" to theme.name,
+ )
+ )
+ }
+
companion object {
fun getDefaultInstance(): AppSettings = AppSettings()
+
+ fun fromJSONObject(data: JSONObject): AppSettings {
+ return AppSettings(
+ audioRecorderSettings = AudioRecorderSettings.fromJSONObject(data.getJSONObject("audioRecorderSettings")),
+ hasSeenOnboarding = data.getBoolean("hasSeenOnboarding"),
+ showAdvancedSettings = data.getBoolean("showAdvancedSettings"),
+ theme = Theme.valueOf(data.getString("theme")),
+ )
+ }
}
}
@@ -292,6 +313,20 @@ data class AudioRecorderSettings(
return supportedFormats.contains(outputFormat)
}
+ fun toJSONObject(): JSONObject {
+ return JSONObject(
+ mapOf(
+ "maxDuration" to maxDuration,
+ "intervalDuration" to intervalDuration,
+ "forceExactMaxDuration" to forceExactMaxDuration,
+ "bitRate" to bitRate,
+ "samplingRate" to samplingRate,
+ "outputFormat" to outputFormat,
+ "encoder" to encoder,
+ )
+ )
+ }
+
companion object {
fun getDefaultInstance(): AudioRecorderSettings = AudioRecorderSettings()
val EXAMPLE_MAX_DURATIONS = listOf(
@@ -398,5 +433,23 @@ data class AudioRecorderSettings(
}
}
}).toMap()
+
+ fun fromJSONObject(data: JSONObject): AudioRecorderSettings {
+ return AudioRecorderSettings(
+ maxDuration = data.getLong("maxDuration"),
+ intervalDuration = data.getLong("intervalDuration"),
+ forceExactMaxDuration = data.getBoolean("forceExactMaxDuration"),
+ bitRate = data.getInt("bitRate"),
+ samplingRate = data.optInt("samplingRate", -1).let {
+ if (it == -1) null else it
+ },
+ outputFormat = data.optInt("outputFormat", -1).let {
+ if (it == -1) null else it
+ },
+ encoder = data.optInt("encoder", -1).let {
+ if (it == -1) null else it
+ },
+ )
+ }
}
}
From d9420ddff551fb48cdceae60b810c681f75657ec Mon Sep 17 00:00:00 2001
From: Myzel394 <50424412+Myzel394@users.noreply.github.com>
Date: Sun, 22 Oct 2023 16:14:45 +0200
Subject: [PATCH 02/11] feat: Add import export to settings
---
.../SettingsScreen/atoms/ImportExport.kt | 53 +++++++++++++++++++
.../alibi/ui/screens/SettingsScreen.kt | 26 ++++++---
app/src/main/res/values/strings.xml | 5 +-
3 files changed, 75 insertions(+), 9 deletions(-)
create mode 100644 app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/atoms/ImportExport.kt
diff --git a/app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/atoms/ImportExport.kt b/app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/atoms/ImportExport.kt
new file mode 100644
index 0000000..698ff2b
--- /dev/null
+++ b/app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/atoms/ImportExport.kt
@@ -0,0 +1,53 @@
+package app.myzel394.alibi.ui.components.SettingsScreen.atoms
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.size
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Download
+import androidx.compose.material.icons.filled.Upload
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import app.myzel394.alibi.R
+
+@Composable
+fun ImportExport() {
+ Row(
+ horizontalArrangement = Arrangement.SpaceEvenly,
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier.fillMaxWidth(),
+ ) {
+ Button(
+ onClick = { /*TODO*/ },
+ colors = ButtonDefaults.filledTonalButtonColors(),
+ ) {
+ Icon(
+ Icons.Default.Download,
+ contentDescription = null,
+ modifier = Modifier.size(ButtonDefaults.IconSize),
+ )
+ Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing))
+ Text(stringResource(R.string.ui_settings_option_import_label))
+ }
+ Button(
+ onClick = { /*TODO*/ },
+ colors = ButtonDefaults.filledTonalButtonColors(),
+ ) {
+ Icon(
+ Icons.Default.Upload,
+ contentDescription = null,
+ modifier = Modifier.size(ButtonDefaults.IconSize),
+ )
+ Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing))
+ Text(stringResource(R.string.ui_settings_option_export_label))
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/app/myzel394/alibi/ui/screens/SettingsScreen.kt b/app/src/main/java/app/myzel394/alibi/ui/screens/SettingsScreen.kt
index 13294c5..793a601 100644
--- a/app/src/main/java/app/myzel394/alibi/ui/screens/SettingsScreen.kt
+++ b/app/src/main/java/app/myzel394/alibi/ui/screens/SettingsScreen.kt
@@ -1,6 +1,7 @@
package app.myzel394.alibi.ui.screens
import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
@@ -39,6 +40,7 @@ import app.myzel394.alibi.ui.SUPPORTS_DARK_MODE_NATIVELY
import app.myzel394.alibi.ui.components.SettingsScreen.atoms.BitrateTile
import app.myzel394.alibi.ui.components.SettingsScreen.atoms.EncoderTile
import app.myzel394.alibi.ui.components.SettingsScreen.atoms.ForceExactMaxDurationTile
+import app.myzel394.alibi.ui.components.SettingsScreen.atoms.ImportExport
import app.myzel394.alibi.ui.components.SettingsScreen.atoms.InAppLanguagePicker
import app.myzel394.alibi.ui.components.SettingsScreen.atoms.IntervalDurationTile
import app.myzel394.alibi.ui.components.SettingsScreen.atoms.MaxDurationTile
@@ -128,16 +130,26 @@ fun SettingsScreen(
ForceExactMaxDurationTile()
InAppLanguagePicker()
AnimatedVisibility(visible = settings.showAdvancedSettings) {
- Column {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.spacedBy(32.dp),
+ ) {
+ Column {
+ Divider(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = 16.dp, vertical = 32.dp)
+ )
+ BitrateTile()
+ SamplingRateTile()
+ EncoderTile(snackbarHostState = snackbarHostState)
+ OutputFormatTile()
+ }
Divider(
modifier = Modifier
- .fillMaxWidth()
- .padding(horizontal = 16.dp, vertical = 32.dp)
+ .fillMaxWidth(0.5f)
)
- BitrateTile()
- SamplingRateTile()
- EncoderTile(snackbarHostState = snackbarHostState)
- OutputFormatTile()
+ ImportExport()
}
}
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 15ab739..34a9509 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,5 +1,4 @@
-
+
Alibi
Cancel
@@ -64,4 +63,6 @@
Alibi encountered an error during recording. Would you like to try saving the recording?
Language
Change
+ Import Settings
+ Export Settings
\ No newline at end of file
From 5e9f46d97993718170ad4451507e7c424ccd164a Mon Sep 17 00:00:00 2001
From: Myzel394 <50424412+Myzel394@users.noreply.github.com>
Date: Sun, 22 Oct 2023 16:47:43 +0200
Subject: [PATCH 03/11] feat: Add import functionality
---
.../java/app/myzel394/alibi/db/AppSettings.kt | 19 +++-
.../SettingsScreen/atoms/ImportExport.kt | 102 +++++++++++++++++-
.../alibi/ui/screens/AudioRecorder.kt | 4 +-
.../java/app/myzel394/alibi/ui/utils/file.kt | 44 +++++---
app/src/main/res/values/strings.xml | 2 +
5 files changed, 154 insertions(+), 17 deletions(-)
diff --git a/app/src/main/java/app/myzel394/alibi/db/AppSettings.kt b/app/src/main/java/app/myzel394/alibi/db/AppSettings.kt
index 33c951d..2fd5abc 100644
--- a/app/src/main/java/app/myzel394/alibi/db/AppSettings.kt
+++ b/app/src/main/java/app/myzel394/alibi/db/AppSettings.kt
@@ -5,7 +5,6 @@ import android.os.Build
import android.util.Log
import com.arthenica.ffmpegkit.FFmpegKit
import com.arthenica.ffmpegkit.ReturnCode
-import kotlinx.coroutines.delay
import kotlinx.serialization.Serializable
import org.json.JSONObject
import java.io.File
@@ -52,6 +51,19 @@ data class AppSettings(
)
}
+ fun exportToString(): String {
+ return JSONObject(
+ mapOf(
+ "_meta" to mapOf(
+ "version" to 1,
+ "date" to LocalDateTime.now().format(ISO_DATE_TIME),
+ "app" to "app.myzel394.alibi",
+ ),
+ "data" to toJSONObject(),
+ )
+ ).toString(0)
+ }
+
companion object {
fun getDefaultInstance(): AppSettings = AppSettings()
@@ -63,6 +75,11 @@ data class AppSettings(
theme = Theme.valueOf(data.getString("theme")),
)
}
+
+ fun fromExportedString(data: String): AppSettings {
+ val json = JSONObject(data)
+ return fromJSONObject(json.getJSONObject("data"))
+ }
}
}
diff --git a/app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/atoms/ImportExport.kt b/app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/atoms/ImportExport.kt
index 698ff2b..b42888e 100644
--- a/app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/atoms/ImportExport.kt
+++ b/app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/atoms/ImportExport.kt
@@ -6,27 +6,118 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Check
+import androidx.compose.material.icons.filled.CheckCircle
import androidx.compose.material.icons.filled.Download
import androidx.compose.material.icons.filled.Upload
+import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
+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 app.myzel394.alibi.R
+import app.myzel394.alibi.dataStore
+import app.myzel394.alibi.db.AppSettings
+import app.myzel394.alibi.ui.utils.rememberFileSaverDialog
+import app.myzel394.alibi.ui.utils.rememberFileSelectorDialog
+import kotlinx.coroutines.launch
+import java.io.File
@Composable
fun ImportExport() {
+ val context = LocalContext.current
+
+ val scope = rememberCoroutineScope()
+ val dataStore = LocalContext.current.dataStore
+ val settings = dataStore
+ .data
+ .collectAsState(initial = AppSettings.getDefaultInstance())
+ .value
+
+ var settingsToBeImported by remember { mutableStateOf(null) }
+
+ val saveFile = rememberFileSaverDialog("application/json")
+ val openFile = rememberFileSelectorDialog { uri ->
+ val file = File.createTempFile("alibi_settings", ".json")
+
+ context.contentResolver.openInputStream(uri)!!.use {
+ it.copyTo(file.outputStream())
+ }
+ val rawContent = file.readText()
+
+ settingsToBeImported = AppSettings.fromExportedString(rawContent)
+ }
+
+ if (settingsToBeImported != null) {
+ AlertDialog(
+ onDismissRequest = {
+ settingsToBeImported = null
+ },
+ title = {
+ Text(stringResource(R.string.ui_settings_option_import_label))
+ },
+ text = {
+ Text(stringResource(R.string.ui_settings_option_import_dialog_text))
+ },
+ icon = {
+ Icon(
+ Icons.Default.Download,
+ contentDescription = null,
+ )
+ },
+ confirmButton = {
+ Button(
+ onClick = {
+ scope.launch {
+ dataStore.updateData {
+ settingsToBeImported!!
+ }
+ settingsToBeImported = null
+ }
+ },
+ ) {
+ Icon(
+ Icons.Default.CheckCircle,
+ contentDescription = null,
+ modifier = Modifier.size(ButtonDefaults.IconSize),
+ )
+ Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing))
+ Text(stringResource(R.string.ui_settings_option_import_dialog_confirm))
+ }
+ },
+ dismissButton = {
+ Button(
+ onClick = {
+ settingsToBeImported = null
+ },
+ colors = ButtonDefaults.textButtonColors(),
+ ) {
+ Text(stringResource(R.string.dialog_close_cancel_label))
+ }
+ },
+ )
+ }
+
Row(
horizontalArrangement = Arrangement.SpaceEvenly,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth(),
) {
Button(
- onClick = { /*TODO*/ },
+ onClick = {
+ openFile("application/json")
+ },
colors = ButtonDefaults.filledTonalButtonColors(),
) {
Icon(
@@ -38,7 +129,14 @@ fun ImportExport() {
Text(stringResource(R.string.ui_settings_option_import_label))
}
Button(
- onClick = { /*TODO*/ },
+ onClick = {
+ val rawContent = settings.exportToString()
+
+ val tempFile = File.createTempFile("alibi_settings", ".json")
+ tempFile.writeText(rawContent)
+
+ saveFile(tempFile, "alibi_settings.json")
+ },
colors = ButtonDefaults.filledTonalButtonColors(),
) {
Icon(
diff --git a/app/src/main/java/app/myzel394/alibi/ui/screens/AudioRecorder.kt b/app/src/main/java/app/myzel394/alibi/ui/screens/AudioRecorder.kt
index 0db7196..1e121bf 100644
--- a/app/src/main/java/app/myzel394/alibi/ui/screens/AudioRecorder.kt
+++ b/app/src/main/java/app/myzel394/alibi/ui/screens/AudioRecorder.kt
@@ -64,7 +64,7 @@ fun AudioRecorder(
try {
val file = audioRecorder.lastRecording!!.concatenateFiles()
- saveFile(file)
+ saveFile(file, file.name)
} catch (error: Exception) {
Log.getStackTraceString(error)
} finally {
@@ -165,7 +165,7 @@ fun AudioRecorder(
}
)
},
- ) {padding ->
+ ) { padding ->
Box(
modifier = Modifier
.fillMaxSize()
diff --git a/app/src/main/java/app/myzel394/alibi/ui/utils/file.kt b/app/src/main/java/app/myzel394/alibi/ui/utils/file.kt
index 8838d04..cd50b80 100644
--- a/app/src/main/java/app/myzel394/alibi/ui/utils/file.kt
+++ b/app/src/main/java/app/myzel394/alibi/ui/utils/file.kt
@@ -1,33 +1,53 @@
package app.myzel394.alibi.ui.utils
+import android.net.Uri
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
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.platform.LocalContext
import java.io.File
@Composable
-fun rememberFileSaverDialog(mimeType: String): ((File) -> Unit) {
+fun rememberFileSaverDialog(mimeType: String): ((File, String) -> Unit) {
val context = LocalContext.current
var file = remember { mutableStateOf(null) }
- val launcher = rememberLauncherForActivityResult(ActivityResultContracts.CreateDocument(mimeType)) {
- it?.let {
- context.contentResolver.openOutputStream(it)?.use { outputStream ->
- file.value!!.inputStream().use { inputStream ->
- inputStream.copyTo(outputStream)
+ val launcher =
+ rememberLauncherForActivityResult(ActivityResultContracts.CreateDocument(mimeType)) {
+ it?.let {
+ context.contentResolver.openOutputStream(it)?.use { outputStream ->
+ file.value!!.inputStream().use { inputStream ->
+ inputStream.copyTo(outputStream)
+ }
}
}
+
+ file.value = null
+ }
+
+ return { it, name ->
+ file.value = it
+ launcher.launch(name ?: it.name)
+ }
+}
+
+@Composable
+fun rememberFileSelectorDialog(
+ callback: (Uri) -> Unit
+): ((String) -> Unit) {
+ val launcher =
+ rememberLauncherForActivityResult(ActivityResultContracts.OpenDocument()) {
+ if (it != null) {
+ callback(it)
+ }
}
- file.value = null
- }
-
- return {
- file.value = it
- launcher.launch(it.name)
+ return { mimeType ->
+ launcher.launch(arrayOf(mimeType))
}
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 34a9509..e67d141 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -65,4 +65,6 @@
Change
Import Settings
Export Settings
+ Are you sure you want to import these settings? Your current settings will be overwritten!
+ Import settings
\ No newline at end of file
From 54b2e9bee5cdc6d1033bee7de21a69f8cbbd4c0e Mon Sep 17 00:00:00 2001
From: Myzel394 <50424412+Myzel394@users.noreply.github.com>
Date: Sun, 22 Oct 2023 17:05:24 +0200
Subject: [PATCH 04/11] fix: Improve snackbar & add import success message
---
.../SettingsScreen/atoms/ImportExport.kt | 16 ++++++++++++++-
.../alibi/ui/screens/SettingsScreen.kt | 20 +++++++++++++++++--
app/src/main/res/values/strings.xml | 1 +
3 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/atoms/ImportExport.kt b/app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/atoms/ImportExport.kt
index b42888e..830d550 100644
--- a/app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/atoms/ImportExport.kt
+++ b/app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/atoms/ImportExport.kt
@@ -14,6 +14,9 @@ import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
+import androidx.compose.material3.SnackbarDuration
+import androidx.compose.material3.SnackbarHostState
+import androidx.compose.material3.SnackbarVisuals
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
@@ -35,7 +38,9 @@ import kotlinx.coroutines.launch
import java.io.File
@Composable
-fun ImportExport() {
+fun ImportExport(
+ snackbarHostState: SnackbarHostState,
+) {
val context = LocalContext.current
val scope = rememberCoroutineScope()
@@ -60,6 +65,8 @@ fun ImportExport() {
}
if (settingsToBeImported != null) {
+ val successMessage = stringResource(R.string.ui_settings_option_import_success)
+
AlertDialog(
onDismissRequest = {
settingsToBeImported = null
@@ -84,7 +91,14 @@ fun ImportExport() {
settingsToBeImported!!
}
settingsToBeImported = null
+
+ snackbarHostState.showSnackbar(
+ message = successMessage,
+ withDismissAction = true,
+ duration = SnackbarDuration.Short,
+ )
}
+
},
) {
Icon(
diff --git a/app/src/main/java/app/myzel394/alibi/ui/screens/SettingsScreen.kt b/app/src/main/java/app/myzel394/alibi/ui/screens/SettingsScreen.kt
index 793a601..420c117 100644
--- a/app/src/main/java/app/myzel394/alibi/ui/screens/SettingsScreen.kt
+++ b/app/src/main/java/app/myzel394/alibi/ui/screens/SettingsScreen.kt
@@ -16,7 +16,9 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LargeTopAppBar
+import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Snackbar
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
@@ -65,7 +67,21 @@ fun SettingsScreen(
)
Scaffold(
- snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
+ snackbarHost = {
+ SnackbarHost(
+ hostState = snackbarHostState,
+ snackbar = {
+ Snackbar(
+ snackbarData = it,
+ containerColor = MaterialTheme.colorScheme.primaryContainer,
+ contentColor = MaterialTheme.colorScheme.onPrimaryContainer,
+ actionColor = MaterialTheme.colorScheme.onPrimaryContainer,
+ actionContentColor = MaterialTheme.colorScheme.onPrimaryContainer,
+ dismissActionContentColor = MaterialTheme.colorScheme.onPrimaryContainer,
+ )
+ }
+ )
+ },
topBar = {
LargeTopAppBar(
title = {
@@ -149,7 +165,7 @@ fun SettingsScreen(
modifier = Modifier
.fillMaxWidth(0.5f)
)
- ImportExport()
+ ImportExport(snackbarHostState = snackbarHostState)
}
}
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index e67d141..baa7240 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -67,4 +67,5 @@
Export Settings
Are you sure you want to import these settings? Your current settings will be overwritten!
Import settings
+ Settings have been imported successfully!
\ No newline at end of file
From 543f06eee7ccf05d2aa61083f9849f1f6adba4fe Mon Sep 17 00:00:00 2001
From: Myzel394 <50424412+Myzel394@users.noreply.github.com>
Date: Sun, 22 Oct 2023 18:03:47 +0200
Subject: [PATCH 05/11] chore: Add crowdin.yml
---
crowdin.yml | 7 +++++++
1 file changed, 7 insertions(+)
create mode 100644 crowdin.yml
diff --git a/crowdin.yml b/crowdin.yml
new file mode 100644
index 0000000..e8d2c50
--- /dev/null
+++ b/crowdin.yml
@@ -0,0 +1,7 @@
+files:
+ - source: /app/src/main/res/values/strings.xml
+ translation: /app/src/main/res/values-b+%two_letters_code%+%locale%/strings.xml
+ translate_attributes: 0
+ content_segmentation: 0
+ - source: /fastlane/metadata/android/en-US/*.txt
+ translation: /fastlane/metadata/android/%locale%/%original_file_name%
From f90ca6ef8441b7a05adfc1ecc4a8693500a7ac7e Mon Sep 17 00:00:00 2001
From: Myzel394 <50424412+Myzel394@users.noreply.github.com>
Date: Sun, 22 Oct 2023 18:11:58 +0200
Subject: [PATCH 06/11] Update crowdin.yml
---
crowdin.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/crowdin.yml b/crowdin.yml
index e8d2c50..c10b1a3 100644
--- a/crowdin.yml
+++ b/crowdin.yml
@@ -1,6 +1,6 @@
files:
- source: /app/src/main/res/values/strings.xml
- translation: /app/src/main/res/values-b+%two_letters_code%+%locale%/strings.xml
+ translation: /app/src/main/res/values-b+%two_letters_code%+*/strings.xml
translate_attributes: 0
content_segmentation: 0
- source: /fastlane/metadata/android/en-US/*.txt
From 7fe6ab79e174f1dbb519f39d00cd0d92f1a47e3b Mon Sep 17 00:00:00 2001
From: Myzel394 <50424412+Myzel394@users.noreply.github.com>
Date: Sun, 22 Oct 2023 20:00:37 +0200
Subject: [PATCH 07/11] fix: Fix Turkish translation name
---
app/src/main/res/{values-tr-rTR => values-b+tr+rTR}/strings.xml | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename app/src/main/res/{values-tr-rTR => values-b+tr+rTR}/strings.xml (100%)
diff --git a/app/src/main/res/values-tr-rTR/strings.xml b/app/src/main/res/values-b+tr+rTR/strings.xml
similarity index 100%
rename from app/src/main/res/values-tr-rTR/strings.xml
rename to app/src/main/res/values-b+tr+rTR/strings.xml
From 739d5cc7387d0e3f57195501ffad8e57b242ec79 Mon Sep 17 00:00:00 2001
From: Myzel394 <50424412+Myzel394@users.noreply.github.com>
Date: Sun, 22 Oct 2023 20:13:44 +0200
Subject: [PATCH 08/11] fix: Fix translation names
---
app/src/main/res/{values-b+de+DE => values-de-rDE}/strings.xml | 0
app/src/main/res/{values-b+tr+rTR => values-tr-rTR}/strings.xml | 0
app/src/main/res/{values-b+zh+CN => values-zh-rCN}/strings.xml | 0
3 files changed, 0 insertions(+), 0 deletions(-)
rename app/src/main/res/{values-b+de+DE => values-de-rDE}/strings.xml (100%)
rename app/src/main/res/{values-b+tr+rTR => values-tr-rTR}/strings.xml (100%)
rename app/src/main/res/{values-b+zh+CN => values-zh-rCN}/strings.xml (100%)
diff --git a/app/src/main/res/values-b+de+DE/strings.xml b/app/src/main/res/values-de-rDE/strings.xml
similarity index 100%
rename from app/src/main/res/values-b+de+DE/strings.xml
rename to app/src/main/res/values-de-rDE/strings.xml
diff --git a/app/src/main/res/values-b+tr+rTR/strings.xml b/app/src/main/res/values-tr-rTR/strings.xml
similarity index 100%
rename from app/src/main/res/values-b+tr+rTR/strings.xml
rename to app/src/main/res/values-tr-rTR/strings.xml
diff --git a/app/src/main/res/values-b+zh+CN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
similarity index 100%
rename from app/src/main/res/values-b+zh+CN/strings.xml
rename to app/src/main/res/values-zh-rCN/strings.xml
From de0e163b28fe8375cc9ca54f569be1697ff82dd0 Mon Sep 17 00:00:00 2001
From: Myzel394 <50424412+Myzel394@users.noreply.github.com>
Date: Sun, 22 Oct 2023 20:15:59 +0200
Subject: [PATCH 09/11] Update crowdin.yml
---
crowdin.yml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/crowdin.yml b/crowdin.yml
index c10b1a3..6cb062d 100644
--- a/crowdin.yml
+++ b/crowdin.yml
@@ -1,7 +1,8 @@
files:
- source: /app/src/main/res/values/strings.xml
- translation: /app/src/main/res/values-b+%two_letters_code%+*/strings.xml
+ translation: /app/src/main/res/values-%locale%/strings.xml
translate_attributes: 0
content_segmentation: 0
+ type: xml
- source: /fastlane/metadata/android/en-US/*.txt
translation: /fastlane/metadata/android/%locale%/%original_file_name%
From 2134839c30b157211c3d8e19d788853832c85235 Mon Sep 17 00:00:00 2001
From: Myzel394 <50424412+Myzel394@users.noreply.github.com>
Date: Sun, 22 Oct 2023 20:21:50 +0200
Subject: [PATCH 10/11] Update crowdin.yml
---
crowdin.yml | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/crowdin.yml b/crowdin.yml
index 6cb062d..01f1013 100644
--- a/crowdin.yml
+++ b/crowdin.yml
@@ -1,8 +1,13 @@
files:
- source: /app/src/main/res/values/strings.xml
- translation: /app/src/main/res/values-%locale%/strings.xml
+ translation: /app/src/main/res/values(-%android_code%)?/strings.xml
translate_attributes: 0
content_segmentation: 0
type: xml
+ languages_mapping:
+ android_code:
+ de-rDE: de
+ tr-rTR: tr
+ zh-rCN: zh
- source: /fastlane/metadata/android/en-US/*.txt
translation: /fastlane/metadata/android/%locale%/%original_file_name%
From 8fc0dbe6a34678b87ce11c67d13b9aef80d6ca57 Mon Sep 17 00:00:00 2001
From: Myzel394 <50424412+Myzel394@users.noreply.github.com>
Date: Sun, 22 Oct 2023 20:48:02 +0200
Subject: [PATCH 11/11] Update crowdin.yml
---
crowdin.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/crowdin.yml b/crowdin.yml
index 01f1013..2789da1 100644
--- a/crowdin.yml
+++ b/crowdin.yml
@@ -1,6 +1,6 @@
files:
- source: /app/src/main/res/values/strings.xml
- translation: /app/src/main/res/values(-%android_code%)?/strings.xml
+ translation: /app/src/main/res/values-%android_code%/strings.xml
translate_attributes: 0
content_segmentation: 0
type: xml