Skip to content

Commit d0e6203

Browse files
authored
feat: add brownie android (#257)
* chore: scaffold android * feat: add cpp bindings * feat: add compiler flags and target linkages * feat: use brownie on android * refactor: use new module registration API * refactor: remove redundancy * refactor: remove unused methods * feat: improve Android DX * refactor: split impl between files * docs: add brownie android * docs: update pre-req * fix: add kotlin to platforms * fix: separate imports by flavor * fix: add brownie config block * chore: run changeset * feat: exclude libc++ at brownie level * chore: run changeset * fix: add kotlin to cli choices * refactor: remove unused style * feat: rely on StoreManager instead of custom tracker * fix: add guard * fix: notify state update only once * chore: add consumer-rules to avoid required function name strip * docs: update * feat: changes after rebase * fix: brownfield store * fix: expo apps * fix: pin xcode 26.3
1 parent 45cf023 commit d0e6203

File tree

43 files changed

+1437
-170
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1437
-170
lines changed

.changeset/red-llamas-love.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
'@callstack/brownie': minor
3+
'@callstack/brownfield-cli': minor
4+
'brownfield': minor
5+
'@callstack/react-native-brownfield': minor
6+
---
7+
8+
add brownie android

.github/actions/prepare-ios/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ runs:
1313
- name: Use appropriate Xcode version
1414
uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0
1515
with:
16-
xcode-version: '26'
16+
xcode-version: '26.3'
1717

1818
- name: Setup Ruby
1919
uses: ruby/setup-ruby@5dd816ae0186f20dfa905997a64104db9a8221c7 # v1.280.0

apps/AndroidApp/app/build.gradle.kts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,18 +52,19 @@ android {
5252
}
5353
}
5454
compileOptions {
55-
sourceCompatibility = JavaVersion.VERSION_11
56-
targetCompatibility = JavaVersion.VERSION_11
55+
sourceCompatibility = JavaVersion.VERSION_17
56+
targetCompatibility = JavaVersion.VERSION_17
5757
}
5858
kotlinOptions {
59-
jvmTarget = "11"
59+
jvmTarget = "17"
6060
}
6161
buildFeatures {
6262
compose = true
6363
}
6464
}
6565

6666
dependencies {
67+
implementation("com.google.code.gson:gson:2.13.1")
6768
implementation(libs.androidx.core.ktx)
6869
implementation(libs.androidx.lifecycle.runtime.ktx)
6970
implementation(libs.androidx.activity.compose)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.callstack.brownfield.android.example
2+
3+
typealias BrownfieldStore = com.callstack.rnbrownfield.demo.expoapp54.BrownfieldStore
4+
typealias User = com.callstack.rnbrownfield.demo.expoapp54.User
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.callstack.brownfield.android.example
22

33
object ReactNativeConstants {
4-
const val MAIN_MODULE_NAME = "main"
4+
const val MAIN_MODULE_NAME = "RNApp"
55
const val APP_NAME = "Android (Expo 54)"
66
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.callstack.brownfield.android.example
2+
3+
typealias BrownfieldStore = com.callstack.rnbrownfield.demo.expoapp55.BrownfieldStore
4+
typealias User = com.callstack.rnbrownfield.demo.expoapp55.User
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.callstack.brownfield.android.example
22

33
object ReactNativeConstants {
4-
const val MAIN_MODULE_NAME = "main"
4+
const val MAIN_MODULE_NAME = "RNApp"
55
const val APP_NAME = "Android (Expo 55)"
66
}

apps/AndroidApp/app/src/main/java/com/callstack/brownfield/android/example/MainActivity.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import androidx.fragment.compose.AndroidFragment
2727
import com.callstack.brownfield.android.example.components.GreetingCard
2828
import com.callstack.brownfield.android.example.components.PostMessageCard
2929
import com.callstack.brownfield.android.example.ui.theme.AndroidBrownfieldAppTheme
30+
import com.callstack.brownie.registerStoreIfNeeded
3031
import com.callstack.nativebrownfieldnavigation.BrownfieldNavigationDelegate
3132
import com.callstack.nativebrownfieldnavigation.BrownfieldNavigationManager
3233
import com.callstack.reactnativebrownfield.ReactNativeFragment
@@ -52,6 +53,15 @@ class MainActivity : AppCompatActivity(), BrownfieldNavigationDelegate {
5253
Toast.LENGTH_LONG
5354
).show()
5455
}
56+
57+
registerStoreIfNeeded(
58+
storeName = BrownfieldStore.STORE_NAME
59+
) {
60+
BrownfieldStore(
61+
counter = 0.0,
62+
user = User(name = "Username")
63+
)
64+
}
5565
}
5666

5767
setContent {

apps/AndroidApp/app/src/main/java/com/callstack/brownfield/android/example/components/GreetingCard.kt

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,42 @@ import androidx.compose.material3.Button
88
import androidx.compose.material3.MaterialTheme
99
import androidx.compose.material3.Text
1010
import androidx.compose.runtime.Composable
11+
import androidx.compose.runtime.DisposableEffect
1112
import androidx.compose.runtime.getValue
1213
import androidx.compose.runtime.mutableIntStateOf
13-
import androidx.compose.runtime.saveable.rememberSaveable
14+
import androidx.compose.runtime.remember
1415
import androidx.compose.runtime.setValue
1516
import androidx.compose.ui.Alignment
1617
import androidx.compose.ui.Modifier
1718
import androidx.compose.ui.text.style.TextAlign
1819
import androidx.compose.ui.unit.dp
20+
import com.callstack.brownfield.android.example.BrownfieldStore
21+
import com.callstack.brownie.Store
22+
import com.callstack.brownie.StoreManager
23+
import com.callstack.brownie.store
24+
import com.callstack.brownie.subscribe
25+
26+
private fun brownieStore(): Store<BrownfieldStore>? {
27+
return StoreManager.shared.store(BrownfieldStore.STORE_NAME)
28+
}
1929

2030
@Composable
2131
fun GreetingCard(
2232
name: String,
2333
) {
24-
var counter by rememberSaveable { mutableIntStateOf(0) }
34+
var counter by remember { mutableIntStateOf(0) }
35+
36+
DisposableEffect(Unit) {
37+
val store = brownieStore()
38+
val unsubscribe = store?.subscribe(
39+
selector = { state -> state.counter.toInt() },
40+
onChange = { updatedCounter -> counter = updatedCounter }
41+
) ?: {}
42+
43+
onDispose {
44+
unsubscribe()
45+
}
46+
}
2547

2648
MaterialCard {
2749
Column(
@@ -43,7 +65,11 @@ fun GreetingCard(
4365
style = MaterialTheme.typography.bodyMedium
4466
)
4567

46-
Button(onClick = { counter++ }) {
68+
Button(onClick = {
69+
brownieStore()?.set { state ->
70+
state.copy(counter = state.counter + 1)
71+
}
72+
}) {
4773
Text("Increment counter")
4874
}
4975
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.callstack.brownfield.android.example
2+
3+
typealias BrownfieldStore = com.rnapp.brownfieldlib.BrownfieldStore
4+
typealias User = com.rnapp.brownfieldlib.User

0 commit comments

Comments
 (0)