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