-
Notifications
You must be signed in to change notification settings - Fork 55
feat: add Jetpack Compose support with real-time string updates #329
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is being reviewed by Cursor Bugbot
Details
Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.
To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.
crowdin/src/main/java/com/crowdin/platform/realtimeupdate/EchoWebSocketListener.kt
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR introduces comprehensive Jetpack Compose support to the Crowdin Android SDK, enabling real-time translation updates in Compose applications through a sophisticated compiler plugin architecture and runtime integration system.
Key Changes
- New compiler plugin module (
crowdin-compiler-plugin) that transparently transformsstringResource()calls tocrowdinString()at compile-time using K2-compatible IR transformation - New Gradle plugin module (
crowdin-gradle-plugin) that integrates the compiler plugin into Android builds with variant-based control - Compose runtime integration with thread-safe state management, WebSocket support for real-time updates, and lifecycle-aware watcher registration
Reviewed changes
Copilot reviewed 44 out of 44 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
website/sidebars.ts |
Added Jetpack Compose documentation to sidebar navigation |
website/docs/advanced-features/jetpack-compose.mdx |
Comprehensive documentation for Compose integration with usage examples |
website/docs/advanced-features/real-time-preview.mdx |
Added cross-reference to Compose documentation |
website/docs/code-samples/jetpack-compose/config.kt |
Configuration example for enabling Compose support |
website/docs/code-samples/jetpack-compose/usage.kt |
Usage example for manual Compose integration |
settings.gradle |
Added new compiler and Gradle plugin modules to build |
gradle/publishing.gradle.kts |
Shared publishing configuration for consistent Maven Central metadata |
gradle/libs.versions.toml |
New version catalog with centralized dependency versions |
gradle.properties |
Centralized version management and publishing metadata |
example/build.gradle |
Enabled Compose support in example app |
crowdin/build.gradle |
Added Compose dependencies and enabled Compose build features |
crowdin/src/main/java/com/crowdin/platform/Crowdin.kt |
Added Compose repository initialization and integration hooks |
crowdin/src/main/java/com/crowdin/platform/CrowdinConfig.kt |
Added configuration flag for Compose support |
crowdin/src/main/java/com/crowdin/platform/compose/CrowdinCompose.kt |
Composable functions for real-time string retrieval |
crowdin/src/main/java/com/crowdin/platform/compose/ComposeStringRepository.kt |
Thread-safe state management for Compose strings with WebSocket integration |
crowdin/src/main/java/com/crowdin/platform/realtimeupdate/EchoWebSocketListener.kt |
Extended WebSocket listener to support Compose watchers |
crowdin/src/main/java/com/crowdin/platform/realtimeupdate/RealTimeUpdateManager.kt |
Integrated Compose repository into real-time update system |
crowdin/src/main/java/com/crowdin/platform/data/model/TextMetaData.kt |
Added resourceId field for Compose integration |
crowdin/src/main/java/com/crowdin/platform/util/FeatureFlags.kt |
Added Compose feature flag |
crowdin/src/test/java/com/crowdin/platform/compose/ComposeStringRepositoryTest.kt |
Basic unit tests for Compose repository |
crowdin/src/test/java/com/crowdin/platform/RealTimeUpdateManagerTest.kt |
Updated tests to include Compose repository parameter |
crowdin/src/test/java/com/crowdin/platform/EchoWebSocketListenerTest.kt |
Updated tests to include Compose repository parameter |
crowdin/src/test/java/com/crowdin/platform/FeatureFlagTest.kt |
Added test for Compose feature flag |
crowdin/src/test/java/com/crowdin/platform/CrowdinConfigTest.kt |
Added test for Compose configuration |
crowdin-gradle-plugin/build.gradle.kts |
Build configuration for Gradle plugin with Maven publishing |
crowdin-gradle-plugin/src/main/kotlin/com/crowdin/platform/gradle/CrowdinGradlePlugin.kt |
Gradle plugin that applies compiler plugin with variant-based enabling |
crowdin-gradle-plugin/src/test/kotlin/com/crowdin/platform/gradle/CrowdinExtensionTest.kt |
Tests for Gradle plugin extension |
crowdin-compiler-plugin/build.gradle.kts |
Build configuration for compiler plugin with test framework |
crowdin-compiler-plugin/src/main/kotlin/com/crowdin/platform/compiler/CrowdinComponentRegistrar.kt |
Compiler plugin entry point and extension registration |
crowdin-compiler-plugin/src/main/kotlin/com/crowdin/platform/compiler/CrowdinCommandLineProcessor.kt |
Command-line processor for compiler plugin options |
crowdin-compiler-plugin/src/main/kotlin/com/crowdin/platform/compiler/CrowdinIrGenerationExtension.kt |
IR generation extension with plugin ordering enforcement |
crowdin-compiler-plugin/src/main/kotlin/com/crowdin/platform/compiler/CrowdinStringResourceTransformer.kt |
IR transformer that intercepts and transforms stringResource calls |
crowdin-compiler-plugin/testData/box/stringResourceTransform.kt |
Compiler plugin test for transformation verification |
crowdin-compiler-plugin/test-fixtures/* |
Test infrastructure for compiler plugin testing |
crowdin-compiler-plugin/resources/META-INF/services/* |
Service loader files for compiler plugin discovery |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
crowdin/src/main/java/com/crowdin/platform/compose/ComposeStringRepository.kt
Show resolved
Hide resolved
...ompiler-plugin/src/main/kotlin/com/crowdin/platform/compiler/CrowdinIrGenerationExtension.kt
Show resolved
Hide resolved
crowdin/src/main/java/com/crowdin/platform/compose/ComposeStringRepository.kt
Outdated
Show resolved
Hide resolved
crowdin-gradle-plugin/src/main/kotlin/com/crowdin/platform/gradle/CrowdinGradlePlugin.kt
Outdated
Show resolved
Hide resolved
crowdin/src/main/java/com/crowdin/platform/realtimeupdate/EchoWebSocketListener.kt
Outdated
Show resolved
Hide resolved
crowdin/src/test/java/com/crowdin/platform/compose/ComposeStringRepositoryTest.kt
Show resolved
Hide resolved
b7c33cd to
50c7142
Compare
crowdin/src/main/java/com/crowdin/platform/compose/ComposeStringRepository.kt
Outdated
Show resolved
Hide resolved
|
@leo-benz thanks a lot for such a great contribution! 🚀 Requesting a review from @MykhailoNester. In the meantime, could you please take a look at the AI comments? If something looks irrelevant, just resolve it. |
50c7142 to
ff7b804
Compare
META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
Outdated
Show resolved
Hide resolved
crowdin/src/main/java/com/crowdin/platform/compose/ComposeStringRepository.kt
Show resolved
Hide resolved
ff7b804 to
1cb42d6
Compare
crowdin/src/main/java/com/crowdin/platform/compose/CrowdinCompose.kt
Outdated
Show resolved
Hide resolved
1cb42d6 to
ff67778
Compare
|
@andrii-bodnar First time for me working with a GitHub repo with such extensive AI checks, overall a nice workflow and good comments 👍🏻 I have addressed and resolved all the relevant ones. |
...ompiler-plugin/src/main/kotlin/com/crowdin/platform/compiler/CrowdinIrGenerationExtension.kt
Show resolved
Hide resolved
| @RequiresApi(Build.VERSION_CODES.N) | ||
| @Composable | ||
| fun crowdinString( | ||
| resourceId: Int, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor API suggestion: Consider matching the original stringResource() signature more closely:
@StringRes id: Int
// Original code
Text(stringResource(id = R.string.welcome))
// After find/replace "stringResource" → "crowdinString"
Text(crowdinString(id = R.string.welcome))
| return | ||
| } | ||
|
|
||
| if (eventData.pluralForm == null || eventData.pluralForm == PLURAL_NONE) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @leo-benz ! 👋
Nice work on this! The Compose integration looks solid and the compiler plugin approach is clean.
Quick question - I noticed the WebSocket handler for Compose only handles non-plural strings EchoWebSocketListener.kt:349-354, while TextViews handle both the else block at line 224 handles plurals. Is plural support for Compose something planned for a follow-up, or should we document this limitation?
Otherwise looks good to merge! 🚀
Summary
This PR adds comprehensive Jetpack Compose support to the Crowdin Android SDK, enabling real-time translation updates in Compose-based applications through a Kotlin compiler plugin.
Key Features
1. Kotlin Compiler Plugin (
crowdin-compiler-plugin/)stringResource()calls at compile-timecrowdinString()for real-time updates2. Gradle Plugin (
crowdin-gradle-plugin/)3. Compose Runtime Integration (
crowdin/src/main/java/com/crowdin/platform/compose/)ComposeStringRepository: Thread-safe state management for Compose stringscrowdinString(): Composable functions with automatic recomposition on translation updatesDisposableEffect4. Enhanced WebSocket Support
EchoWebSocketListenerto support Compose watchers5. Build Configuration Improvements
gradle.propertiesgradle/publishing.gradle.kts) for consistent POM metadatabuildConfigconfigurationDocumentation
website/docs/advanced-features/jetpack-compose.mdxBreaking Changes
None - this is a purely additive feature that's opt-in via configuration.
Usage Guide
Option 1: With Compiler Plugin (Recommended)
The compiler plugin automatically transforms all
stringResource()calls to support real-time updates. No code changes required!plugins { id("com.crowdin.platform.gradle") // Must be before Compose plugin id("org.jetbrains.kotlin.plugin.compose") }Option 2: Without Compiler Plugin
If you prefer not to use the compiler plugin, you can manually use
crowdinString():🤖 Generated with Claude Code
Note
Introduces a K2 compiler plugin and Gradle plugin to auto-transform
stringResource()tocrowdinString(), plus SDK-side Compose runtime/state + WebSocket integration, centralized build/publishing config, and documentation.com.crowdin.platform.composeruntime:ComposeStringRepositoryandcrowdinString()composables with stateful updates and lifecycle-aware watchers.Crowdin,CrowdinConfig, andFeatureFlagsto enable/guard real-time Compose (API 24+), expose repository, and trigger updates on config/data changes.EchoWebSocketListenerandRealTimeUpdateManagerto subscribe/update Compose watchers.crowdin-compiler-plugin/):androidx.compose.ui.res.stringResource()calls withcom.crowdin.platform.compose.crowdinString().enabledoption; tests and generators included.crowdin-gradle-plugin/):crowdinextension.gradle.properties,libs.versions.toml).gradle/publishing.gradle.kts) and sources JARs; include new modules insettings.gradle.crowdin/and update example app config.Written by Cursor Bugbot for commit ff67778. This will update automatically on new commits. Configure here.