diff --git a/.yarn/patches/expo-updates-npm-29.0.16-1c5c89eb83.patch b/.yarn/patches/expo-updates-npm-29.0.16-1c5c89eb83.patch new file mode 100644 index 00000000..ce26846a --- /dev/null +++ b/.yarn/patches/expo-updates-npm-29.0.16-1c5c89eb83.patch @@ -0,0 +1,222 @@ +diff --git a/android/src/main/java/expo/modules/updates/UpdatesController.kt b/android/src/main/java/expo/modules/updates/UpdatesController.kt +index 6ff694ccecafac0da2ffa2538500341e07e858d8..a670c0b833f33cf00981bc95daf44afa879cc69d 100644 +--- a/android/src/main/java/expo/modules/updates/UpdatesController.kt ++++ b/android/src/main/java/expo/modules/updates/UpdatesController.kt +@@ -2,6 +2,7 @@ package expo.modules.updates + + import android.content.Context + import com.facebook.react.ReactApplication ++import com.facebook.react.ReactHost + import expo.modules.updates.events.IUpdatesEventManagerObserver + import expo.modules.updates.loader.LoaderTask + import expo.modules.updates.logging.UpdatesErrorCode +@@ -25,6 +26,19 @@ object UpdatesController { + @Volatile + private var overrideConfiguration: UpdatesConfiguration? = null + ++ @Volatile ++ private var reactHost: ReactHost? = null ++ ++ @JvmStatic ++ fun setReactHost(reactHost: ReactHost) { ++ this.reactHost = reactHost ++ } ++ ++ @JvmStatic ++ fun getReactHost(): ReactHost? { ++ return reactHost ++ } ++ + @JvmStatic + val instance: IUpdatesController + get() { +diff --git a/android/src/main/java/expo/modules/updates/procedures/RecreateReactContextProcedure.kt b/android/src/main/java/expo/modules/updates/procedures/RecreateReactContextProcedure.kt +index 3bf9f207ae7d3c46151103d8f809821a9df20d56..1ccb4877c2fcefd2c63d43dcc59664c83932805f 100644 +--- a/android/src/main/java/expo/modules/updates/procedures/RecreateReactContextProcedure.kt ++++ b/android/src/main/java/expo/modules/updates/procedures/RecreateReactContextProcedure.kt +@@ -2,7 +2,6 @@ package expo.modules.updates.procedures + + import android.app.Activity + import android.content.Context +-import com.facebook.react.ReactApplication + import expo.modules.updates.launcher.Launcher + import expo.modules.updates.statemachine.UpdatesStateEvent + import kotlinx.coroutines.CoroutineScope +@@ -20,16 +19,11 @@ class RecreateReactContextProcedure( + override val loggerTimerLabel = "timer-recreate-react-context" + + override suspend fun run(procedureContext: ProcedureContext) { +- val reactApplication = context.applicationContext as? ReactApplication ?: run inner@{ +- callback.onFailure(Exception("Could not reload application. Ensure you have passed the correct instance of ReactApplication into UpdatesController.initialize().")) +- return +- } +- + procedureContext.processStateEvent(UpdatesStateEvent.Restart()) + callback.onSuccess() + procedureScope.launch { + withContext(Dispatchers.Main) { +- reactApplication.restart(weakActivity?.get(), "Restart from RecreateReactContextProcedure") ++ RestartReactAppExtensions.restart(weakActivity?.get(), "Restart from RecreateReactContextProcedure") + } + } + procedureContext.resetStateAfterRestart() +diff --git a/android/src/main/java/expo/modules/updates/procedures/RelaunchProcedure.kt b/android/src/main/java/expo/modules/updates/procedures/RelaunchProcedure.kt +index 64cc2870d28557c07217e1f78ad86e0fabe70bee..f2cf6a958d4da3f0a29040a6e101ce819c0696b7 100644 +--- a/android/src/main/java/expo/modules/updates/procedures/RelaunchProcedure.kt ++++ b/android/src/main/java/expo/modules/updates/procedures/RelaunchProcedure.kt +@@ -43,11 +43,6 @@ class RelaunchProcedure( + override val loggerTimerLabel = "timer-relaunch" + + override suspend fun run(procedureContext: ProcedureContext) { +- val reactApplication = context as? ReactApplication ?: run inner@{ +- callback.onFailure(Exception("Could not reload application. Ensure you have passed the correct instance of ReactApplication into UpdatesController.initialize().")) +- return +- } +- + procedureContext.processStateEvent(UpdatesStateEvent.Restart()) + + val oldLaunchAssetFile = getCurrentLauncher().launchAssetFile +@@ -74,7 +69,7 @@ class RelaunchProcedure( + val newLaunchAssetFile = getCurrentLauncher().launchAssetFile + if (newLaunchAssetFile != null && newLaunchAssetFile != oldLaunchAssetFile) { + try { +- replaceLaunchAssetFileIfNeeded(reactApplication, newLaunchAssetFile) ++ replaceLaunchAssetFileIfNeeded(newLaunchAssetFile) + } catch (e: Exception) { + logger.error("Could not reset launchAssetFile for the ReactApplication", e, UpdatesErrorCode.Unknown) + } +@@ -84,7 +79,7 @@ class RelaunchProcedure( + procedureScope.launch { + withContext(Dispatchers.Main) { + reloadScreenManager?.show(weakActivity?.get()) +- reactApplication.restart(weakActivity?.get(), "Restart from RelaunchProcedure") ++ RestartReactAppExtensions.restart(weakActivity?.get(), "Restart from RelaunchProcedure") + } + } + +@@ -127,13 +122,16 @@ class RelaunchProcedure( + * [com.facebook.react.ReactInstanceManager]. + */ + private fun replaceLaunchAssetFileIfNeeded( +- reactApplication: ReactApplication, + launchAssetFile: String + ) { + if (ReactNativeFeatureFlags.enableBridgelessArchitecture) { + return + } + ++ val reactApplication = context as? ReactApplication ?: run inner@{ ++ callback.onFailure(Exception("Could not reload application. Ensure you have passed the correct instance of ReactApplication into UpdatesController.initialize().")) ++ return ++ } + val instanceManager = reactApplication.reactNativeHost.reactInstanceManager + val jsBundleLoaderField = instanceManager.javaClass.getDeclaredField("mBundleLoader") + jsBundleLoaderField.isAccessible = true +diff --git a/android/src/main/java/expo/modules/updates/procedures/RestartReactAppExtensions.kt b/android/src/main/java/expo/modules/updates/procedures/RestartReactAppExtensions.kt +index 25c6e804d31f9ee915acdf5f363af07e7b7bf424..3a90db88ac3e70fae3c6d909c955210093f306f9 100644 +--- a/android/src/main/java/expo/modules/updates/procedures/RestartReactAppExtensions.kt ++++ b/android/src/main/java/expo/modules/updates/procedures/RestartReactAppExtensions.kt +@@ -2,25 +2,42 @@ package expo.modules.updates.procedures + + import android.app.Activity + import com.facebook.react.ReactApplication ++import com.facebook.react.ReactHost ++import com.facebook.react.ReactNativeHost + import com.facebook.react.common.LifecycleState + import expo.modules.rncompatibility.ReactNativeFeatureFlags ++import expo.modules.updates.UpdatesController + +-/** +- * An extension for [ReactApplication] to restart the app +- * +- * @param activity For bridgeless mode if the ReactHost is destroyed, we need an Activity to resume it. +- * @param reason The restart reason. Only used on bridgeless mode. +- */ +-internal fun ReactApplication.restart(activity: Activity?, reason: String) { +- if (ReactNativeFeatureFlags.enableBridgelessArchitecture) { +- val reactHost = this.reactHost +- check(reactHost != null) +- if (reactHost.lifecycleState != LifecycleState.RESUMED && activity != null) { +- reactHost.onHostResume(activity) ++private fun getReactHostReflectively(app: ReactApplication): ReactHost? { ++ return runCatching { ++ app.javaClass.getMethod("getReactHost").invoke(app) as? ReactHost ++ }.getOrNull() ++} ++ ++private fun getReactNativeHostReflectively(app: ReactApplication): ReactNativeHost? { ++ return runCatching { ++ app.javaClass.getMethod("getReactNativeHost").invoke(app) as? ReactNativeHost ++ }.getOrNull() ++} ++ ++object RestartReactAppExtensions { ++ /** ++ * A function to restart the app ++ * ++ * @param activity For bridgeless mode if the ReactHost is destroyed, we need an Activity to resume it. ++ * @param reason The restart reason. Only used on bridgeless mode. ++ */ ++ fun restart(activity: Activity?, reason: String) { ++ if (ReactNativeFeatureFlags.enableBridgelessArchitecture) { ++ val reactHost = UpdatesController.getReactHost() ?: getReactHostReflectively(activity?.application as ReactApplication) ++ check(reactHost != null) ++ if (reactHost.lifecycleState != LifecycleState.RESUMED && activity != null) { ++ reactHost.onHostResume(activity) ++ } ++ reactHost.reload(reason) ++ return + } +- reactHost.reload(reason) +- return +- } + +- reactNativeHost.reactInstanceManager.recreateReactContextInBackground() ++ getReactNativeHostReflectively(activity?.application as ReactApplication)?.reactInstanceManager?.recreateReactContextInBackground() ++ } + } +diff --git a/ios/EXUpdates/UpdatesConfig.swift b/ios/EXUpdates/UpdatesConfig.swift +index 09a1e145a9f5a938e10dd3c59eedfd213ad54346..787c1a8f7ae6a010fff4200ffebe31742e9a25eb 100644 +--- a/ios/EXUpdates/UpdatesConfig.swift ++++ b/ios/EXUpdates/UpdatesConfig.swift +@@ -141,7 +141,8 @@ public final class UpdatesConfig: NSObject { + } + + private static func configDictionaryWithExpoPlist(mergingOtherDictionary: [String: Any]?) throws -> [String: Any] { +- guard let configPlistPath = Bundle.main.path(forResource: PlistName, ofType: "plist") else { ++ let bundle = Bundle(for: UpdatesConfig.self) ++ guard let configPlistPath = bundle.path(forResource: PlistName, ofType: "plist") else { + throw UpdatesConfigError.ExpoUpdatesConfigPlistError + } + +diff --git a/ios/EXUpdates/UpdatesUtils.swift b/ios/EXUpdates/UpdatesUtils.swift +index a1e2c9af4ebaf9e50db2acaabfa876fc46d22454..0b96a7062dbcd021339a9daeb4397b3c7715b96d 100644 +--- a/ios/EXUpdates/UpdatesUtils.swift ++++ b/ios/EXUpdates/UpdatesUtils.swift +@@ -108,18 +108,22 @@ public final class UpdatesUtils: NSObject { + return assetFilesMap + } + ++ private static func getBundle() -> Bundle { ++ return Bundle(for: UpdatesUtils.self) ++ } ++ + internal static func url(forBundledAsset asset: UpdateAsset) -> URL? { + guard let mainBundleDir = asset.mainBundleDir else { +- return Bundle.main.url(forResource: asset.mainBundleFilename, withExtension: asset.type) ++ return getBundle().url(forResource: asset.mainBundleFilename, withExtension: asset.type) + } +- return Bundle.main.url(forResource: asset.mainBundleFilename, withExtension: asset.type, subdirectory: mainBundleDir) ++ return getBundle().url(forResource: asset.mainBundleFilename, withExtension: asset.type, subdirectory: mainBundleDir) + } + + internal static func path(forBundledAsset asset: UpdateAsset) -> String? { + guard let mainBundleDir = asset.mainBundleDir else { +- return Bundle.main.path(forResource: asset.mainBundleFilename, ofType: asset.type) ++ return getBundle().path(forResource: asset.mainBundleFilename, ofType: asset.type) + } +- return Bundle.main.path(forResource: asset.mainBundleFilename, ofType: asset.type, inDirectory: mainBundleDir) ++ return getBundle().path(forResource: asset.mainBundleFilename, ofType: asset.type, inDirectory: mainBundleDir) + } + + /** diff --git a/.yarn/patches/expo-updates-npm-55.0.20-be281bcd39.patch b/.yarn/patches/expo-updates-npm-55.0.20-be281bcd39.patch new file mode 100644 index 00000000..f784da42 --- /dev/null +++ b/.yarn/patches/expo-updates-npm-55.0.20-be281bcd39.patch @@ -0,0 +1,203 @@ +diff --git a/android/src/main/java/expo/modules/updates/UpdatesController.kt b/android/src/main/java/expo/modules/updates/UpdatesController.kt +index 9abf5b3bb92cda5bc4ab7501c35abe2bffeed59c..4ce541561208d8cd1ccaaf46f49211a5818a4015 100644 +--- a/android/src/main/java/expo/modules/updates/UpdatesController.kt ++++ b/android/src/main/java/expo/modules/updates/UpdatesController.kt +@@ -2,6 +2,7 @@ package expo.modules.updates + + import android.content.Context + import com.facebook.react.ReactApplication ++import com.facebook.react.ReactHost + import expo.modules.updates.events.IUpdatesEventManagerObserver + import expo.modules.updates.loader.LoaderTask + import expo.modules.updates.logging.UpdatesErrorCode +@@ -25,6 +26,19 @@ object UpdatesController { + @Volatile + private var overrideConfiguration: UpdatesConfiguration? = null + ++ @Volatile ++ private var reactHost: ReactHost? = null ++ ++ @JvmStatic ++ fun setReactHost(reactHost: ReactHost) { ++ this.reactHost = reactHost ++ } ++ ++ @JvmStatic ++ fun getReactHost(): ReactHost? { ++ return reactHost ++ } ++ + @JvmStatic + val instance: IUpdatesController + get() { +diff --git a/android/src/main/java/expo/modules/updates/UpdatesPackage.kt b/android/src/main/java/expo/modules/updates/UpdatesPackage.kt +index df17124d19bc734e32594237f7aff3085ea1573f..035d5be5e3189153d32a880ec48b8f45a0fb37d2 100644 +--- a/android/src/main/java/expo/modules/updates/UpdatesPackage.kt ++++ b/android/src/main/java/expo/modules/updates/UpdatesPackage.kt +@@ -49,6 +49,10 @@ class UpdatesPackage : Package { + override fun onReactInstanceException(useDeveloperSupport: Boolean, exception: Exception) { + UpdatesController.instance.onReactInstanceException(exception) + } ++ ++ override fun onDidCreateReactHost(context: Context, reactNativeHost: ReactHost) { ++ UpdatesController.setReactHost(reactNativeHost) ++ } + } + return listOf(handler) + } +diff --git a/android/src/main/java/expo/modules/updates/procedures/RecreateReactContextProcedure.kt b/android/src/main/java/expo/modules/updates/procedures/RecreateReactContextProcedure.kt +index 3bf9f207ae7d3c46151103d8f809821a9df20d56..1ccb4877c2fcefd2c63d43dcc59664c83932805f 100644 +--- a/android/src/main/java/expo/modules/updates/procedures/RecreateReactContextProcedure.kt ++++ b/android/src/main/java/expo/modules/updates/procedures/RecreateReactContextProcedure.kt +@@ -2,7 +2,6 @@ package expo.modules.updates.procedures + + import android.app.Activity + import android.content.Context +-import com.facebook.react.ReactApplication + import expo.modules.updates.launcher.Launcher + import expo.modules.updates.statemachine.UpdatesStateEvent + import kotlinx.coroutines.CoroutineScope +@@ -20,16 +19,11 @@ class RecreateReactContextProcedure( + override val loggerTimerLabel = "timer-recreate-react-context" + + override suspend fun run(procedureContext: ProcedureContext) { +- val reactApplication = context.applicationContext as? ReactApplication ?: run inner@{ +- callback.onFailure(Exception("Could not reload application. Ensure you have passed the correct instance of ReactApplication into UpdatesController.initialize().")) +- return +- } +- + procedureContext.processStateEvent(UpdatesStateEvent.Restart()) + callback.onSuccess() + procedureScope.launch { + withContext(Dispatchers.Main) { +- reactApplication.restart(weakActivity?.get(), "Restart from RecreateReactContextProcedure") ++ RestartReactAppExtensions.restart(weakActivity?.get(), "Restart from RecreateReactContextProcedure") + } + } + procedureContext.resetStateAfterRestart() +diff --git a/android/src/main/java/expo/modules/updates/procedures/RelaunchProcedure.kt b/android/src/main/java/expo/modules/updates/procedures/RelaunchProcedure.kt +index 4cbb7670f0a1853f9ecc9a5e41d033884df793fb..6a74db0df9083635588534e88fb154cdc432c453 100644 +--- a/android/src/main/java/expo/modules/updates/procedures/RelaunchProcedure.kt ++++ b/android/src/main/java/expo/modules/updates/procedures/RelaunchProcedure.kt +@@ -2,7 +2,6 @@ package expo.modules.updates.procedures + + import android.app.Activity + import android.content.Context +-import com.facebook.react.ReactApplication + import expo.modules.updates.UpdatesConfiguration + import expo.modules.updates.db.DatabaseHolder + import expo.modules.updates.db.Reaper +@@ -40,11 +39,6 @@ class RelaunchProcedure( + override val loggerTimerLabel = "timer-relaunch" + + override suspend fun run(procedureContext: ProcedureContext) { +- val reactApplication = context as? ReactApplication ?: run inner@{ +- callback.onFailure(Exception("Could not reload application. Ensure you have passed the correct instance of ReactApplication into UpdatesController.initialize().")) +- return +- } +- + procedureContext.processStateEvent(UpdatesStateEvent.Restart()) + + val newLauncher = DatabaseLauncher( +@@ -71,7 +65,7 @@ class RelaunchProcedure( + procedureScope.launch { + withContext(Dispatchers.Main) { + reloadScreenManager?.show(weakActivity?.get()) +- reactApplication.restart(weakActivity?.get(), "Restart from RelaunchProcedure") ++ RestartReactAppExtensions.restart(weakActivity?.get(), "Restart from RelaunchProcedure") + } + } + +diff --git a/android/src/main/java/expo/modules/updates/procedures/RestartReactAppExtensions.kt b/android/src/main/java/expo/modules/updates/procedures/RestartReactAppExtensions.kt +index 7392ca808be584f994a26f5b7294cd2d29f1fc8d..23252f652bcfbab569541d5ed2d371b7843e2e09 100644 +--- a/android/src/main/java/expo/modules/updates/procedures/RestartReactAppExtensions.kt ++++ b/android/src/main/java/expo/modules/updates/procedures/RestartReactAppExtensions.kt +@@ -2,19 +2,29 @@ package expo.modules.updates.procedures + + import android.app.Activity + import com.facebook.react.ReactApplication ++import com.facebook.react.ReactHost + import com.facebook.react.common.LifecycleState ++import expo.modules.updates.UpdatesController + +-/** +- * An extension for [ReactApplication] to restart the app +- * +- * @param activity For bridgeless mode if the ReactHost is destroyed, we need an Activity to resume it. +- * @param reason The restart reason. Only used on bridgeless mode. +- */ +-internal fun ReactApplication.restart(activity: Activity?, reason: String) { +- val reactHost = this.reactHost +- check(reactHost != null) +- if (reactHost.lifecycleState != LifecycleState.RESUMED && activity != null) { +- reactHost.onHostResume(activity) ++private fun getReactHostReflectively(app: ReactApplication): ReactHost? { ++ return runCatching { ++ app.javaClass.getMethod("getReactHost").invoke(app) as? ReactHost ++ }.getOrNull() ++} ++ ++object RestartReactAppExtensions { ++ /** ++ * A function to restart the app ++ * ++ * @param activity For bridgeless mode if the ReactHost is destroyed, we need an Activity to resume it. ++ * @param reason The restart reason. Only used on bridgeless mode. ++ */ ++ internal fun restart(activity: Activity?, reason: String) { ++ val reactHost = UpdatesController.getReactHost() ?: getReactHostReflectively(activity?.application as ReactApplication) ++ check(reactHost != null) ++ if (reactHost.lifecycleState != LifecycleState.RESUMED && activity != null) { ++ reactHost.onHostResume(activity) ++ } ++ reactHost.reload(reason) + } +- reactHost.reload(reason) + } +\ No newline at end of file +diff --git a/ios/EXUpdates/UpdatesConfig.swift b/ios/EXUpdates/UpdatesConfig.swift +index 75df5a42c4b2622cfc51ca6bddb22e00497118cb..21779ae0ab8ac717f4b7688139d9aefc88dd89be 100644 +--- a/ios/EXUpdates/UpdatesConfig.swift ++++ b/ios/EXUpdates/UpdatesConfig.swift +@@ -145,7 +145,8 @@ public final class UpdatesConfig: NSObject { + } + + private static func configDictionaryWithExpoPlist(mergingOtherDictionary: [String: Any]?) throws -> [String: Any] { +- guard let configPlistPath = Bundle.main.path(forResource: PlistName, ofType: "plist") else { ++ let bundle = Bundle(for: UpdatesConfig.self) ++ guard let configPlistPath = bundle.path(forResource: PlistName, ofType: "plist") else { + throw UpdatesConfigError.ExpoUpdatesConfigPlistError + } + +diff --git a/ios/EXUpdates/UpdatesUtils.swift b/ios/EXUpdates/UpdatesUtils.swift +index a1e2c9af4ebaf9e50db2acaabfa876fc46d22454..9260c47bf28d5fb3ae31df966d9af775683836fe 100644 +--- a/ios/EXUpdates/UpdatesUtils.swift ++++ b/ios/EXUpdates/UpdatesUtils.swift +@@ -108,18 +108,23 @@ public final class UpdatesUtils: NSObject { + return assetFilesMap + } + ++ ++ private static func getBundle() -> Bundle { ++ return Bundle(for: UpdatesConfig.self) ++ } ++ + internal static func url(forBundledAsset asset: UpdateAsset) -> URL? { + guard let mainBundleDir = asset.mainBundleDir else { +- return Bundle.main.url(forResource: asset.mainBundleFilename, withExtension: asset.type) ++ return getBundle().url(forResource: asset.mainBundleFilename, withExtension: asset.type) + } +- return Bundle.main.url(forResource: asset.mainBundleFilename, withExtension: asset.type, subdirectory: mainBundleDir) ++ return getBundle().url(forResource: asset.mainBundleFilename, withExtension: asset.type, subdirectory: mainBundleDir) + } + + internal static func path(forBundledAsset asset: UpdateAsset) -> String? { + guard let mainBundleDir = asset.mainBundleDir else { +- return Bundle.main.path(forResource: asset.mainBundleFilename, ofType: asset.type) ++ return getBundle().path(forResource: asset.mainBundleFilename, ofType: asset.type) + } +- return Bundle.main.path(forResource: asset.mainBundleFilename, ofType: asset.type, inDirectory: mainBundleDir) ++ return getBundle().path(forResource: asset.mainBundleFilename, ofType: asset.type, inDirectory: mainBundleDir) + } + + /** diff --git a/apps/AndroidApp/app/build.gradle.kts b/apps/AndroidApp/app/build.gradle.kts index afbb59b1..d58dd702 100644 --- a/apps/AndroidApp/app/build.gradle.kts +++ b/apps/AndroidApp/app/build.gradle.kts @@ -61,10 +61,20 @@ android { buildFeatures { compose = true } + + packaging { + jniLibs { + pickFirsts.add("**/libc++_shared.so") + } + } } dependencies { implementation("com.google.code.gson:gson:2.13.1") + implementation("androidx.room:room-runtime:2.6.1") + implementation("androidx.room:room-ktx:2.6.1") + implementation("com.squareup.okhttp3:okhttp-brotli:4.9.2") + implementation(libs.androidx.core.ktx) implementation(libs.androidx.lifecycle.runtime.ktx) implementation(libs.androidx.activity.compose) diff --git a/apps/AndroidApp/app/src/main/java/com/callstack/brownfield/android/example/MainActivity.kt b/apps/AndroidApp/app/src/main/java/com/callstack/brownfield/android/example/MainActivity.kt index f1311942..0c9972a4 100644 --- a/apps/AndroidApp/app/src/main/java/com/callstack/brownfield/android/example/MainActivity.kt +++ b/apps/AndroidApp/app/src/main/java/com/callstack/brownfield/android/example/MainActivity.kt @@ -1,5 +1,6 @@ package com.callstack.brownfield.android.example +//import com.callstack.brownie.registerStoreIfNeeded import android.content.Intent import android.content.res.Configuration import android.os.Bundle @@ -27,9 +28,9 @@ import androidx.fragment.compose.AndroidFragment import com.callstack.brownfield.android.example.components.GreetingCard import com.callstack.brownfield.android.example.components.PostMessageCard import com.callstack.brownfield.android.example.ui.theme.AndroidBrownfieldAppTheme -import com.callstack.brownie.registerStoreIfNeeded import com.callstack.nativebrownfieldnavigation.BrownfieldNavigationDelegate import com.callstack.nativebrownfieldnavigation.BrownfieldNavigationManager +import com.callstack.reactnativebrownfield.ReactNativeBrownfield import com.callstack.reactnativebrownfield.ReactNativeFragment import com.callstack.reactnativebrownfield.constants.ReactNativeFragmentArgNames @@ -54,14 +55,14 @@ class MainActivity : AppCompatActivity(), BrownfieldNavigationDelegate { ).show() } - registerStoreIfNeeded( - storeName = BrownfieldStore.STORE_NAME - ) { - BrownfieldStore( - counter = 0.0, - user = User(name = "Username") - ) - } +// registerStoreIfNeeded( +// storeName = BrownfieldStore.STORE_NAME +// ) { +// BrownfieldStore( +// counter = 0.0, +// user = User(name = "Username") +// ) +// } } setContent { @@ -101,11 +102,13 @@ private fun MainScreen(modifier: Modifier = Modifier) { verticalArrangement = Arrangement.spacedBy(16.dp), horizontalAlignment = Alignment.CenterHorizontally // center top bar content ) { + Spacer(modifier = Modifier.height(3.dp)) + GreetingCard( name = ReactNativeConstants.APP_NAME, ) - PostMessageCard() +// PostMessageCard() Spacer(modifier = Modifier.height(1.dp)) diff --git a/apps/AndroidApp/app/src/main/java/com/callstack/brownfield/android/example/components/GreetingCard.kt b/apps/AndroidApp/app/src/main/java/com/callstack/brownfield/android/example/components/GreetingCard.kt index 1f04e99f..2a842ef5 100644 --- a/apps/AndroidApp/app/src/main/java/com/callstack/brownfield/android/example/components/GreetingCard.kt +++ b/apps/AndroidApp/app/src/main/java/com/callstack/brownfield/android/example/components/GreetingCard.kt @@ -8,7 +8,7 @@ import androidx.compose.material3.Button import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.DisposableEffect +//import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.remember @@ -17,15 +17,15 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import com.callstack.brownfield.android.example.BrownfieldStore -import com.callstack.brownie.Store -import com.callstack.brownie.StoreManager -import com.callstack.brownie.store -import com.callstack.brownie.subscribe +//import com.callstack.brownfield.android.example.BrownfieldStore +//import com.callstack.brownie.Store +//import com.callstack.brownie.StoreManager +//import com.callstack.brownie.store +//import com.callstack.brownie.subscribe -private fun brownieStore(): Store? { - return StoreManager.shared.store(BrownfieldStore.STORE_NAME) -} +//private fun brownieStore(): Store? { +// return StoreManager.shared.store(BrownfieldStore.STORE_NAME) +//} @Composable fun GreetingCard( @@ -33,17 +33,17 @@ fun GreetingCard( ) { var counter by remember { mutableIntStateOf(0) } - DisposableEffect(Unit) { - val store = brownieStore() - val unsubscribe = store?.subscribe( - selector = { state -> state.counter.toInt() }, - onChange = { updatedCounter -> counter = updatedCounter } - ) ?: {} - - onDispose { - unsubscribe() - } - } +// DisposableEffect(Unit) { +// val store = brownieStore() +// val unsubscribe = store?.subscribe( +// selector = { state -> state.counter.toInt() }, +// onChange = { updatedCounter -> counter = updatedCounter } +// ) ?: {} +// +// onDispose { +// unsubscribe() +// } +// } MaterialCard { Column( @@ -59,19 +59,19 @@ fun GreetingCard( textAlign = TextAlign.Center ) - Text( - text = "You clicked the button $counter time${if (counter == 1) "" else "s"}", - textAlign = TextAlign.Center, - style = MaterialTheme.typography.bodyMedium - ) - - Button(onClick = { - brownieStore()?.set { state -> - state.copy(counter = state.counter + 1) - } - }) { - Text("Increment counter") - } +// Text( +// text = "You clicked the button $counter time${if (counter == 1) "" else "s"}", +// textAlign = TextAlign.Center, +// style = MaterialTheme.typography.bodyMedium +// ) +// +// Button(onClick = { +//// brownieStore()?.set { state -> +//// state.copy(counter = state.counter + 1) +//// } +// }) { +// Text("Increment counter") +// } } } } \ No newline at end of file diff --git a/apps/AppleApp/Brownfield Apple App.xcodeproj/project.pbxproj b/apps/AppleApp/Brownfield Apple App.xcodeproj/project.pbxproj index 78323de0..ebde8c30 100644 --- a/apps/AppleApp/Brownfield Apple App.xcodeproj/project.pbxproj +++ b/apps/AppleApp/Brownfield Apple App.xcodeproj/project.pbxproj @@ -9,8 +9,6 @@ /* Begin PBXBuildFile section */ 614B23922F50633200CB6363 /* BrownfieldLib.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 614B238D2F50633200CB6363 /* BrownfieldLib.xcframework */; }; 614B23932F50633200CB6363 /* BrownfieldLib.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 614B238D2F50633200CB6363 /* BrownfieldLib.xcframework */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 614B23942F50633200CB6363 /* Brownie.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 614B238E2F50633200CB6363 /* Brownie.xcframework */; }; - 614B23952F50633200CB6363 /* Brownie.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 614B238E2F50633200CB6363 /* Brownie.xcframework */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 614B23962F50633200CB6363 /* BrownfieldNavigation.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 614B238F2F50633200CB6363 /* BrownfieldNavigation.xcframework */; }; 614B23972F50633200CB6363 /* BrownfieldNavigation.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 614B238F2F50633200CB6363 /* BrownfieldNavigation.xcframework */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 614B23982F50633200CB6363 /* hermesvm.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 614B23902F50633200CB6363 /* hermesvm.xcframework */; }; @@ -27,7 +25,6 @@ dstSubfolderSpec = 10; files = ( 614B23972F50633200CB6363 /* BrownfieldNavigation.xcframework in Embed Frameworks */, - 614B23952F50633200CB6363 /* Brownie.xcframework in Embed Frameworks */, 614B239B2F50633200CB6363 /* ReactBrownfield.xcframework in Embed Frameworks */, 614B23992F50633200CB6363 /* hermesvm.xcframework in Embed Frameworks */, 614B23932F50633200CB6363 /* BrownfieldLib.xcframework in Embed Frameworks */, @@ -39,7 +36,6 @@ /* Begin PBXFileReference section */ 614B238D2F50633200CB6363 /* BrownfieldLib.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = BrownfieldLib.xcframework; path = package/BrownfieldLib.xcframework; sourceTree = ""; }; - 614B238E2F50633200CB6363 /* Brownie.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Brownie.xcframework; path = package/Brownie.xcframework; sourceTree = ""; }; 614B238F2F50633200CB6363 /* BrownfieldNavigation.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = BrownfieldNavigation.xcframework; path = package/BrownfieldNavigation.xcframework; sourceTree = ""; }; 614B23902F50633200CB6363 /* hermesvm.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = hermesvm.xcframework; path = package/hermesvm.xcframework; sourceTree = ""; }; 614B23912F50633200CB6363 /* ReactBrownfield.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = ReactBrownfield.xcframework; path = package/ReactBrownfield.xcframework; sourceTree = ""; }; @@ -60,7 +56,6 @@ buildActionMask = 2147483647; files = ( 614B23962F50633200CB6363 /* BrownfieldNavigation.xcframework in Frameworks */, - 614B23942F50633200CB6363 /* Brownie.xcframework in Frameworks */, 614B239A2F50633200CB6363 /* ReactBrownfield.xcframework in Frameworks */, 614B23982F50633200CB6363 /* hermesvm.xcframework in Frameworks */, 614B23922F50633200CB6363 /* BrownfieldLib.xcframework in Frameworks */, @@ -75,7 +70,6 @@ children = ( 614B238D2F50633200CB6363 /* BrownfieldLib.xcframework */, 614B238F2F50633200CB6363 /* BrownfieldNavigation.xcframework */, - 614B238E2F50633200CB6363 /* Brownie.xcframework */, 614B23902F50633200CB6363 /* hermesvm.xcframework */, 614B23912F50633200CB6363 /* ReactBrownfield.xcframework */, ); diff --git a/apps/AppleApp/Brownfield Apple App.xcodeproj/xcshareddata/xcschemes/Brownfield Apple App Expo.xcscheme b/apps/AppleApp/Brownfield Apple App.xcodeproj/xcshareddata/xcschemes/Brownfield Apple App Expo.xcscheme index 25cbd4e2..b491f3bb 100644 --- a/apps/AppleApp/Brownfield Apple App.xcodeproj/xcshareddata/xcschemes/Brownfield Apple App Expo.xcscheme +++ b/apps/AppleApp/Brownfield Apple App.xcodeproj/xcshareddata/xcschemes/Brownfield Apple App Expo.xcscheme @@ -31,7 +31,7 @@ shouldAutocreateTestPlan = "YES"> Bool { + return ReactNativeBrownfield.shared.application(application, willFinishLaunchingWithOptions: launchOptions) + } } public class RNNavigationDelegate: BrownfieldNavigationDelegate { @@ -87,7 +91,7 @@ struct BrownfieldAppleApp: App { ReactNativeBrownfield.shared.ensureExpoModulesProvider() #endif - BrownfieldStore.register(initialState) +// BrownfieldStore.register(initialState) } var body: some Scene { diff --git a/apps/AppleApp/Brownfield Apple App/components/ContentView.swift b/apps/AppleApp/Brownfield Apple App/components/ContentView.swift index 7f08507a..be6369a0 100644 --- a/apps/AppleApp/Brownfield Apple App/components/ContentView.swift +++ b/apps/AppleApp/Brownfield Apple App/components/ContentView.swift @@ -1,4 +1,4 @@ -import Brownie +//import Brownie import ReactBrownfield import SwiftUI import UIKit @@ -9,10 +9,10 @@ struct ChatMessage: Identifiable { let fromRN: Bool } -let initialState = BrownfieldStore( - counter: 0, - user: User(name: "Username") -) +//let initialState = BrownfieldStore( +// counter: 0, +// user: User(name: "Username") +//) struct ContentView: View { var body: some View { @@ -23,7 +23,7 @@ struct ContentView: View { MessagesView() - ReactNativeView(moduleName: "main") + ReactNativeView(moduleName: "RNApp") .navigationBarHidden(true) .clipShape(RoundedRectangle(cornerRadius: 16)) .background(Color(UIColor.systemBackground)) diff --git a/apps/AppleApp/Brownfield Apple App/components/GreetingCard.swift b/apps/AppleApp/Brownfield Apple App/components/GreetingCard.swift index 8829bf7f..ee242afc 100644 --- a/apps/AppleApp/Brownfield Apple App/components/GreetingCard.swift +++ b/apps/AppleApp/Brownfield Apple App/components/GreetingCard.swift @@ -1,9 +1,9 @@ import SwiftUI -import Brownie +//import Brownie struct GreetingCard: View { let name: String - @UseStore(\BrownfieldStore.counter) var counter +// @UseStore(\BrownfieldStore.counter) var counter var body: some View { MaterialCard { @@ -11,16 +11,16 @@ struct GreetingCard: View { .font(.title3) .multilineTextAlignment(.center) - Text( - "You clicked the button \(Int(counter)) time\(counter == 1 ? "" : "s")" - ) - .multilineTextAlignment(.center) - .font(.body) - - Button("Increment counter") { - $counter.set { $0 + 1 } - } - .buttonStyle(.borderedProminent) +// Text( +// "You clicked the button \(Int(counter)) time\(counter == 1 ? "" : "s")" +// ) +// .multilineTextAlignment(.center) +// .font(.body) +// +// Button("Increment counter") { +// $counter.set { $0 + 1 } +// } +// .buttonStyle(.borderedProminent) } } } diff --git a/apps/AppleApp/Brownfield Apple App/components/SettingsScreen.swift b/apps/AppleApp/Brownfield Apple App/components/SettingsScreen.swift index d5f584c3..f8eab904 100644 --- a/apps/AppleApp/Brownfield Apple App/components/SettingsScreen.swift +++ b/apps/AppleApp/Brownfield Apple App/components/SettingsScreen.swift @@ -19,4 +19,4 @@ struct SettingsScreen: View { } .navigationTitle("Settings") } -} \ No newline at end of file +} diff --git a/apps/ExpoApp54/BrownfieldStore.brownie.ts b/apps/ExpoApp54/BrownfieldStore.brownie.ts index 94e22c72..142e3934 100644 --- a/apps/ExpoApp54/BrownfieldStore.brownie.ts +++ b/apps/ExpoApp54/BrownfieldStore.brownie.ts @@ -1,21 +1,21 @@ -import type { BrownieStore } from '@callstack/brownie'; +// import type { BrownieStore } from '@callstack/brownie'; -export interface BrownfieldStore extends BrownieStore { - counter: number; - user: { - name: string; - }; -} +// export interface BrownfieldStore extends BrownieStore { +// counter: number; +// user: { +// name: string; +// }; +// } -export interface SettingsStore extends BrownieStore { - theme: 'light' | 'dark'; - notificationsEnabled: boolean; - privacyMode: boolean; -} +// export interface SettingsStore extends BrownieStore { +// theme: 'light' | 'dark'; +// notificationsEnabled: boolean; +// privacyMode: boolean; +// } -declare module '@callstack/brownie' { - interface BrownieStores { - BrownfieldStore: BrownfieldStore; - SettingsStore: SettingsStore; - } -} +// declare module '@callstack/brownie' { +// interface BrownieStores { +// BrownfieldStore: BrownfieldStore; +// SettingsStore: SettingsStore; +// } +// } diff --git a/apps/ExpoApp54/RNApp.tsx b/apps/ExpoApp54/RNApp.tsx index 5d08feed..93bc398b 100644 --- a/apps/ExpoApp54/RNApp.tsx +++ b/apps/ExpoApp54/RNApp.tsx @@ -2,7 +2,7 @@ import { SafeAreaView } from 'react-native-safe-area-context'; import { Button, StyleSheet, Text, View } from 'react-native'; import BrownfieldNavigation from '@callstack/brownfield-navigation'; -import Counter from './components/counter'; +import { checkAndFetchUpdate } from './utils/expo-rn-updates'; export default function RNApp() { return ( @@ -10,8 +10,6 @@ export default function RNApp() { Expo React Native Brownfield - -