feat: move hardcoded UI strings to strings.xml
Replaces hardcoded string literals in composables with string resource references for proper i18n support. Adds 20 new strings to strings.xml. Files updated: - NewUserMetadataScreen: "Social proof" section title - NoteCompose: "Approve" community post button - Badge: " and N others" badge awardees text - Chess: "Decline"/"Accept" challenge buttons - InteractiveStory: "Restart" story button - Poll: "Submit" poll button - ChessGameScreen: "Back", "Relay Settings", "Loading game...", "Game Not Found", "This game may have ended...", "Game ID: ...", "Go Back" - ChessLobbyScreen: "Back", "Relay Settings", "New Game", "Dismiss", "Connected" - chess/NewChessGameButton: "New Chess Game" content description - home/NewChessGameButton: "New Chess Game" content description - UserSettingsScreen: "Remove <language>" content description https://claude.ai/code/session_0151CDmy5k2pEWnxhRxet41h
This commit is contained in:
+1
-1
@@ -291,7 +291,7 @@ fun NewUserMetadataScreen(
|
||||
|
||||
// -- Social Proofs --
|
||||
ExpandableSection(
|
||||
title = "Social proof",
|
||||
title = stringRes(R.string.social_proof),
|
||||
expanded = socialExpanded,
|
||||
) {
|
||||
OutlinedTextField(
|
||||
|
||||
@@ -670,7 +670,7 @@ fun RenderApproveButton(
|
||||
accountViewModel.approveCommunityPost(post, community)
|
||||
},
|
||||
) {
|
||||
Text("Approve")
|
||||
Text(stringRes(R.string.approve))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ fun RenderBadgeAward(
|
||||
}
|
||||
|
||||
if (awardees.size > 100) {
|
||||
Text(" and ${awardees.size - 100} others", maxLines = 1)
|
||||
Text(stringRes(R.string.badge_and_n_others, awardees.size - 100), maxLines = 1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChessChallenge
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChessGameViewer
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
@@ -48,6 +49,7 @@ import com.vitorpamplona.amethyst.ui.components.SensitivityWarning
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chess.ChessViewModelFactory
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chess.ChessViewModelNew
|
||||
import com.vitorpamplona.quartz.nip64Chess.ChessGameEvent
|
||||
@@ -178,7 +180,7 @@ fun RenderLiveChessChallenge(
|
||||
horizontalArrangement = Arrangement.End,
|
||||
) {
|
||||
OutlinedButton(onClick = { /* TODO: Decline */ }) {
|
||||
Text("Decline")
|
||||
Text(stringRes(R.string.chess_decline))
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
@@ -207,7 +209,7 @@ fun RenderLiveChessChallenge(
|
||||
nav.nav(Route.ChessGame(gameId))
|
||||
},
|
||||
) {
|
||||
Text("Accept")
|
||||
Text(stringRes(R.string.chess_accept))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,9 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNo
|
||||
import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryBaseEvent
|
||||
import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryReadingStateEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
@@ -183,7 +185,7 @@ fun RenderInteractiveStory(
|
||||
OutlinedButton(
|
||||
onClick = onRestart,
|
||||
) {
|
||||
Text("Restart")
|
||||
Text(stringRes(R.string.restart))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,8 +77,10 @@ import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor
|
||||
import com.vitorpamplona.amethyst.ui.note.ClickableUserPicture
|
||||
import com.vitorpamplona.amethyst.ui.note.elements.DisplayUncitedHashtags
|
||||
import com.vitorpamplona.amethyst.ui.note.showCount
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.BigPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size25dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.SmallishBorder
|
||||
@@ -392,7 +394,7 @@ private fun ColumnScope.RenderMultiChoiceOptions(
|
||||
modifier = Modifier.align(Alignment.End),
|
||||
enabled = multichoice.isNotEmpty(),
|
||||
) {
|
||||
Text("Submit")
|
||||
Text(stringRes(R.string.poll_submit))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-8
@@ -68,8 +68,10 @@ import com.vitorpamplona.amethyst.commons.chess.ChessBroadcastBanner
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChessBroadcastStatus
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChessSyncBanner
|
||||
import com.vitorpamplona.amethyst.commons.chess.LiveChessGameScreen
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.Height4dpModifier
|
||||
import com.vitorpamplona.quartz.nip64Chess.ChessGameNameGenerator
|
||||
|
||||
@@ -186,7 +188,7 @@ fun ChessGameScreen(
|
||||
IconButton(onClick = { nav.popBack() }) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
|
||||
contentDescription = "Back",
|
||||
contentDescription = stringRes(R.string.back),
|
||||
)
|
||||
}
|
||||
},
|
||||
@@ -194,7 +196,7 @@ fun ChessGameScreen(
|
||||
IconButton(onClick = { showRelaySettings = true }) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Settings,
|
||||
contentDescription = "Relay Settings",
|
||||
contentDescription = stringRes(R.string.relay_settings),
|
||||
)
|
||||
}
|
||||
},
|
||||
@@ -239,7 +241,7 @@ fun ChessGameScreen(
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
CircularProgressIndicator()
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Text("Loading game...")
|
||||
Text(stringRes(R.string.chess_loading_game))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -256,7 +258,7 @@ fun ChessGameScreen(
|
||||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Text(
|
||||
text = "Game Not Found",
|
||||
text = stringRes(R.string.chess_game_not_found),
|
||||
style = MaterialTheme.typography.headlineMedium,
|
||||
fontWeight = FontWeight.Bold,
|
||||
)
|
||||
@@ -265,7 +267,7 @@ fun ChessGameScreen(
|
||||
|
||||
// Show specific error if available
|
||||
Text(
|
||||
text = error ?: "This game may have ended or is waiting for opponent.",
|
||||
text = error ?: stringRes(R.string.chess_game_waiting),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = if (error != null) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -273,7 +275,7 @@ fun ChessGameScreen(
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
Text(
|
||||
text = "Game ID: ${gameId.take(16)}...",
|
||||
text = stringRes(R.string.chess_game_id, gameId.take(16)),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -283,10 +285,10 @@ fun ChessGameScreen(
|
||||
Button(onClick = { nav.popBack() }) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
|
||||
contentDescription = "Back",
|
||||
contentDescription = stringRes(R.string.back),
|
||||
modifier = Modifier.padding(end = 8.dp),
|
||||
)
|
||||
Text("Go Back")
|
||||
Text(stringRes(R.string.go_back))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-5
@@ -82,6 +82,7 @@ import com.vitorpamplona.amethyst.commons.chess.PublicGame
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.quartz.nip64Chess.LiveChessGameState
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -168,7 +169,7 @@ fun ChessLobbyScreen(
|
||||
IconButton(onClick = { nav.popBack() }) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
|
||||
contentDescription = "Back",
|
||||
contentDescription = stringRes(R.string.back),
|
||||
)
|
||||
}
|
||||
},
|
||||
@@ -176,7 +177,7 @@ fun ChessLobbyScreen(
|
||||
IconButton(onClick = { showRelaySettings = true }) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Settings,
|
||||
contentDescription = "Relay Settings",
|
||||
contentDescription = stringRes(R.string.relay_settings),
|
||||
)
|
||||
}
|
||||
},
|
||||
@@ -186,7 +187,7 @@ fun ChessLobbyScreen(
|
||||
FloatingActionButton(
|
||||
onClick = { showNewGameDialog = true },
|
||||
) {
|
||||
Icon(Icons.Default.Add, contentDescription = "New Game")
|
||||
Icon(Icons.Default.Add, contentDescription = stringRes(R.string.chess_new_game))
|
||||
}
|
||||
},
|
||||
) { paddingValues ->
|
||||
@@ -238,7 +239,7 @@ fun ChessLobbyScreen(
|
||||
) {
|
||||
Text(errorMsg, color = MaterialTheme.colorScheme.onErrorContainer)
|
||||
OutlinedButton(onClick = { chessViewModel.clearError() }) {
|
||||
Text("Dismiss")
|
||||
Text(stringRes(R.string.dismiss))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -730,7 +731,7 @@ private fun RelayRow(
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.CheckCircle,
|
||||
contentDescription = "Connected",
|
||||
contentDescription = stringRes(R.string.connected),
|
||||
tint =
|
||||
if (isPreferred) {
|
||||
MaterialTheme.colorScheme.tertiary
|
||||
|
||||
+3
-1
@@ -28,6 +28,8 @@ import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size26Modifier
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size55Modifier
|
||||
|
||||
@@ -45,7 +47,7 @@ fun NewChessGameButton(onClick: () -> Unit) {
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Add,
|
||||
contentDescription = "New Chess Game",
|
||||
contentDescription = stringRes(R.string.new_chess_game),
|
||||
modifier = Size26Modifier,
|
||||
tint = Color.White,
|
||||
)
|
||||
|
||||
+3
-1
@@ -25,6 +25,8 @@ import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material3.FloatingActionButton
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.runtime.Composable
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
@@ -57,7 +59,7 @@ fun NewChessGameButton(
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Add,
|
||||
contentDescription = "New Chess Game",
|
||||
contentDescription = stringRes(R.string.new_chess_game),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -131,7 +131,7 @@ fun DontTranslateFromSetting(accountViewModel: AccountViewModel) {
|
||||
trailingIcon = {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Close,
|
||||
contentDescription = "Remove $languageCode",
|
||||
contentDescription = stringRes(R.string.remove_language, languageCode),
|
||||
tint = Color.Red,
|
||||
modifier = Modifier.size(16.dp),
|
||||
)
|
||||
|
||||
@@ -1525,4 +1525,24 @@
|
||||
<string name="confirm">Confirm</string>
|
||||
<string name="next">Next</string>
|
||||
<string name="add_poll_option_button">Add poll option button</string>
|
||||
|
||||
<string name="back">Back</string>
|
||||
<string name="go_back">Go Back</string>
|
||||
<string name="dismiss">Dismiss</string>
|
||||
<string name="approve">Approve</string>
|
||||
<string name="connected">Connected</string>
|
||||
<string name="relay_settings">Relay Settings</string>
|
||||
<string name="social_proof">Social proof</string>
|
||||
<string name="poll_submit">Submit</string>
|
||||
<string name="restart">Restart</string>
|
||||
<string name="chess_accept">Accept</string>
|
||||
<string name="chess_decline">Decline</string>
|
||||
<string name="chess_new_game">New Game</string>
|
||||
<string name="new_chess_game">New Chess Game</string>
|
||||
<string name="chess_loading_game">Loading game\u2026</string>
|
||||
<string name="chess_game_not_found">Game Not Found</string>
|
||||
<string name="chess_game_waiting">This game may have ended or is waiting for opponent.</string>
|
||||
<string name="chess_game_id">Game ID: %1$s\u2026</string>
|
||||
<string name="badge_and_n_others"> and %1$d others</string>
|
||||
<string name="remove_language">Remove %1$s</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user