From e6a29c6af11cac90b964a750c050f1ee97fbe89f Mon Sep 17 00:00:00 2001 From: Faded Date: Sun, 21 Sep 2025 16:17:36 +0500 Subject: [PATCH 1/9] Add localization support for multiple languages including German, Spanish, French, Hindi, and Urdu - Created new strings.xml files for German (values-de), Spanish (values-es), French (values-fr), Hindi (values-hi), and Urdu (values-ur) with translations for all app strings. - Extracted the remaining hardcoded texts into Strings --- .../com/yogeshpaliyal/deepr/MainActivity.kt | 29 ++++ .../preference/AppPreferenceDataStore.kt | 12 ++ .../ui/components/LanguageSelectionDialog.kt | 87 ++++++++++++ .../yogeshpaliyal/deepr/ui/screens/AboutUs.kt | 6 + .../deepr/ui/screens/Settings.kt | 59 ++++++++ .../deepr/ui/screens/home/DeeprItem.kt | 26 ++-- .../deepr/ui/screens/home/FilterMenu.kt | 75 ++++++++-- .../deepr/ui/screens/home/Home.kt | 33 +++-- .../ui/screens/home/HomeBottomContent.kt | 25 ++-- .../deepr/ui/screens/home/ShortcutMenuItem.kt | 9 +- .../ui/screens/home/ShowQRCodeMenuItem.kt | 6 +- .../screens/home/TagSelectionBottomSheet.kt | 6 +- .../yogeshpaliyal/deepr/util/LanguageUtil.kt | 80 +++++++++++ .../deepr/viewmodel/AccountViewModel.kt | 11 ++ app/src/main/res/values-de/strings.xml | 128 ++++++++++++++++++ app/src/main/res/values-es/strings.xml | 128 ++++++++++++++++++ app/src/main/res/values-fr/strings.xml | 128 ++++++++++++++++++ app/src/main/res/values-hi/strings.xml | 128 ++++++++++++++++++ app/src/main/res/values-ur/strings.xml | 128 ++++++++++++++++++ app/src/main/res/values/strings.xml | 49 +++++++ 20 files changed, 1107 insertions(+), 46 deletions(-) create mode 100644 app/src/main/java/com/yogeshpaliyal/deepr/ui/components/LanguageSelectionDialog.kt create mode 100644 app/src/main/java/com/yogeshpaliyal/deepr/util/LanguageUtil.kt create mode 100644 app/src/main/res/values-de/strings.xml create mode 100644 app/src/main/res/values-es/strings.xml create mode 100644 app/src/main/res/values-fr/strings.xml create mode 100644 app/src/main/res/values-hi/strings.xml create mode 100644 app/src/main/res/values-ur/strings.xml diff --git a/app/src/main/java/com/yogeshpaliyal/deepr/MainActivity.kt b/app/src/main/java/com/yogeshpaliyal/deepr/MainActivity.kt index 697ba33..6e242f0 100644 --- a/app/src/main/java/com/yogeshpaliyal/deepr/MainActivity.kt +++ b/app/src/main/java/com/yogeshpaliyal/deepr/MainActivity.kt @@ -1,5 +1,6 @@ package com.yogeshpaliyal.deepr +import android.content.Context import android.content.Intent import android.os.Bundle import androidx.activity.ComponentActivity @@ -19,6 +20,7 @@ import androidx.navigation3.runtime.NavEntry import androidx.navigation3.runtime.rememberSavedStateNavEntryDecorator import androidx.navigation3.ui.NavDisplay import androidx.navigation3.ui.rememberSceneSetupNavEntryDecorator +import com.yogeshpaliyal.deepr.preference.AppPreferenceDataStore import com.yogeshpaliyal.deepr.ui.screens.AboutUs import com.yogeshpaliyal.deepr.ui.screens.AboutUsScreen import com.yogeshpaliyal.deepr.ui.screens.Settings @@ -26,7 +28,12 @@ import com.yogeshpaliyal.deepr.ui.screens.SettingsScreen import com.yogeshpaliyal.deepr.ui.screens.home.Home import com.yogeshpaliyal.deepr.ui.screens.home.HomeScreen import com.yogeshpaliyal.deepr.ui.theme.DeeprTheme +import com.yogeshpaliyal.deepr.util.LanguageUtil +import com.yogeshpaliyal.deepr.viewmodel.AccountViewModel import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.runBlocking +import org.koin.androidx.viewmodel.ext.android.viewModel data class SharedLink( val url: String, @@ -35,6 +42,28 @@ data class SharedLink( class MainActivity : ComponentActivity() { val sharingLink = MutableStateFlow(null) + private val accountViewModel: AccountViewModel by viewModel() + + override fun attachBaseContext(newBase: Context?) { + super.attachBaseContext( + newBase?.let { context -> + try { + val preferenceDataStore = AppPreferenceDataStore(context) + val languageCode = + runBlocking { + preferenceDataStore.getLanguageCode.first() + } + if (languageCode.isNotEmpty()) { + LanguageUtil.updateLocale(context, languageCode) + } else { + context + } + } catch (e: Exception) { + context + } + }, + ) + } @OptIn(ExperimentalMaterial3Api::class) override fun onCreate(savedInstanceState: Bundle?) { diff --git a/app/src/main/java/com/yogeshpaliyal/deepr/preference/AppPreferenceDataStore.kt b/app/src/main/java/com/yogeshpaliyal/deepr/preference/AppPreferenceDataStore.kt index b30e61c..ff7853d 100644 --- a/app/src/main/java/com/yogeshpaliyal/deepr/preference/AppPreferenceDataStore.kt +++ b/app/src/main/java/com/yogeshpaliyal/deepr/preference/AppPreferenceDataStore.kt @@ -23,6 +23,7 @@ class AppPreferenceDataStore( private val SYNC_ENABLED = booleanPreferencesKey("sync_enabled") private val SYNC_FILE_PATH = stringPreferencesKey("sync_file_path") private val LAST_SYNC_TIME = longPreferencesKey("last_sync_time") + private val LANGUAGE_CODE = stringPreferencesKey("language_code") } val getSortingOrder: Flow<@SortType String> = @@ -50,6 +51,11 @@ class AppPreferenceDataStore( preferences[LAST_SYNC_TIME] ?: 0L // Default to 0 (never synced) } + val getLanguageCode: Flow = + context.appDataStore.data.map { preferences -> + preferences[LANGUAGE_CODE] ?: "" // Default to system language + } + suspend fun setSortingOrder(order: @SortType String) { context.appDataStore.edit { prefs -> prefs[SORTING_ORDER] = order @@ -79,4 +85,10 @@ class AppPreferenceDataStore( prefs[LAST_SYNC_TIME] = timestamp } } + + suspend fun setLanguageCode(code: String) { + context.appDataStore.edit { prefs -> + prefs[LANGUAGE_CODE] = code + } + } } diff --git a/app/src/main/java/com/yogeshpaliyal/deepr/ui/components/LanguageSelectionDialog.kt b/app/src/main/java/com/yogeshpaliyal/deepr/ui/components/LanguageSelectionDialog.kt new file mode 100644 index 0000000..95743ad --- /dev/null +++ b/app/src/main/java/com/yogeshpaliyal/deepr/ui/components/LanguageSelectionDialog.kt @@ -0,0 +1,87 @@ +package com.yogeshpaliyal.deepr.ui.components + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.ListItem +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.RadioButton +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import com.yogeshpaliyal.deepr.R +import com.yogeshpaliyal.deepr.util.LanguageUtil + +@Composable +fun LanguageSelectionDialog( + currentLanguageCode: String, + onLanguageSelect: (String) -> Unit, + onDismiss: () -> Unit, + modifier: Modifier = Modifier, +) { + AlertDialog( + modifier = modifier, + onDismissRequest = onDismiss, + title = { + Text( + text = stringResource(R.string.language_dialog_title), + style = MaterialTheme.typography.headlineSmall, + ) + }, + text = { + Column { + LanguageUtil.availableLanguages.forEach { language -> + ListItem( + modifier = + Modifier + .fillMaxWidth() + .clip(RoundedCornerShape(8.dp)) + .clickable { + onLanguageSelect(language.code) + onDismiss() + }.padding(vertical = 4.dp), + headlineContent = { + Text( + text = language.nativeName, + style = MaterialTheme.typography.bodyLarge, + ) + }, + supportingContent = + if (language.name != language.nativeName) { + { + Text( + text = language.name, + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + } + } else { + null + }, + trailingContent = { + RadioButton( + selected = currentLanguageCode == language.code, + onClick = { + onLanguageSelect(language.code) + onDismiss() + }, + ) + }, + ) + } + } + }, + confirmButton = { + TextButton(onClick = onDismiss) { + Text(stringResource(R.string.cancel)) + } + }, + ) +} diff --git a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/AboutUs.kt b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/AboutUs.kt index 3b2d279..70bb8ec 100644 --- a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/AboutUs.kt +++ b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/AboutUs.kt @@ -27,10 +27,13 @@ import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.scale +import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.dp import com.yogeshpaliyal.deepr.BuildConfig import com.yogeshpaliyal.deepr.R @@ -48,6 +51,8 @@ fun AboutUsScreen( backStack: SnapshotStateList, modifier: Modifier = Modifier, ) { + val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl + Scaffold(modifier = modifier.fillMaxSize(), topBar = { Column { TopAppBar( @@ -61,6 +66,7 @@ fun AboutUsScreen( Icon( TablerIcons.ArrowLeft, contentDescription = stringResource(R.string.back), + modifier = if (isRtl) Modifier.scale(-1f, 1f) else Modifier, ) } }, diff --git a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/Settings.kt b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/Settings.kt index b8a374c..7877964 100644 --- a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/Settings.kt +++ b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/Settings.kt @@ -31,25 +31,35 @@ import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.isGranted import com.google.accompanist.permissions.rememberPermissionState import com.yogeshpaliyal.deepr.BuildConfig +import com.yogeshpaliyal.deepr.MainActivity import com.yogeshpaliyal.deepr.R +import com.yogeshpaliyal.deepr.ui.components.LanguageSelectionDialog +import com.yogeshpaliyal.deepr.util.LanguageUtil import com.yogeshpaliyal.deepr.viewmodel.AccountViewModel import compose.icons.TablerIcons import compose.icons.tablericons.ArrowLeft import compose.icons.tablericons.Download import compose.icons.tablericons.FileText import compose.icons.tablericons.InfoCircle +import compose.icons.tablericons.Language import compose.icons.tablericons.Refresh import compose.icons.tablericons.Settings import compose.icons.tablericons.Upload @@ -82,6 +92,10 @@ fun SettingsScreen( // Collect the shortcut icon preference state val useLinkBasedIcons by viewModel.useLinkBasedIcons.collectAsStateWithLifecycle() + // Collect language preference state + val languageCode by viewModel.languageCode.collectAsStateWithLifecycle() + var showLanguageDialog by remember { mutableStateOf(false) } + // Collect sync preference states val syncEnabled by viewModel.syncEnabled.collectAsStateWithLifecycle() val syncFilePath by viewModel.syncFilePath.collectAsStateWithLifecycle() @@ -139,12 +153,20 @@ fun SettingsScreen( Text(stringResource(R.string.settings)) }, navigationIcon = { + val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl + IconButton(onClick = { backStack.removeLastOrNull() }) { Icon( TablerIcons.ArrowLeft, contentDescription = stringResource(R.string.back), + modifier = + if (isRtl) { + Modifier.graphicsLayer(scaleX = -1f) + } else { + Modifier + }, ) } }, @@ -332,6 +354,27 @@ fun SettingsScreen( ) HorizontalDivider() + // Language Selection Setting + ListItem( + modifier = + Modifier.clickable { + showLanguageDialog = true + }, + headlineContent = { Text(stringResource(R.string.language)) }, + supportingContent = { + Text( + LanguageUtil.getLanguageNativeName(languageCode), + ) + }, + leadingContent = { + Icon( + TablerIcons.Language, + contentDescription = stringResource(R.string.language), + ) + }, + ) + HorizontalDivider() + ListItem( modifier = Modifier.clickable(true) { @@ -368,5 +411,21 @@ fun SettingsScreen( Spacer(modifier = Modifier.height(16.dp)) } } + + // Language Selection Dialog + if (showLanguageDialog) { + LanguageSelectionDialog( + currentLanguageCode = languageCode, + onLanguageSelect = { selectedLanguageCode -> + viewModel.setLanguageCode(selectedLanguageCode) + showLanguageDialog = false + // Recreate activity to apply language change + (context as? MainActivity)?.let { activity -> + activity.recreate() + } + }, + onDismiss = { showLanguageDialog = false }, + ) + } } } diff --git a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/DeeprItem.kt b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/DeeprItem.kt index 08d8f8c..b00c586 100644 --- a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/DeeprItem.kt +++ b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/DeeprItem.kt @@ -32,9 +32,11 @@ 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.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.yogeshpaliyal.deepr.GetLinksAndTags +import com.yogeshpaliyal.deepr.R import com.yogeshpaliyal.deepr.Tags import compose.icons.TablerIcons import compose.icons.tablericons.Copy @@ -65,6 +67,10 @@ fun DeeprItem( val selectedTags = remember(account.tagsNames) { account.tagsNames?.split(",")?.toMutableList() } + // Extract string resources at Composable level + val copyLinkText = stringResource(R.string.copy_link) + val linkCopiedText = stringResource(R.string.link_copied) + Card( colors = CardDefaults.cardColors( @@ -113,7 +119,7 @@ fun DeeprItem( ) Spacer(modifier = Modifier.weight(1f)) Text( - text = "Opened: ${account.openedCount}", + text = stringResource(R.string.opened_count, account.openedCount), style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant, ) @@ -121,7 +127,7 @@ fun DeeprItem( } Box { IconButton(onClick = { expanded = true }) { - Icon(TablerIcons.DotsVertical, contentDescription = "More options") + Icon(TablerIcons.DotsVertical, contentDescription = stringResource(R.string.more_options)) } DropdownMenu( @@ -129,19 +135,19 @@ fun DeeprItem( onDismissRequest = { expanded = false }, ) { DropdownMenuItem( - text = { Text("Copy link") }, + text = { Text(copyLinkText) }, onClick = { val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - val clip = ClipData.newPlainText("Link copied", account.link) + val clip = ClipData.newPlainText(linkCopiedText, account.link) clipboard.setPrimaryClip(clip) - Toast.makeText(context, "Link copied", Toast.LENGTH_SHORT).show() + Toast.makeText(context, linkCopiedText, Toast.LENGTH_SHORT).show() expanded = false }, leadingIcon = { Icon( TablerIcons.Copy, - contentDescription = "Copy link", + contentDescription = copyLinkText, ) }, ) @@ -154,7 +160,7 @@ fun DeeprItem( expanded = false }) DropdownMenuItem( - text = { Text("Edit") }, + text = { Text(stringResource(R.string.edit)) }, onClick = { onEditClick?.invoke(account) expanded = false @@ -162,12 +168,12 @@ fun DeeprItem( leadingIcon = { Icon( TablerIcons.Edit, - contentDescription = "Edit", + contentDescription = stringResource(R.string.edit), ) }, ) DropdownMenuItem( - text = { Text("Delete") }, + text = { Text(stringResource(R.string.delete)) }, onClick = { onRemoveClick?.invoke(account) expanded = false @@ -175,7 +181,7 @@ fun DeeprItem( leadingIcon = { Icon( TablerIcons.Trash, - contentDescription = "Delete", + contentDescription = stringResource(R.string.delete), ) }, ) diff --git a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/FilterMenu.kt b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/FilterMenu.kt index c9b343b..997e69f 100644 --- a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/FilterMenu.kt +++ b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/FilterMenu.kt @@ -12,9 +12,18 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import com.yogeshpaliyal.deepr.R import com.yogeshpaliyal.deepr.viewmodel.SortType import compose.icons.TablerIcons +import compose.icons.tablericons.Calendar +import compose.icons.tablericons.CalendarEvent +import compose.icons.tablericons.Eye +import compose.icons.tablericons.EyeOff import compose.icons.tablericons.Filter +import compose.icons.tablericons.Link +import compose.icons.tablericons.SortAscending +import compose.icons.tablericons.SortDescending @Composable fun FilterMenu( @@ -24,67 +33,115 @@ fun FilterMenu( var expanded by remember { mutableStateOf(false) } Box(modifier) { IconButton(onClick = { expanded = true }) { - Icon(TablerIcons.Filter, contentDescription = "Filter") + Icon(TablerIcons.Filter, contentDescription = stringResource(R.string.filter)) } DropdownMenu( expanded = expanded, onDismissRequest = { expanded = false }, ) { DropdownMenuItem( - text = { Text("Sort by Date Ascending") }, + text = { Text(stringResource(R.string.sort_by_date_ascending)) }, onClick = { onSortOrderChange(SortType.SORT_CREATED_BY_ASC) expanded = false }, + leadingIcon = { + Icon( + TablerIcons.Calendar, + contentDescription = null, + ) + }, ) DropdownMenuItem( - text = { Text("Sort by Date Descending") }, + text = { Text(stringResource(R.string.sort_by_date_descending)) }, onClick = { onSortOrderChange(SortType.SORT_CREATED_BY_DESC) expanded = false }, + leadingIcon = { + Icon( + TablerIcons.CalendarEvent, + contentDescription = null, + ) + }, ) DropdownMenuItem( - text = { Text("Sort by Opened Ascending") }, + text = { Text(stringResource(R.string.sort_by_opened_ascending)) }, onClick = { onSortOrderChange(SortType.SORT_OPENED_ASC) expanded = false }, + leadingIcon = { + Icon( + TablerIcons.Eye, + contentDescription = null, + ) + }, ) DropdownMenuItem( - text = { Text("Sort by Opened Descending") }, + text = { Text(stringResource(R.string.sort_by_opened_descending)) }, onClick = { onSortOrderChange(SortType.SORT_OPENED_DESC) expanded = false }, + leadingIcon = { + Icon( + TablerIcons.EyeOff, + contentDescription = null, + ) + }, ) DropdownMenuItem( - text = { Text("Sort by Name Ascending") }, + text = { Text(stringResource(R.string.sort_by_name_ascending)) }, onClick = { onSortOrderChange(SortType.SORT_NAME_ASC) expanded = false }, + leadingIcon = { + Icon( + TablerIcons.SortAscending, + contentDescription = null, + ) + }, ) DropdownMenuItem( - text = { Text("Sort by Name Descending") }, + text = { Text(stringResource(R.string.sort_by_name_descending)) }, onClick = { onSortOrderChange(SortType.SORT_NAME_DESC) expanded = false }, + leadingIcon = { + Icon( + TablerIcons.SortDescending, + contentDescription = null, + ) + }, ) DropdownMenuItem( - text = { Text("Sort by Link Ascending") }, + text = { Text(stringResource(R.string.sort_by_link_ascending)) }, onClick = { onSortOrderChange(SortType.SORT_LINK_ASC) expanded = false }, + leadingIcon = { + Icon( + TablerIcons.Link, + contentDescription = null, + ) + }, ) DropdownMenuItem( - text = { Text("Sort by Link Descending") }, + text = { Text(stringResource(R.string.sort_by_link_descending)) }, onClick = { onSortOrderChange(SortType.SORT_LINK_DESC) expanded = false }, + leadingIcon = { + Icon( + TablerIcons.Link, + contentDescription = null, + ) + }, ) } } diff --git a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/Home.kt b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/Home.kt index 5444df1..e256d02 100644 --- a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/Home.kt +++ b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/Home.kt @@ -50,13 +50,18 @@ import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalLayoutDirection +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.journeyapps.barcodescanner.ScanOptions import com.yogeshpaliyal.deepr.DeeprQueries import com.yogeshpaliyal.deepr.GetLinksAndTags +import com.yogeshpaliyal.deepr.R import com.yogeshpaliyal.deepr.SharedLink import com.yogeshpaliyal.deepr.Tags import com.yogeshpaliyal.deepr.ui.components.CreateShortcutDialog @@ -153,19 +158,21 @@ fun HomeScreen( if (searchBarState.currentValue == SearchBarValue.Collapsed) { Text( modifier = Modifier.fillMaxWidth(), - text = "Search", + text = stringResource(R.string.search), textAlign = TextAlign.Center, ) } }, leadingIcon = { if (searchBarState.currentValue == SearchBarValue.Expanded) { + val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl + TooltipBox( positionProvider = TooltipDefaults.rememberTooltipPositionProvider( TooltipAnchorPosition.Above, ), - tooltip = { PlainTooltip { Text("Back") } }, + tooltip = { PlainTooltip { Text(stringResource(R.string.back)) } }, state = rememberTooltipState(), ) { IconButton( @@ -173,7 +180,13 @@ fun HomeScreen( ) { Icon( TablerIcons.ArrowLeft, - contentDescription = "Back", + contentDescription = stringResource(R.string.back), + modifier = + if (isRtl) { + Modifier.graphicsLayer(scaleX = -1f) + } else { + Modifier + }, ) } } @@ -188,7 +201,7 @@ fun HomeScreen( TooltipDefaults.rememberTooltipPositionProvider( TooltipAnchorPosition.Below, ), - tooltip = { PlainTooltip { Text("Sorting") } }, + tooltip = { PlainTooltip { Text(stringResource(R.string.sorting)) } }, state = rememberTooltipState(), ) { FilterMenu(onSortOrderChange = { @@ -240,7 +253,7 @@ fun HomeScreen( }) { Icon( TablerIcons.Qrcode, - contentDescription = "QR Scanner", + contentDescription = stringResource(R.string.qr_scanner), ) } IconButton(onClick = { @@ -248,7 +261,7 @@ fun HomeScreen( }) { Icon( TablerIcons.Tag, - contentDescription = "Tags", + contentDescription = stringResource(R.string.tags), ) } IconButton(onClick = { @@ -257,7 +270,7 @@ fun HomeScreen( }) { Icon( TablerIcons.Settings, - contentDescription = "Settings", + contentDescription = stringResource(R.string.settings), ) } }, @@ -267,7 +280,7 @@ fun HomeScreen( }) { Icon( TablerIcons.Plus, - contentDescription = "Add Link", + contentDescription = stringResource(R.string.add_link), ) } }, @@ -436,13 +449,13 @@ fun DeeprList( tint = MaterialTheme.colorScheme.primary, ) Text( - text = "No links saved yet", + text = stringResource(R.string.no_links_saved_yet), style = MaterialTheme.typography.headlineSmall, textAlign = TextAlign.Center, ) Spacer(modifier = Modifier.height(8.dp)) Text( - text = "Save your link below to quickly access them later.", + text = stringResource(R.string.save_your_link_below), style = MaterialTheme.typography.bodyLarge, textAlign = TextAlign.Center, color = MaterialTheme.colorScheme.onSurfaceVariant, diff --git a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/HomeBottomContent.kt b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/HomeBottomContent.kt index 9fa8c9d..328fe0f 100644 --- a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/HomeBottomContent.kt +++ b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/HomeBottomContent.kt @@ -66,6 +66,10 @@ fun HomeBottomContent( viewModel: AccountViewModel = koinInject(), onSaveDialogInfoChange: ((SaveDialogInfo?) -> Unit) = {}, ) { + val context = LocalContext.current + val fetchMetadataErrorText = stringResource(R.string.failed_to_fetch_metadata) + val removeTagText = stringResource(R.string.remove_tag) + val deeplinkExistsText = stringResource(R.string.deeplink_already_exists) var deeprInfo by remember(selectedLink) { mutableStateOf( selectedLink, @@ -133,7 +137,6 @@ fun HomeBottomContent( onSaveDialogInfoChange(SaveDialogInfo(deeprInfo, executeAfterSave)) } - val context = LocalContext.current val modalBottomSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) ModalBottomSheet(sheetState = modalBottomSheetState, onDismissRequest = { @@ -150,7 +153,7 @@ fun HomeBottomContent( ).fillMaxWidth(), ) { Text( - text = if (isCreate) "Create" else "Edit", + text = if (isCreate) stringResource(R.string.create) else stringResource(R.string.edit), modifier = Modifier.padding(8.dp), style = MaterialTheme.typography.headlineMedium, ) @@ -189,14 +192,14 @@ fun HomeBottomContent( Toast .makeText( context, - "Failed to fetch metadata", + fetchMetadataErrorText, Toast.LENGTH_SHORT, ).show() } } }, ) { - Text("Fetch name from link") + Text(stringResource(R.string.fetch_name_from_link)) } Spacer(modifier = Modifier.height(8.dp)) @@ -226,7 +229,7 @@ fun HomeBottomContent( OutlinedTextField( value = newTagName, onValueChange = { newTagName = it }, - label = { Text("New tag") }, + label = { Text(stringResource(R.string.new_tag)) }, modifier = Modifier.weight(1f), singleLine = true, ) @@ -254,7 +257,7 @@ fun HomeBottomContent( }, enabled = newTagName.isNotBlank(), ) { - Text("Add Tag") + Text(stringResource(R.string.add_tag)) } } @@ -263,7 +266,7 @@ fun HomeBottomContent( // Display selected tags - only show the label if there are tags if (selectedTags.isNotEmpty()) { Text( - "Tags:", + stringResource(R.string.tags_label), style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant, ) @@ -287,7 +290,7 @@ fun HomeBottomContent( ) { Icon( imageVector = TablerIcons.X, - contentDescription = "Remove tag", + contentDescription = removeTagText, ) } }, @@ -302,7 +305,7 @@ fun HomeBottomContent( val availableSuggestions = allTags.filter { tag -> !selectedTags.contains(tag) } if (availableSuggestions.isNotEmpty()) { Text( - "Suggestions:", + stringResource(R.string.suggestions_label), style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant, ) @@ -356,7 +359,7 @@ fun HomeBottomContent( Toast .makeText( context, - "Deeplink already exists", + deeplinkExistsText, Toast.LENGTH_SHORT, ).show() } else { @@ -390,7 +393,7 @@ fun HomeBottomContent( Toast .makeText( context, - "Deeplink already exists", + deeplinkExistsText, Toast.LENGTH_SHORT, ).show() } else { diff --git a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/ShortcutMenuItem.kt b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/ShortcutMenuItem.kt index 9db8925..68b7424 100644 --- a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/ShortcutMenuItem.kt +++ b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/ShortcutMenuItem.kt @@ -7,7 +7,9 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource import com.yogeshpaliyal.deepr.GetLinksAndTags +import com.yogeshpaliyal.deepr.R import com.yogeshpaliyal.deepr.util.hasShortcut import com.yogeshpaliyal.deepr.util.isShortcutSupported import compose.icons.TablerIcons @@ -22,17 +24,20 @@ fun ShortcutMenuItem( val context = LocalContext.current val shortcutExists = remember(account.id) { hasShortcut(context, account.id) } + val addShortcutText = stringResource(R.string.add_shortcut) + val editShortcutText = stringResource(R.string.edit_shortcut) + if (isShortcutSupported(LocalContext.current)) { DropdownMenuItem( modifier = modifier, - text = { Text(if (shortcutExists) "Edit shortcut" else "Add shortcut") }, + text = { Text(if (shortcutExists) editShortcutText else addShortcutText) }, onClick = { onShortcutClick(account) }, leadingIcon = { Icon( TablerIcons.Plus, - contentDescription = if (shortcutExists) "Edit shortcut" else "Add shortcut", + contentDescription = if (shortcutExists) editShortcutText else addShortcutText, ) }, ) diff --git a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/ShowQRCodeMenuItem.kt b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/ShowQRCodeMenuItem.kt index 9e32c80..a3840ce 100644 --- a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/ShowQRCodeMenuItem.kt +++ b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/ShowQRCodeMenuItem.kt @@ -5,7 +5,9 @@ import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource import com.yogeshpaliyal.deepr.GetLinksAndTags +import com.yogeshpaliyal.deepr.R import compose.icons.TablerIcons import compose.icons.tablericons.Qrcode @@ -17,14 +19,14 @@ fun ShowQRCodeMenuItem( ) { DropdownMenuItem( modifier = modifier, - text = { Text("Show QR Code") }, + text = { Text(stringResource(R.string.show_qr_code)) }, onClick = { onQrCodeClick(account) }, leadingIcon = { Icon( TablerIcons.Qrcode, - contentDescription = "Show QR Code", + contentDescription = stringResource(R.string.show_qr_code), ) }, ) diff --git a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/TagSelectionBottomSheet.kt b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/TagSelectionBottomSheet.kt index 9423532..ff5949b 100644 --- a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/TagSelectionBottomSheet.kt +++ b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/TagSelectionBottomSheet.kt @@ -14,6 +14,8 @@ import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import com.yogeshpaliyal.deepr.R import com.yogeshpaliyal.deepr.Tags @OptIn(ExperimentalMaterial3Api::class) @@ -31,7 +33,7 @@ fun TagSelectionBottomSheet( Column(modifier) { TopAppBar( title = { - Text("Tags") + Text(stringResource(R.string.tags)) }, colors = TopAppBarDefaults.topAppBarColors(containerColor = Color.Transparent), ) @@ -42,7 +44,7 @@ fun TagSelectionBottomSheet( setTagFilter(null) dismissBottomSheet() }, - headlineContent = { Text("All") }, + headlineContent = { Text(stringResource(R.string.all)) }, colors = if (selectedTag == null) { ListItemDefaults.colors( diff --git a/app/src/main/java/com/yogeshpaliyal/deepr/util/LanguageUtil.kt b/app/src/main/java/com/yogeshpaliyal/deepr/util/LanguageUtil.kt new file mode 100644 index 0000000..7b92638 --- /dev/null +++ b/app/src/main/java/com/yogeshpaliyal/deepr/util/LanguageUtil.kt @@ -0,0 +1,80 @@ +package com.yogeshpaliyal.deepr.util + +import android.content.Context +import android.content.res.Configuration +import android.os.Build +import java.util.Locale + +object LanguageUtil { + // Language code constants + const val SYSTEM_DEFAULT = "" + const val ENGLISH = "en" + const val HINDI = "hi" + const val SPANISH = "es" + const val FRENCH = "fr" + const val GERMAN = "de" + const val URDU = "ur" + + // Available languages + data class Language( + val code: String, + val name: String, + val nativeName: String, + ) + + val availableLanguages = + listOf( + Language(SYSTEM_DEFAULT, "System Default", "System Default"), + Language(ENGLISH, "English", "English"), + Language(HINDI, "Hindi", "हिंदी"), + Language(SPANISH, "Spanish", "Español"), + Language(FRENCH, "French", "Français"), + Language(GERMAN, "German", "Deutsch"), + Language(URDU, "Urdu", "اردو"), + ) + + /** + * Updates the app's locale configuration + */ + fun updateLocale( + context: Context, + languageCode: String, + ): Context { + val locale = + if (languageCode.isEmpty()) { + // Use system default locale + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + context.resources.configuration.locales[0] + } else { + @Suppress("DEPRECATION") + context.resources.configuration.locale + } + } else { + Locale(languageCode) + } + + Locale.setDefault(locale) + + val configuration = Configuration(context.resources.configuration) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + configuration.setLocale(locale) + return context.createConfigurationContext(configuration) + } else { + @Suppress("DEPRECATION") + configuration.locale = locale + context.resources.updateConfiguration(configuration, context.resources.displayMetrics) + return context + } + } + + /** + * Gets the display name for a language code + */ + fun getLanguageDisplayName(languageCode: String): String = availableLanguages.find { it.code == languageCode }?.name ?: "System Default" + + /** + * Gets the native name for a language code + */ + fun getLanguageNativeName(languageCode: String): String = + availableLanguages.find { it.code == languageCode }?.nativeName ?: "System Default" +} diff --git a/app/src/main/java/com/yogeshpaliyal/deepr/viewmodel/AccountViewModel.kt b/app/src/main/java/com/yogeshpaliyal/deepr/viewmodel/AccountViewModel.kt index c3e1702..2d33165 100644 --- a/app/src/main/java/com/yogeshpaliyal/deepr/viewmodel/AccountViewModel.kt +++ b/app/src/main/java/com/yogeshpaliyal/deepr/viewmodel/AccountViewModel.kt @@ -273,6 +273,17 @@ class AccountViewModel( } } + // Language preference methods + val languageCode = + preferenceDataStore.getLanguageCode + .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), "") + + fun setLanguageCode(code: String) { + viewModelScope.launch(Dispatchers.IO) { + preferenceDataStore.setLanguageCode(code) + } + } + // Sync preference methods val syncEnabled = preferenceDataStore.getSyncEnabled diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml new file mode 100644 index 0000000..e9d6033 --- /dev/null +++ b/app/src/main/res/values-de/strings.xml @@ -0,0 +1,128 @@ + + Deepr + + + Einstellungen + Über uns + Zurück + Speichern + Gespeichert + Ausführen + Abbrechen + Suchen + Erstellen + Bearbeiten + Sortierung + QR-Scanner + Tags + Alle + Link hinzufügen + Name vom Link abrufen + Tag hinzufügen + Neuer Tag + Noch keine Links gespeichert + Speichern Sie Ihren Link unten, um später schnell darauf zugreifen zu können. + + + Weitere Optionen + Link kopieren + Link kopiert + Löschen + Tag entfernen + Fehler beim Abrufen der Metadaten + Geöffnet: %d + Tags: + Vorschläge: + Filter + Verknüpfung hinzufügen + Verknüpfung bearbeiten + QR-Code anzeigen + Deeplink existiert bereits + + + Nach Datum aufsteigend sortieren + Nach Datum absteigend sortieren + Nach Öffnung aufsteigend sortieren + Nach Öffnung absteigend sortieren + Nach Name aufsteigend sortieren + Nach Name absteigend sortieren + Nach Link aufsteigend sortieren + Nach Link absteigend sortieren + + + Deeplinks importieren + Deeplinks aus CSV-Datei importieren + Deeplinks exportieren + Deeplinks in CSV-Datei exportieren + Verknüpfungssymbol + Symbol der Link-unterstützenden App verwenden + Deepr-App-Symbol verwenden + Verknüpfungssymbol-Einstellung + Sprache + App-Sprache ändern + Sprache auswählen + Systemstandard + English + हिंदी + Español + Français + Deutsch + اردو + App-Version: %s + Mit ❤️ in Indien gemacht + + + App-Logo + Version %s + Eine einfache App zum Speichern, Organisieren und Starten von Deeplinks. + Autor + Yogesh Choudhary + Twitter + GitHub + LinkedIn + Auf GitHub ansehen + + + Deeplink speichern + Deeplink speichern: %s ? + Bitte geben Sie den Namen des Links ein + Bitte geben Sie den Namen des Links ein. + Speichern und ausführen + + + Deeplink oder Befehl eingeben + Ungültiger oder leerer Deeplink. + + + Ungültiger Deeplink: %s + Keine Daten in der Datenbank zum Exportieren gefunden. + Keine Daten zum Exportieren nach Mapping verfügbar. + Erfolgreich exportiert nach %s + Fehler beim Erstellen der CSV-Datei. + + + Synchronisationsdatei auswählen + Jetzt synchronisieren + Letzte Synchronisation: + Noch nie synchronisiert + %s + + + Synchronisation ist deaktiviert + Keine Synchronisationsdatei ausgewählt + Erfolgreich mit %s synchronisiert + Synchronisation fehlgeschlagen: %s + Kein Dateipfad angegeben + Ungültiges Markdown-Tabellenformat + Dateivalidierungsfehler: %s + + + Mit lokaler Datei synchronisieren (Beta) + Deeplinks automatisch mit einer Markdown-Datei synchronisieren + Dateispeicherort für Markdown-Synchronisation wählen + Dateiformat-Validierung + ✓ Dateiformat ist gültig + ⚠ Dateiformat ist ungültig + Keine Sync-Datei ausgewählt + Deeplinks manuell mit ausgewählter Datei synchronisieren + \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml new file mode 100644 index 0000000..d60b220 --- /dev/null +++ b/app/src/main/res/values-es/strings.xml @@ -0,0 +1,128 @@ + + Deepr + + + Configuración + Acerca de nosotros + Atrás + Guardar + Guardado + Ejecutar + Cancelar + Buscar + Crear + Editar + Ordenar + Escáner QR + Etiquetas + Todos + Agregar enlace + Obtener nombre del enlace + Agregar etiqueta + Nueva etiqueta + Aún no hay enlaces guardados + Guarda tu enlace abajo para acceder rápidamente más tarde. + + + Más opciones + Copiar enlace + Enlace copiado + Eliminar + Eliminar etiqueta + Error al obtener metadatos + Abierto: %d + Etiquetas: + Sugerencias: + Filtrar + Agregar acceso directo + Editar acceso directo + Mostrar código QR + El enlace profundo ya existe + + + Ordenar por Fecha Ascendente + Ordenar por Fecha Descendente + Ordenar por Abierto Ascendente + Ordenar por Abierto Descendente + Ordenar por Nombre Ascendente + Ordenar por Nombre Descendente + Ordenar por Enlace Ascendente + Ordenar por Enlace Descendente + + + Importar Deeplinks + Importar Deeplinks desde archivo CSV + Exportar Deeplinks + Exportar Deeplinks a archivo CSV + Icono de acceso directo + Usar icono de la app que soporta enlaces + Usar icono de la app Deepr + Configuración de icono de acceso directo + Idioma + Cambiar idioma de la aplicación + Seleccionar idioma + Predeterminado del sistema + English + हिंदी + Español + Français + Deutsch + اردو + Versión de la aplicación: %s + Hecho con ❤️ en India + + + Logo de la aplicación + Versión %s + Una aplicación simple para guardar, organizar y lanzar enlaces profundos. + Autor + Yogesh Choudhary + Twitter + GitHub + LinkedIn + Ver en GitHub + + + Guardar enlace profundo + ¿Guardar el enlace profundo: %s? + Por favor, ingresa el nombre del enlace + Por favor, ingresa el nombre del enlace. + Guardar y ejecutar + + + Ingresa enlace profundo o comando + Enlace profundo inválido o vacío. + + + Enlace profundo inválido: %s + No se encontraron datos en la base de datos para exportar. + No hay datos disponibles para exportar después del mapeo. + Exportado exitosamente a %s + Error al crear archivo CSV. + + + Seleccionar archivo de sincronización + Sincronizar ahora + Última sincronización: + Nunca sincronizado + %s + + + Sincronización deshabilitada + No se seleccionó archivo de sincronización + Sincronizado exitosamente con %s + Error de sincronización: %s + No se proporcionó ruta de archivo + Formato de tabla markdown inválido + Error de validación de archivo: %s + + + Sincronizar a archivo local (Beta) + Sincronizar automáticamente enlaces profundos a un archivo markdown + Elegir ubicación del archivo para sincronización markdown + Validación de formato de archivo + ✓ El formato del archivo es válido + ⚠ El formato del archivo es inválido + No se seleccionó archivo de sincronización + Sincronizar manualmente enlaces profundos al archivo seleccionado + \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml new file mode 100644 index 0000000..d5172cd --- /dev/null +++ b/app/src/main/res/values-fr/strings.xml @@ -0,0 +1,128 @@ + + Deepr + + + Paramètres + À propos de nous + Retour + Enregistrer + Enregistré + Exécuter + Annuler + Rechercher + Créer + Éditer + Tri + Scanner QR + Étiquettes + Tous + Ajouter un lien + Récupérer le nom depuis le lien + Ajouter une étiquette + Nouvelle étiquette + Aucun lien sauvegardé pour le moment + Enregistrez votre lien ci-dessous pour y accéder rapidement plus tard. + + + Plus d\'options + Copier le lien + Lien copié + Supprimer + Supprimer l\'étiquette + Échec de la récupération des métadonnées + Ouvert : %d + Étiquettes : + Suggestions : + Filtrer + Ajouter un raccourci + Modifier le raccourci + Afficher le code QR + Le lien profond existe déjà + + + Trier par Date Croissante + Trier par Date Décroissante + Trier par Ouverture Croissante + Trier par Ouverture Décroissante + Trier par Nom Croissant + Trier par Nom Décroissant + Trier par Lien Croissant + Trier par Lien Décroissant + + + Importer des Deeplinks + Importer des Deeplinks depuis un fichier CSV + Exporter des Deeplinks + Exporter des Deeplinks vers un fichier CSV + Icône de raccourci + Utiliser l\'icône de l\'application prenant en charge les liens + Utiliser l\'icône de l\'application Deepr + Paramètre d\'icône de raccourci + Langue + Changer la langue de l\'application + Sélectionner la langue + Par défaut du système + English + हिंदी + Español + Français + Deutsch + اردو + Version de l\'application : %s + Fait avec ❤️ en Inde + + + Logo de l\'application + Version %s + Une application simple pour sauvegarder, organiser et lancer des liens profonds. + Auteur + Yogesh Choudhary + Twitter + GitHub + LinkedIn + Voir sur GitHub + + + Sauvegarder le lien profond + Sauvegarder le lien profond : %s ? + Veuillez saisir le nom du lien + Veuillez saisir le nom du lien. + Sauvegarder et exécuter + + + Saisir un lien profond ou une commande + Lien profond invalide ou vide. + + + Lien profond invalide : %s + Aucune donnée trouvée dans la base de données à exporter. + Aucune donnée disponible à exporter après mapping. + Exporté avec succès vers %s + Échec de la création du fichier CSV. + + + Sélectionner le fichier de synchronisation + Synchroniser maintenant + Dernière synchronisation : + Jamais synchronisé + %s + + + La synchronisation est désactivée + Aucun fichier de synchronisation sélectionné + Synchronisé avec succès avec %s + Échec de la synchronisation : %s + Aucun chemin de fichier fourni + Format de tableau markdown invalide + Erreur de validation du fichier : %s + + + Synchroniser vers un fichier local (Bêta) + Synchroniser automatiquement les liens profonds vers un fichier markdown + Choisir l\'emplacement du fichier pour la synchronisation markdown + Validation du format de fichier + ✓ Le format du fichier est valide + ⚠ Le format du fichier est invalide + Aucun fichier de synchronisation sélectionné + Synchroniser manuellement les liens profonds vers le fichier sélectionné + \ No newline at end of file diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml new file mode 100644 index 0000000..4126728 --- /dev/null +++ b/app/src/main/res/values-hi/strings.xml @@ -0,0 +1,128 @@ + + Deepr + + + सेटिंग्स + हमारे बारे में + वापस + सहेजें + सहेजा गया + निष्पादित करें + रद्द करें + खोजें + बनाएं + संपादित करें + क्रमबद्ध करना + क्यूआर स्कैनर + टैग्स + सभी + लिंक जोड़ें + लिंक से नाम प्राप्त करें + टैग जोड़ें + नया टैग + अभी तक कोई लिंक सहेजे नहीं गए + बाद में तुरंत एक्सेस करने के लिए अपना लिंक नीचे सेव करें। + + + अधिक विकल्प + लिंक कॉपी करें + लिंक कॉपी किया गया + हटाएं + टैग हटाएं + मेटाडेटा प्राप्त करने में विफल + खोला गया: %d + टैग: + सुझाव: + फ़िल्टर + शॉर्टकट जोड़ें + शॉर्टकट संपादित करें + QR कोड दिखाएं + डीपलिंक पहले से मौजूद है + + + दिनांक के अनुसार आरोही क्रम में + दिनांक के अनुसार अवरोही क्रम में + खोले गए के अनुसार आरोही क्रम में + खोले गए के अनुसार अवरोही क्रम में + नाम के अनुसार आरोही क्रम में + नाम के अनुसार अवरोही क्रम में + लिंक के अनुसार आरोही क्रम में + लिंक के अनुसार अवरोही क्रम में + + + Deeplinks आयात करें + CSV फ़ाइल से Deeplinks आयात करें + Deeplinks निर्यात करें + Deeplinks को CSV फ़ाइल में निर्यात करें + शॉर्टकट आइकन + लिंक समर्थन करने वाले ऐप का आइकन उपयोग करें + Deepr ऐप आइकन उपयोग करें + शॉर्टकट आइकन सेटिंग + भाषा + ऐप की भाषा बदलें + भाषा चुनें + सिस्टम डिफ़ॉल्ट + English + हिंदी + Español + Français + Deutsch + اردو + ऐप संस्करण: %s + भारत में ❤️ के साथ बनाया गया + + + ऐप लोगो + संस्करण %s + डीपलिंक सहेजने, व्यवस्थित करने और लॉन्च करने के लिए एक सरल ऐप। + लेखक + योगेश चौधरी + ट्विटर + गिटहब + लिंक्डइन + गिटहब पर देखें + + + डीपलिंक सहेजें + डीपलिंक सहेजें: %s ? + कृपया लिंक का नाम दर्ज करें + कृपया लिंक का नाम दर्ज करें। + सहेजें और निष्पादित करें + + + डीपलिंक या कमांड दर्ज करें + अमान्य या खाली डीपलिंक। + + + अमान्य डीपलिंक: %s + निर्यात करने के लिए डेटाबेस में कोई डेटा नहीं मिला। + मैपिंग के बाद निर्यात करने के लिए कोई डेटा उपलब्ध नहीं। + सफलतापूर्वक %s में निर्यात किया गया + CSV फ़ाइल बनाने में विफल। + + + सिंक फ़ाइल चुनें + अभी सिंक करें + अंतिम सिंक समय: + कभी सिंक नहीं हुआ + %s + + + सिंक अक्षम है + कोई सिंक फ़ाइल नहीं चुनी गई + %s के साथ सफलतापूर्वक सिंक हो गया + सिंक विफल: %s + कोई फ़ाइल पथ प्रदान नहीं किया गया + अमान्य मार्कडाउन तालिका प्रारूप + फ़ाइल सत्यापन त्रुटि: %s + + + स्थानीय फ़ाइल में सिंक करें (बीटा) + डीपलिंक्स को मार्कडाउन फ़ाइल में स्वचालित रूप से सिंक करें + मार्कडाउन सिंक के लिए फ़ाइल स्थान चुनें + फ़ाइल प्रारूप सत्यापन + ✓ फ़ाइल प्रारूप वैध है + ⚠ फ़ाइल प्रारूप अवैध है + कोई सिंक फ़ाइल नहीं चुनी गई + चयनित फ़ाइल में डीपलिंक्स को मैन्युअल रूप से सिंक करें + \ No newline at end of file diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml new file mode 100644 index 0000000..f667f02 --- /dev/null +++ b/app/src/main/res/values-ur/strings.xml @@ -0,0 +1,128 @@ + + Deepr + + + سیٹنگز + ہمارے بارے میں + واپس + محفوظ کریں + محفوظ ہو گیا + چلائیں + منسوخ کریں + تلاش کریں + بنائیں + ترمیم کریں + ترتیب + QR اسکینر + ٹیگز + تمام + لنک شامل کریں + لنک سے نام حاصل کریں + ٹیگ شامل کریں + نیا ٹیگ + ابھی تک کوئی لنک محفوظ نہیں + بعد میں تیزی سے رسائی کے لیے اپنا لنک نیچے محفوظ کریں۔ + + + مزید اختیارات + لنک کاپی کریں + لنک کاپی ہو گیا + حذف کریں + ٹیگ ہٹائیں + میٹاڈیٹا لانے میں ناکام + کھولا گیا: %d + ٹیگز: + تجاویز: + فلٹر + شارٹ کٹ شامل کریں + شارٹ کٹ میں تبدیلی + QR کوڈ دکھائیں + ڈیپ لنک پہلے سے موجود ہے + + + تاریخ کے حساب سے صاعد ترتیب + تاریخ کے حساب سے نازل ترتیب + کھولے گئے کے حساب سے صاعد ترتیب + کھولے گئے کے حساب سے نازل ترتیب + نام کے حساب سے صاعد ترتیب + نام کے حساب سے نازل ترتیب + لنک کے حساب سے صاعد ترتیب + لنک کے حساب سے نازل ترتیب + + + Deeplinks درآمد کریں + CSV فائل سے Deeplinks درآمد کریں + Deeplinks برآمد کریں + Deeplinks کو CSV فائل میں برآمد کریں + شارٹ کٹ آئیکن + لنک سپورٹ کرنے والے ایپ کا آئیکن استعمال کریں + Deepr ایپ آئیکن استعمال کریں + شارٹ کٹ آئیکن سیٹنگ + زبان + ایپ کی زبان تبدیل کریں + زبان منتخب کریں + سسٹم ڈیفالٹ + English + हिंदी + Español + Français + Deutsch + اردو + ایپ ورژن: %s + ہندوستان میں ❤️ کے ساتھ بنایا گیا + + + ایپ لوگو + ورژن %s + ڈیپ لنکس کو محفوظ کرنے، منظم کرنے اور لانچ کرنے کے لیے ایک آسان ایپ۔ + مصنف + یوگیش چوہدری + ٹویٹر + گٹ ہب + لنکڈ ان + گٹ ہب پر دیکھیں + + + ڈیپ لنک محفوظ کریں + ڈیپ لنک محفوظ کریں: %s؟ + براہ کرم لنک کا نام داخل کریں + براہ کرم لنک کا نام داخل کریں۔ + محفوظ کریں اور چلائیں + + + ڈیپ لنک یا کمانڈ داخل کریں + غلط یا خالی ڈیپ لنک۔ + + + غلط ڈیپ لنک: %s + ایکسپورٹ کرنے کے لیے ڈیٹابیس میں کوئی ڈیٹا نہیں ملا۔ + میپنگ کے بعد ایکسپورٹ کرنے کے لیے کوئی ڈیٹا دستیاب نہیں۔ + کامیابی سے %s میں ایکسپورٹ کیا گیا + CSV فائل بنانے میں ناکام۔ + + + ہم آہنگی فائل منتخب کریں + ابھی ہم آہنگ کریں + آخری ہم آہنگی: + کبھی ہم آہنگ نہیں ہوا + %s + + + ہم آہنگی غیر فعال ہے + کوئی ہم آہنگی فائل منتخب نہیں + %s کے ساتھ کامیابی سے ہم آہنگ + ہم آہنگی ناکام: %s + کوئی فائل کا راستہ فراہم نہیں کیا گیا + غلط مارک ڈاؤن ٹیبل فارمیٹ + فائل توثیق کی خرابی: %s + + + مقامی فائل سے ہم آہنگ کریں (بیٹا) + ڈیپ لنکس کو مارک ڈاؤن فائل میں خودکار طور پر ہم آہنگ کریں + مارک ڈاؤن ہم آہنگی کے لیے فائل کا مقام منتخب کریں + فائل فارمیٹ کی توثیق + ✓ فائل فارمیٹ درست ہے + ⚠ فائل فارمیٹ غلط ہے + کوئی ہم آہنگی فائل منتخب نہیں + منتخب کردہ فائل میں ڈیپ لنکس کو دستی طور پر ہم آہنگ کریں + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0092104..4e248d2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -9,6 +9,45 @@ Saved Execute Cancel + Search + Create + Edit + Sorting + QR Scanner + Tags + All + Add Link + Fetch name from link + Add Tag + New tag + No links saved yet + Save your link below to quickly access them later. + + + More options + Copy link + Link copied + Delete + Remove tag + Failed to fetch metadata + Opened: %d + Tags: + Suggestions: + Filter + Add shortcut + Edit shortcut + Show QR Code + Deeplink already exists + + + Sort by Date Ascending + Sort by Date Descending + Sort by Opened Ascending + Sort by Opened Descending + Sort by Name Ascending + Sort by Name Descending + Sort by Link Ascending + Sort by Link Descending Import Deeplinks @@ -19,6 +58,16 @@ Use link supporting app icon Use Deepr app icon Shortcut Icon Setting + Language + Change app language + Select Language + System Default + English + हिंदी + Español + Français + Deutsch + اردو App Version: %s Made with ❤️ in India From 873e2da6d4c7d316d5c1943c46d9ab8a9f0808b2 Mon Sep 17 00:00:00 2001 From: Faded Date: Sun, 21 Sep 2025 16:48:28 +0500 Subject: [PATCH 2/9] chore: extracted hardcoded texts form TagSelectionBottomSheet into strings --- .../ui/screens/home/TagSelectionBottomSheet.kt | 17 +++++++++++------ app/src/main/res/values-de/strings.xml | 12 ++++++++++++ app/src/main/res/values-es/strings.xml | 12 ++++++++++++ app/src/main/res/values-fr/strings.xml | 12 ++++++++++++ app/src/main/res/values-hi/strings.xml | 14 ++++++++++++-- app/src/main/res/values-ur/strings.xml | 15 +++++++++++++-- app/src/main/res/values/strings.xml | 4 +--- 7 files changed, 73 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/TagSelectionBottomSheet.kt b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/TagSelectionBottomSheet.kt index e502b5d..0a510de 100644 --- a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/TagSelectionBottomSheet.kt +++ b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/TagSelectionBottomSheet.kt @@ -130,22 +130,27 @@ fun TagSelectionBottomSheet( Button(onClick = { val result = deleteTag(tag) if (result.isFailure) { - Toast.makeText(context, "Failed to delete tag ${result.exceptionOrNull()}", Toast.LENGTH_SHORT).show() + Toast + .makeText( + context, + context.getString(R.string.failed_to_delete_tag, result.exceptionOrNull()), + Toast.LENGTH_SHORT, + ).show() } else { isTagDeleteEnable = null Toast - .makeText(context, "Tag deleted successfully", Toast.LENGTH_SHORT) + .makeText(context, context.getString(R.string.tag_deleted_successfully), Toast.LENGTH_SHORT) .show() } }, colors = ButtonDefaults.buttonColors(containerColor = Color.Red)) { - Text("Delete") + Text(stringResource(R.string.delete)) } }, dismissButton = { Button(onClick = { isTagDeleteEnable = null }) { - Text("Cancel") + Text(stringResource(R.string.cancel)) } }, ) @@ -194,7 +199,7 @@ fun TagSelectionBottomSheet( }) { Icon( imageVector = TablerIcons.Edit, - contentDescription = "Edit Tag", + contentDescription = stringResource(R.string.edit_tag_description), ) } @@ -203,7 +208,7 @@ fun TagSelectionBottomSheet( }) { Icon( imageVector = TablerIcons.Trash, - contentDescription = "Clear Tag", + contentDescription = stringResource(R.string.delete_tag_description), ) } } diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index e9d6033..df2a1f9 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -1,5 +1,17 @@ Deepr + + + Tag Bearbeiten + Tag Löschen + Sind Sie sicher, dass Sie diesen Tag löschen möchten? + Ein Tag mit diesem Namen existiert bereits + Fehler beim Bearbeiten des Tags + Tag erfolgreich bearbeitet + Fehler beim Löschen des Tags: %s + Tag erfolgreich gelöscht + Tag Bearbeiten + Tag Löschening> Einstellungen diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index d60b220..cb0f4f3 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -48,6 +48,18 @@ Ordenar por Nombre Descendente Ordenar por Enlace Ascendente Ordenar por Enlace Descendente + + + Editar Etiqueta + Eliminar Etiqueta + ¿Estás seguro de que quieres eliminar esta etiqueta? + Ya existe una etiqueta con este nombre + Error al editar la etiqueta + Etiqueta editada exitosamente + Error al eliminar la etiqueta: %s + Etiqueta eliminada exitosamente + Editar Etiqueta + Eliminar Etiqueta Importar Deeplinks diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index d5172cd..2ee3d16 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -48,6 +48,18 @@ Trier par Nom Décroissant Trier par Lien Croissant Trier par Lien Décroissant + + + Modifier le Tag + Supprimer le Tag + Êtes-vous sûr de vouloir supprimer ce tag ? + Un tag avec ce nom existe déjà + Échec de la modification du tag + Tag modifié avec succès + Échec de la suppression du tag: %s + Tag supprimé avec succès + Modifier le Tag + Supprimer le Tag Importer des Deeplinks diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 4126728..90df347 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -1,7 +1,17 @@ Deepr - - + + + टैग संपादित करें + टैग हटाएं + क्या आप वाकई इस टैग को हटाना चाहते हैं? + इस नाम के साथ एक टैग पहले से मौजूद है + टैग संपादित करने में विफल + टैग सफलतापूर्वक संपादित + टैग हटाने में विफल: %s + टैग सफलतापूर्वक हटाया गया + टैग संपादित करें + टैग हटाएं Navigation and UI Labels --> सेटिंग्स हमारे बारे में वापस diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml index f667f02..b9f949a 100644 --- a/app/src/main/res/values-ur/strings.xml +++ b/app/src/main/res/values-ur/strings.xml @@ -48,8 +48,19 @@ نام کے حساب سے نازل ترتیب لنک کے حساب سے صاعد ترتیب لنک کے حساب سے نازل ترتیب - - + + + + ٹیگ ایڈٹ کریں + ٹیگ حذف کریں + کیا آپ واقعی اس ٹیگ کو حذف کرنا چاہتے ہیں؟ + اس نام کے ساتھ ایک ٹیگ پہلے سے موجود ہے + ٹیگ ایڈٹ کرنے میں ناکام + ٹیگ کامیابی سے ایڈٹ ہوگیا + ٹیگ حذف کرنے میں ناکام: %s + ٹیگ کامیابی سے حذف ہوگیا + ٹیگ ایڈٹ کریں + ٹیگ حذف کریں Deeplinks درآمد کریں CSV فائل سے Deeplinks درآمد کریں Deeplinks برآمد کریں diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f41df6c..16b99d7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -52,13 +52,11 @@ Edit Tag Delete Tag - Edit - Cancel Are you sure you want to delete this tag? Tag with this name already exists Failed to edit tag Tag edited successfully - Failed to delete tag + Failed to delete tag: %s Tag deleted successfully Edit Tag Delete Tag From 69dac203ac2eee7b4dc07fb79ca185b3f8f1c42a Mon Sep 17 00:00:00 2001 From: Faded Date: Mon, 22 Sep 2025 07:49:43 +0500 Subject: [PATCH 3/9] fix: update LanguageSelectionDialog to use ListItemDefaults for transparent bg langauge items --- .../deepr/ui/components/LanguageSelectionDialog.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/java/com/yogeshpaliyal/deepr/ui/components/LanguageSelectionDialog.kt b/app/src/main/java/com/yogeshpaliyal/deepr/ui/components/LanguageSelectionDialog.kt index 95743ad..fc4a096 100644 --- a/app/src/main/java/com/yogeshpaliyal/deepr/ui/components/LanguageSelectionDialog.kt +++ b/app/src/main/java/com/yogeshpaliyal/deepr/ui/components/LanguageSelectionDialog.kt @@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.AlertDialog import androidx.compose.material3.ListItem +import androidx.compose.material3.ListItemDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.RadioButton import androidx.compose.material3.Text @@ -14,6 +15,7 @@ import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.yogeshpaliyal.deepr.R @@ -74,6 +76,10 @@ fun LanguageSelectionDialog( }, ) }, + colors = + ListItemDefaults.colors( + containerColor = Color.Transparent, + ), ) } } From 18e3697fffe84a7f1fd2bbe119f824f81742c19c Mon Sep 17 00:00:00 2001 From: Faded Date: Mon, 22 Sep 2025 07:52:54 +0500 Subject: [PATCH 4/9] fix: correct formatting issues in string resources for German, Spanish, Hindi, and Urdu --- app/src/main/res/values-de/strings.xml | 2 +- app/src/main/res/values-es/strings.xml | 2 +- app/src/main/res/values-hi/strings.xml | 4 +++- app/src/main/res/values-ur/strings.xml | 4 +++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index df2a1f9..ee5fe5c 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -11,7 +11,7 @@ Fehler beim Löschen des Tags: %s Tag erfolgreich gelöscht Tag Bearbeiten - Tag Löschening> + Tag Löschen Einstellungen diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index cb0f4f3..2584183 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -120,7 +120,7 @@ %s - Sincronización deshabilitada + Sincronización deshabilitada No se seleccionó archivo de sincronización Sincronizado exitosamente con %s Error de sincronización: %s diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 90df347..5014add 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -11,7 +11,9 @@ टैग हटाने में विफल: %s टैग सफलतापूर्वक हटाया गया टैग संपादित करें - टैग हटाएं Navigation and UI Labels --> + टैग हटाएं + + सेटिंग्स हमारे बारे में वापस diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml index b9f949a..d58d46a 100644 --- a/app/src/main/res/values-ur/strings.xml +++ b/app/src/main/res/values-ur/strings.xml @@ -60,7 +60,9 @@ ٹیگ حذف کرنے میں ناکام: %s ٹیگ کامیابی سے حذف ہوگیا ٹیگ ایڈٹ کریں - ٹیگ حذف کریں + ٹیگ حذف کریں + + Deeplinks درآمد کریں CSV فائل سے Deeplinks درآمد کریں Deeplinks برآمد کریں From 04e0975fff15603dda01a4280b25e04ae6c259ba Mon Sep 17 00:00:00 2001 From: Faded <124708903+anonfaded@users.noreply.github.com> Date: Mon, 22 Sep 2025 07:59:43 +0500 Subject: [PATCH 5/9] Update app/src/main/res/values-ur/strings.xml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- app/src/main/res/values-ur/strings.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml index d58d46a..c764e27 100644 --- a/app/src/main/res/values-ur/strings.xml +++ b/app/src/main/res/values-ur/strings.xml @@ -49,7 +49,6 @@ لنک کے حساب سے صاعد ترتیب لنک کے حساب سے نازل ترتیب - ٹیگ ایڈٹ کریں ٹیگ حذف کریں From 891a151aa4a5d923ea9330d20965968cb7877f0d Mon Sep 17 00:00:00 2001 From: Faded Date: Mon, 22 Sep 2025 08:16:26 +0500 Subject: [PATCH 6/9] fix: update language display handling in LanguageSelectionDialog and Settings screen --- .../ui/components/LanguageSelectionDialog.kt | 24 +++++++++++++++---- .../deepr/ui/screens/Settings.kt | 8 ++++++- .../yogeshpaliyal/deepr/util/LanguageUtil.kt | 7 +++--- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/yogeshpaliyal/deepr/ui/components/LanguageSelectionDialog.kt b/app/src/main/java/com/yogeshpaliyal/deepr/ui/components/LanguageSelectionDialog.kt index fc4a096..cedf60e 100644 --- a/app/src/main/java/com/yogeshpaliyal/deepr/ui/components/LanguageSelectionDialog.kt +++ b/app/src/main/java/com/yogeshpaliyal/deepr/ui/components/LanguageSelectionDialog.kt @@ -40,6 +40,22 @@ fun LanguageSelectionDialog( text = { Column { LanguageUtil.availableLanguages.forEach { language -> + val displayName = + if (language.code == LanguageUtil.SYSTEM_DEFAULT) { + stringResource(R.string.system_default) + } else { + language.nativeName + } + + val supportingText = + if (language.code == LanguageUtil.SYSTEM_DEFAULT) { + null // No supporting text for system default + } else if (language.name != language.nativeName) { + language.name + } else { + null + } + ListItem( modifier = Modifier @@ -51,21 +67,19 @@ fun LanguageSelectionDialog( }.padding(vertical = 4.dp), headlineContent = { Text( - text = language.nativeName, + text = displayName, style = MaterialTheme.typography.bodyLarge, ) }, supportingContent = - if (language.name != language.nativeName) { + supportingText?.let { text -> { Text( - text = language.name, + text = text, style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant, ) } - } else { - null }, trailingContent = { RadioButton( diff --git a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/Settings.kt b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/Settings.kt index 7877964..9291486 100644 --- a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/Settings.kt +++ b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/Settings.kt @@ -363,7 +363,13 @@ fun SettingsScreen( headlineContent = { Text(stringResource(R.string.language)) }, supportingContent = { Text( - LanguageUtil.getLanguageNativeName(languageCode), + if (languageCode.isEmpty()) { + stringResource(R.string.system_default) + } else { + LanguageUtil.getLanguageNativeName(languageCode).ifEmpty { + stringResource(R.string.system_default) + } + }, ) }, leadingContent = { diff --git a/app/src/main/java/com/yogeshpaliyal/deepr/util/LanguageUtil.kt b/app/src/main/java/com/yogeshpaliyal/deepr/util/LanguageUtil.kt index 7b92638..42244f6 100644 --- a/app/src/main/java/com/yogeshpaliyal/deepr/util/LanguageUtil.kt +++ b/app/src/main/java/com/yogeshpaliyal/deepr/util/LanguageUtil.kt @@ -24,7 +24,7 @@ object LanguageUtil { val availableLanguages = listOf( - Language(SYSTEM_DEFAULT, "System Default", "System Default"), + Language(SYSTEM_DEFAULT, "", ""), // Will be replaced in UI with localized strings Language(ENGLISH, "English", "English"), Language(HINDI, "Hindi", "हिंदी"), Language(SPANISH, "Spanish", "Español"), @@ -70,11 +70,10 @@ object LanguageUtil { /** * Gets the display name for a language code */ - fun getLanguageDisplayName(languageCode: String): String = availableLanguages.find { it.code == languageCode }?.name ?: "System Default" + fun getLanguageDisplayName(languageCode: String): String = availableLanguages.find { it.code == languageCode }?.name ?: "" /** * Gets the native name for a language code */ - fun getLanguageNativeName(languageCode: String): String = - availableLanguages.find { it.code == languageCode }?.nativeName ?: "System Default" + fun getLanguageNativeName(languageCode: String): String = availableLanguages.find { it.code == languageCode }?.nativeName ?: "" } From bcb04e0271f5b3179e6ac56f5c7c4f682c42550d Mon Sep 17 00:00:00 2001 From: Faded Date: Mon, 22 Sep 2025 08:19:38 +0500 Subject: [PATCH 7/9] fix: update icons in FilterMenu for sorting options --- .../com/yogeshpaliyal/deepr/ui/screens/home/FilterMenu.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/FilterMenu.kt b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/FilterMenu.kt index 997e69f..f4b8ee1 100644 --- a/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/FilterMenu.kt +++ b/app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/FilterMenu.kt @@ -21,7 +21,6 @@ import compose.icons.tablericons.CalendarEvent import compose.icons.tablericons.Eye import compose.icons.tablericons.EyeOff import compose.icons.tablericons.Filter -import compose.icons.tablericons.Link import compose.icons.tablericons.SortAscending import compose.icons.tablericons.SortDescending @@ -125,7 +124,7 @@ fun FilterMenu( }, leadingIcon = { Icon( - TablerIcons.Link, + TablerIcons.SortAscending, contentDescription = null, ) }, @@ -138,7 +137,7 @@ fun FilterMenu( }, leadingIcon = { Icon( - TablerIcons.Link, + TablerIcons.SortDescending, contentDescription = null, ) }, From e89dfc68b46ba94ea8170eda6dcbaf172431b639 Mon Sep 17 00:00:00 2001 From: Faded Date: Mon, 22 Sep 2025 08:22:10 +0500 Subject: [PATCH 8/9] fix: reorder and update tag management strings in Hindi localization --- app/src/main/res/values-hi/strings.xml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 5014add..e04398a 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -1,18 +1,6 @@ Deepr - - - टैग संपादित करें - टैग हटाएं - क्या आप वाकई इस टैग को हटाना चाहते हैं? - इस नाम के साथ एक टैग पहले से मौजूद है - टैग संपादित करने में विफल - टैग सफलतापूर्वक संपादित - टैग हटाने में विफल: %s - टैग सफलतापूर्वक हटाया गया - टैग संपादित करें - टैग हटाएं - + सेटिंग्स हमारे बारे में @@ -60,6 +48,18 @@ नाम के अनुसार अवरोही क्रम में लिंक के अनुसार आरोही क्रम में लिंक के अनुसार अवरोही क्रम में + + + टैग संपादित करें + टैग हटाएं + क्या आप वाकई इस टैग को हटाना चाहते हैं? + इस नाम के साथ एक टैग पहले से मौजूद है + टैग संपादित करने में विफल + टैग सफलतापूर्वक संपादित + टैग हटाने में विफल: %s + टैग सफलतापूर्वक हटाया गया + टैग संपादित करें + टैग हटाएं Deeplinks आयात करें From 0ccadbc60c5abb2710da37513d6fed0dbdc1c070 Mon Sep 17 00:00:00 2001 From: Faded Date: Mon, 22 Sep 2025 08:53:56 +0500 Subject: [PATCH 9/9] fix: reorganize and restore tag management strings in German localization --- app/src/main/res/values-de/strings.xml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index ee5fe5c..f47e172 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -1,17 +1,5 @@ Deepr - - - Tag Bearbeiten - Tag Löschen - Sind Sie sicher, dass Sie diesen Tag löschen möchten? - Ein Tag mit diesem Namen existiert bereits - Fehler beim Bearbeiten des Tags - Tag erfolgreich bearbeitet - Fehler beim Löschen des Tags: %s - Tag erfolgreich gelöscht - Tag Bearbeiten - Tag Löschen Einstellungen @@ -50,6 +38,18 @@ Verknüpfung bearbeiten QR-Code anzeigen Deeplink existiert bereits + + + Tag Bearbeiten + Tag Löschen + Sind Sie sicher, dass Sie diesen Tag löschen möchten? + Ein Tag mit diesem Namen existiert bereits + Fehler beim Bearbeiten des Tags + Tag erfolgreich bearbeitet + Fehler beim Löschen des Tags: %s + Tag erfolgreich gelöscht + Tag Bearbeiten + Tag Löschen Nach Datum aufsteigend sortieren