diff --git a/commons/build.gradle.kts b/commons/build.gradle.kts index af8cceeac..bf482725f 100644 --- a/commons/build.gradle.kts +++ b/commons/build.gradle.kts @@ -5,7 +5,6 @@ plugins { alias(libs.plugins.androidLibrary) alias(libs.plugins.jetbrainsComposeCompiler) alias(libs.plugins.composeMultiplatform) - alias(libs.plugins.mokoResources) } android { @@ -81,9 +80,8 @@ kotlin { // Immutable collections api(libs.kotlinx.collections.immutable) - // Moko Resources for KMP string resources - api(libs.moko.resources) - api(libs.moko.resources.compose) + // Compose Multiplatform Resources + implementation(compose.components.resources) } } @@ -141,7 +139,8 @@ kotlin { } } -multiplatformResources { - resourcesPackage.set("com.vitorpamplona.amethyst.commons") - resourcesClassName.set("SharedRes") +compose.resources { + publicResClass = true + packageOfResClass = "com.vitorpamplona.amethyst.commons.resources" + generateResClass = always } diff --git a/commons/src/commonMain/moko-resources/base/strings.xml b/commons/src/commonMain/composeResources/values/strings.xml similarity index 100% rename from commons/src/commonMain/moko-resources/base/strings.xml rename to commons/src/commonMain/composeResources/values/strings.xml diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/LoadingState.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/LoadingState.kt index 2ed9eb625..bab70c642 100644 --- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/LoadingState.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/LoadingState.kt @@ -34,8 +34,12 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import com.vitorpamplona.amethyst.commons.SharedRes -import dev.icerock.moko.resources.compose.stringResource +import com.vitorpamplona.amethyst.commons.resources.Res +import com.vitorpamplona.amethyst.commons.resources.action_refresh +import com.vitorpamplona.amethyst.commons.resources.action_try_again +import com.vitorpamplona.amethyst.commons.resources.error_loading_feed +import com.vitorpamplona.amethyst.commons.resources.feed_empty +import org.jetbrains.compose.resources.stringResource /** * A centered loading state with a progress indicator and message. @@ -71,7 +75,7 @@ fun EmptyState( onRefresh: (() -> Unit)? = null, refreshLabel: String? = null, ) { - val actualRefreshLabel = refreshLabel ?: stringResource(SharedRes.strings.action_refresh) + val actualRefreshLabel = refreshLabel ?: stringResource(Res.string.action_refresh) Column( modifier = modifier.fillMaxSize(), @@ -110,7 +114,7 @@ fun ErrorState( onRetry: (() -> Unit)? = null, retryLabel: String? = null, ) { - val actualRetryLabel = retryLabel ?: stringResource(SharedRes.strings.action_try_again) + val actualRetryLabel = retryLabel ?: stringResource(Res.string.action_try_again) Column( modifier = modifier.fillMaxSize(), @@ -140,7 +144,7 @@ fun FeedEmptyState( title: String? = null, onRefresh: (() -> Unit)? = null, ) { - val actualTitle = title ?: stringResource(SharedRes.strings.feed_empty) + val actualTitle = title ?: stringResource(Res.string.feed_empty) EmptyState( title = actualTitle, @@ -158,7 +162,7 @@ fun FeedErrorState( modifier: Modifier = Modifier, onRetry: (() -> Unit)? = null, ) { - val formattedMessage = stringResource(SharedRes.strings.error_loading_feed).format(errorMessage) + val formattedMessage = stringResource(Res.string.error_loading_feed).format(errorMessage) ErrorState( message = formattedMessage, diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/screens/PlaceholderScreens.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/screens/PlaceholderScreens.kt index 3a30ba107..82ef5f82e 100644 --- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/screens/PlaceholderScreens.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/screens/PlaceholderScreens.kt @@ -28,8 +28,14 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import com.vitorpamplona.amethyst.commons.SharedRes -import dev.icerock.moko.resources.compose.stringResource +import com.vitorpamplona.amethyst.commons.resources.Res +import com.vitorpamplona.amethyst.commons.resources.screen_messages_description +import com.vitorpamplona.amethyst.commons.resources.screen_messages_title +import com.vitorpamplona.amethyst.commons.resources.screen_notifications_description +import com.vitorpamplona.amethyst.commons.resources.screen_notifications_title +import com.vitorpamplona.amethyst.commons.resources.screen_search_description +import com.vitorpamplona.amethyst.commons.resources.screen_search_title +import org.jetbrains.compose.resources.stringResource /** * Generic placeholder screen with title and description. @@ -60,8 +66,8 @@ fun PlaceholderScreen( @Composable fun SearchPlaceholder(modifier: Modifier = Modifier) { PlaceholderScreen( - title = stringResource(SharedRes.strings.screen_search_title), - description = stringResource(SharedRes.strings.screen_search_description), + title = stringResource(Res.string.screen_search_title), + description = stringResource(Res.string.screen_search_description), modifier = modifier, ) } @@ -72,8 +78,8 @@ fun SearchPlaceholder(modifier: Modifier = Modifier) { @Composable fun MessagesPlaceholder(modifier: Modifier = Modifier) { PlaceholderScreen( - title = stringResource(SharedRes.strings.screen_messages_title), - description = stringResource(SharedRes.strings.screen_messages_description), + title = stringResource(Res.string.screen_messages_title), + description = stringResource(Res.string.screen_messages_description), modifier = modifier, ) } @@ -84,8 +90,8 @@ fun MessagesPlaceholder(modifier: Modifier = Modifier) { @Composable fun NotificationsPlaceholder(modifier: Modifier = Modifier) { PlaceholderScreen( - title = stringResource(SharedRes.strings.screen_notifications_title), - description = stringResource(SharedRes.strings.screen_notifications_description), + title = stringResource(Res.string.screen_notifications_title), + description = stringResource(Res.string.screen_notifications_description), modifier = modifier, ) } diff --git a/desktopApp/build.gradle.kts b/desktopApp/build.gradle.kts index b82eb646b..c9d5ee7c4 100644 --- a/desktopApp/build.gradle.kts +++ b/desktopApp/build.gradle.kts @@ -25,6 +25,7 @@ dependencies { implementation(compose.desktop.currentOs) implementation(compose.material3) implementation(compose.materialIconsExtended) + implementation(compose.components.resources) // Quartz Nostr library (will use JVM target) implementation(project(":quartz")) diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/LoginScreen.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/LoginScreen.kt index bf32e84b5..8aeafd2df 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/LoginScreen.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/LoginScreen.kt @@ -37,14 +37,16 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import com.vitorpamplona.amethyst.commons.SharedRes +import com.vitorpamplona.amethyst.commons.resources.Res +import com.vitorpamplona.amethyst.commons.resources.login_subtitle_desktop +import com.vitorpamplona.amethyst.commons.resources.login_title import com.vitorpamplona.amethyst.desktop.account.AccountManager import com.vitorpamplona.amethyst.desktop.account.AccountState import com.vitorpamplona.amethyst.desktop.ui.auth.LoginCard import com.vitorpamplona.amethyst.desktop.ui.auth.NewKeyWarningCard -import dev.icerock.moko.resources.compose.stringResource import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import org.jetbrains.compose.resources.stringResource @Composable fun LoginScreen( @@ -61,7 +63,7 @@ fun LoginScreen( verticalArrangement = Arrangement.Center, ) { Text( - stringResource(SharedRes.strings.login_title), + stringResource(Res.string.login_title), style = MaterialTheme.typography.headlineLarge, color = MaterialTheme.colorScheme.onBackground, ) @@ -69,7 +71,7 @@ fun LoginScreen( Spacer(Modifier.height(8.dp)) Text( - stringResource(SharedRes.strings.login_subtitle_desktop), + stringResource(Res.string.login_subtitle_desktop), style = MaterialTheme.typography.bodyLarge, color = MaterialTheme.colorScheme.onSurfaceVariant, ) diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/auth/KeyInputField.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/auth/KeyInputField.kt index b71a3077d..c5c44f333 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/auth/KeyInputField.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/auth/KeyInputField.kt @@ -42,8 +42,12 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.unit.dp -import com.vitorpamplona.amethyst.commons.SharedRes -import dev.icerock.moko.resources.compose.stringResource +import com.vitorpamplona.amethyst.commons.resources.Res +import com.vitorpamplona.amethyst.commons.resources.login_hide_key +import com.vitorpamplona.amethyst.commons.resources.login_key_label +import com.vitorpamplona.amethyst.commons.resources.login_key_placeholder +import com.vitorpamplona.amethyst.commons.resources.login_show_key +import org.jetbrains.compose.resources.stringResource /** * Text field for entering Nostr keys (nsec or npub) with visibility toggle. @@ -53,8 +57,8 @@ fun KeyInputField( value: String, onValueChange: (String) -> Unit, modifier: Modifier = Modifier, - label: String = stringResource(SharedRes.strings.login_key_label), - placeholder: String = stringResource(SharedRes.strings.login_key_placeholder), + label: String = stringResource(Res.string.login_key_label), + placeholder: String = stringResource(Res.string.login_key_placeholder), errorMessage: String? = null, ) { var showKey by remember { mutableStateOf(false) } @@ -76,7 +80,7 @@ fun KeyInputField( IconButton(onClick = { showKey = !showKey }) { Icon( if (showKey) Icons.Default.VisibilityOff else Icons.Default.Visibility, - contentDescription = if (showKey) stringResource(SharedRes.strings.login_hide_key) else stringResource(SharedRes.strings.login_show_key), + contentDescription = if (showKey) stringResource(Res.string.login_hide_key) else stringResource(Res.string.login_show_key), ) } }, diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/auth/LoginCard.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/auth/LoginCard.kt index 4271baaf7..50c3f13b5 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/auth/LoginCard.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/auth/LoginCard.kt @@ -44,8 +44,12 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import com.vitorpamplona.amethyst.commons.SharedRes -import dev.icerock.moko.resources.compose.stringResource +import com.vitorpamplona.amethyst.commons.resources.Res +import com.vitorpamplona.amethyst.commons.resources.login_button +import com.vitorpamplona.amethyst.commons.resources.login_card_subtitle +import com.vitorpamplona.amethyst.commons.resources.login_card_title +import com.vitorpamplona.amethyst.commons.resources.login_generate_button +import org.jetbrains.compose.resources.stringResource /** * Login card with Nostr key input field and action buttons. @@ -63,8 +67,8 @@ fun LoginCard( onGenerateNew: () -> Unit, modifier: Modifier = Modifier, cardWidth: Dp = 400.dp, - title: String = stringResource(SharedRes.strings.login_card_title), - subtitle: String = stringResource(SharedRes.strings.login_card_subtitle), + title: String = stringResource(Res.string.login_card_title), + subtitle: String = stringResource(Res.string.login_card_subtitle), ) { var keyInput by remember { mutableStateOf("") } var errorMessage by remember { mutableStateOf(null) } @@ -121,14 +125,14 @@ fun LoginCard( modifier = Modifier.weight(1f), enabled = keyInput.isNotBlank(), ) { - Text(stringResource(SharedRes.strings.login_button)) + Text(stringResource(Res.string.login_button)) } OutlinedButton( onClick = onGenerateNew, modifier = Modifier.weight(1f), ) { - Text(stringResource(SharedRes.strings.login_generate_button)) + Text(stringResource(Res.string.login_generate_button)) } } } diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/auth/NewKeyWarningCard.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/auth/NewKeyWarningCard.kt index b473580a4..6cf01a4c0 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/auth/NewKeyWarningCard.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/auth/NewKeyWarningCard.kt @@ -37,8 +37,13 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import com.vitorpamplona.amethyst.commons.SharedRes -import dev.icerock.moko.resources.compose.stringResource +import com.vitorpamplona.amethyst.commons.resources.Res +import com.vitorpamplona.amethyst.commons.resources.new_key_continue_button +import com.vitorpamplona.amethyst.commons.resources.new_key_public_label +import com.vitorpamplona.amethyst.commons.resources.new_key_secret_label +import com.vitorpamplona.amethyst.commons.resources.new_key_warning_message +import com.vitorpamplona.amethyst.commons.resources.new_key_warning_title +import org.jetbrains.compose.resources.stringResource /** * Warning card displayed after generating a new Nostr key pair. @@ -69,7 +74,7 @@ fun NewKeyWarningCard( modifier = Modifier.padding(24.dp), ) { Text( - stringResource(SharedRes.strings.new_key_warning_title), + stringResource(Res.string.new_key_warning_title), style = MaterialTheme.typography.titleMedium, color = Color.Red, ) @@ -77,7 +82,7 @@ fun NewKeyWarningCard( Spacer(Modifier.height(16.dp)) Text( - stringResource(SharedRes.strings.new_key_warning_message), + stringResource(Res.string.new_key_warning_message), style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurface, ) @@ -85,7 +90,7 @@ fun NewKeyWarningCard( Spacer(Modifier.height(16.dp)) Text( - stringResource(SharedRes.strings.new_key_public_label), + stringResource(Res.string.new_key_public_label), style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.onSurfaceVariant, ) @@ -95,7 +100,7 @@ fun NewKeyWarningCard( nsec?.let { secretKey -> Text( - stringResource(SharedRes.strings.new_key_secret_label), + stringResource(Res.string.new_key_secret_label), style = MaterialTheme.typography.labelMedium, color = Color.Red, ) @@ -108,7 +113,7 @@ fun NewKeyWarningCard( onClick = onContinue, modifier = Modifier.fillMaxWidth(), ) { - Text(stringResource(SharedRes.strings.new_key_continue_button)) + Text(stringResource(Res.string.new_key_continue_button)) } } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 38e7607b4..30fd4a4df 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -40,7 +40,6 @@ lightcompressor-enhanced = "1.6.0" markdown = "f92ef49c9d" media3 = "1.9.0" mockk = "1.14.7" -mokoResources = "0.25.2" kotlinx-coroutines-test = "1.10.2" navigationCompose = "2.9.6" okhttp = "5.3.2" @@ -137,8 +136,6 @@ markdown-ui = { group = "com.github.vitorpamplona.compose-richtext", name = "ric markdown-ui-material3 = { group = "com.github.vitorpamplona.compose-richtext", name = "richtext-ui-material3", version.ref = "markdown" } mockk = { group = "io.mockk", name = "mockk", version.ref = "mockk" } mockk-android = { group = "io.mockk", name = "mockk-android", version.ref = "mockk" } -moko-resources = { group = "dev.icerock.moko", name = "resources", version.ref = "mokoResources" } -moko-resources-compose = { group = "dev.icerock.moko", name = "resources-compose", version.ref = "mokoResources" } kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "kotlinx-coroutines-test"} okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" } okhttpCoroutines = { group = "com.squareup.okhttp3", name = "okhttp-coroutines", version.ref = "okhttp" } @@ -178,4 +175,3 @@ androidKotlinMultiplatformLibrary = { id = "com.android.kotlin.multiplatform.lib vanniktech-mavenPublish = { id = "com.vanniktech.maven.publish", version.ref = "mavenPublish" } stability-analyzer = { id = "com.github.skydoves.compose.stability.analyzer", version = "0.6.6" } composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "composeMultiplatform" } -mokoResources = { id = "dev.icerock.mobile.multiplatform-resources", version.ref = "mokoResources" }