diff --git a/android/build.gradle b/android/build.gradle index 8e15162..888c1f3 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -91,11 +91,10 @@ dependencies { implementation "com.facebook.react:react-native:+" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'com.expofp:common:4.11.0' - implementation 'com.expofp:fplan:4.11.0' + implementation 'com.expofp:fplan:5.1.0' - implementation 'com.expofp:crowdconnected:4.11.0' - // implementation 'com.expofp:crowdconnectedbackground:4.11.0' + implementation 'com.expofp:crowdconnected:5.1.0' + // implementation 'com.expofp:crowdconnectedbackground:5.1.0' implementation 'net.crowdconnected.android.core:android-core:2.1.0' implementation 'net.crowdconnected.android.ips:android-ips:2.1.0' implementation 'net.crowdconnected.android.geo:android-geo:2.1.0' diff --git a/android/src/main/java/com/expofp/ExpofpModule.kt b/android/src/main/java/com/expofp/ExpofpModule.kt index f0305f6..23751c0 100644 --- a/android/src/main/java/com/expofp/ExpofpModule.kt +++ b/android/src/main/java/com/expofp/ExpofpModule.kt @@ -1,28 +1,17 @@ package com.expofp -import com.facebook.react.bridge.NativeModule +import android.util.Log import com.facebook.react.bridge.ReactApplicationContext -import com.facebook.react.bridge.ReactContext import com.facebook.react.bridge.ReactContextBaseJavaModule import com.facebook.react.bridge.ReactMethod import com.facebook.react.bridge.Promise -import com.expofp.fplan.SharedFplanView -import com.expofp.fplan.models.Settings -import com.facebook.react.bridge.UiThreadUtil class ExpofpModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) { override fun getName() = "ExpofpModule" @ReactMethod fun preload(url: String, promise: Promise) { - try { - val context = this.reactApplicationContext.applicationContext - UiThreadUtil.runOnUiThread { - SharedFplanView.preload(url, Settings(), context) - } - promise.resolve(null) - } catch (e: Exception) { - promise.reject("PRELOAD_ERROR", e.message) - } + Log.d("ExpofpModule", "preload: not implemented") + promise.reject("PRELOAD_UNAVAILABLE", "ExpoFP Android v5 preload is not implemented yet") } } \ No newline at end of file diff --git a/android/src/main/java/com/expofp/ExpofpViewManager.kt b/android/src/main/java/com/expofp/ExpofpViewManager.kt index c87b2f0..1b55b58 100644 --- a/android/src/main/java/com/expofp/ExpofpViewManager.kt +++ b/android/src/main/java/com/expofp/ExpofpViewManager.kt @@ -1,35 +1,31 @@ package com.expofp import android.app.Application -import android.util.Log -import android.view.View -import com.expofp.common.GlobalLocationProvider -import com.expofp.crowdconnected.CrowdConnectedProvider -import com.expofp.crowdconnected.Mode -import com.expofp.fplan.FplanView -import com.expofp.fplan.models.FplanViewState +import com.expofp.fplan.api.app.ExpoFpPlan +import com.expofp.fplan.api.app.model.ExpoFpLinkType +import com.expofp.fplan.api.locationProvider.IExpoFpLocationProvider +import com.expofp.fplan.ui.ExpoFpView import com.facebook.react.bridge.ReadableMap import com.facebook.react.uimanager.SimpleViewManager import com.facebook.react.uimanager.ThemedReactContext import com.facebook.react.uimanager.annotations.ReactProp -import com.expofp.R -import com.expofp.fplan.contracts.DownloadOfflinePlanCallback -import com.expofp.fplan.models.OfflinePlanInfo +import com.expofp.crowdconnected.ExpoFpCrowdConnectedLocationProvider +// import com.expofp.crowdconnectedbackground.ExpoFpCrowdConnectedBackgroundLocationProvider +import com.expofp.crowdconnected.ExpoFpCrowdConnectedLocationProviderSettings +import com.expofp.crowdconnected.ExpoFpCrowdConnectedNavigationType -class ExpofpViewManager : SimpleViewManager() { +class ExpofpViewManager : SimpleViewManager() { private var reactContext: ThemedReactContext? = null override fun getName() = "ExpofpView" - override fun createViewInstance(reactContext: ThemedReactContext): View { + override fun createViewInstance(reactContext: ThemedReactContext): ExpoFpView { this.reactContext = reactContext - var view = FplanView(reactContext) - - return view; + ExpoFpPlan.initialize(reactContext.applicationContext) + return ExpoFpView(reactContext) } - override fun onDropViewInstance(view: View) { - (view as? FplanView)?.destroy() + override fun onDropViewInstance(view: ExpoFpView) { super.onDropViewInstance(view) } @@ -37,97 +33,46 @@ class ExpofpViewManager : SimpleViewManager() { return url.substringAfter("https://").substringBefore(".expofp.com") } - private fun openMapForUrl(view: FplanView, url: String) { - val expoKey = getExpoKeyFromUrl(url) - val settings = com.expofp.fplan.models.Settings().withGlobalLocationProvider() - - val offlinePlanManager = FplanView.getOfflinePlanManager(reactContext) - val latestOfflinePlan = offlinePlanManager.allOfflinePlansFromCache - .filter { offlinePlanInfo -> offlinePlanInfo.expoKey == expoKey } - .maxByOrNull { offlinePlanInfo -> offlinePlanInfo.version } - - if (latestOfflinePlan != null) { - Log.d("ExpofpModule", latestOfflinePlan.expoKey) - view.openOfflinePlan(latestOfflinePlan, "", settings) - return - } - - val ctx = this.reactContext ?: run { - view.load(url, settings) - return - } - - val am = ctx.assets - val cachePlanExists = try { - am.open("${expoKey}.zip").close() - true - } catch (e: Exception) { - false - } - - if (cachePlanExists) { - try { - Log.d("ExpofpModule", "openZipFromAssets: ${expoKey}.zip") - view.openZipFromAssets("${expoKey}.zip", "", settings, ctx) - return - } catch (e: Exception) { - Log.d("ExpofpModule", "failed to open asset zip, loading url: $url") - view.load(url, settings) - return - } - } - - Log.d("ExpofpModule", "asset zip not found, loading url: $url") - view.load(url, settings) - } - - private fun triggerOfflinePlanDownload(expoKey: String) { - val offlinePlanManager = FplanView.getOfflinePlanManager(reactContext) - offlinePlanManager.downloadOfflinePlanToCache(expoKey, object : DownloadOfflinePlanCallback { - override fun onCompleted(offlinePlanInfo: OfflinePlanInfo) { - Log.d("ExpofpModule", "downloaded offline plan: ${offlinePlanInfo.expoKey} v${offlinePlanInfo.version}") - } - - override fun onError(message: String) { - Log.e("ExpofpModule", "offline plan download failed: $message") - } - }) + private fun createCrowdConnectedProvider(settingsMap: ReadableMap): IExpoFpLocationProvider? { + val context = reactContext?.applicationContext ?: return null + val application = (context as? Application) ?: return null + + val cc = if (settingsMap.hasKey("crowdConnected")) settingsMap.getMap("crowdConnected") else settingsMap + if (cc == null) return null + + val appKey = if (cc.hasKey("appKey")) cc.getString("appKey") else null + val token = if (cc.hasKey("token")) cc.getString("token") else null + val secret = if (cc.hasKey("secret")) cc.getString("secret") else null + if (appKey.isNullOrEmpty() || token.isNullOrEmpty() || secret.isNullOrEmpty()) return null + val aliases = mutableMapOf() + aliases["onesignal_user_id"] = cc.getString("oneSignalUserId") ?: "" + val settings = ExpoFpCrowdConnectedLocationProviderSettings( + appKey = appKey, + token = token, + secret = secret, + navigationType = ExpoFpCrowdConnectedNavigationType.ALL, + isAllowedInBackground = false, + isHeadingEnabled = true, + aliases = aliases, + notificationText = "Indoor navigation is active", + serviceIcon = R.drawable.placeholder_icon + ) + + // ExpoFpCrowdConnectedBackgroundLocationProvider(application, settings) + return ExpoFpCrowdConnectedLocationProvider(application, settings) } @ReactProp(name = "settings") - fun setSettings(view: FplanView, settingsMap: ReadableMap?) { - println("setSettings: $settingsMap") - settingsMap?.let { - var appKey = settingsMap.getString("appKey") - val token = settingsMap.getString("token") - val secret = settingsMap.getString("secret") - if (appKey != null && token != null && secret != null) { - val context = reactContext?.applicationContext ?: return - val application = context as? Application ?: return - val aliases = mutableMapOf() - aliases["onesignal_user_id"] = it.getString("oneSignalUserId") ?: "" - val lpSettings = com.expofp.crowdconnected.Settings( - settingsMap.getString("appKey") ?: "", - settingsMap.getString("token") ?: "", - settingsMap.getString("secret") ?: "", - Mode.IPS_AND_GPS, - true, - aliases - ) - lpSettings.setServiceNotificationInfo("Background Location is running", R.drawable.placeholder_icon); - - val locationProvider = CrowdConnectedProvider(application, lpSettings) - // val locationProvider = CrowdConnectedBackgroundProvider(application, lpSettings) - GlobalLocationProvider.init(locationProvider) - GlobalLocationProvider.start() - } - if (view.state.equals(FplanViewState.Created)) { - val url = it.getString("url") ?: "" - val expoKey = getExpoKeyFromUrl(url) + fun setSettings(view: ExpoFpView, settingsMap: ReadableMap?) { + if (settingsMap == null) return + val url = settingsMap.getString("url") ?: return + val context = reactContext?.applicationContext ?: return + val expoKey = getExpoKeyFromUrl(url) - openMapForUrl(view, url) - triggerOfflinePlanDownload(expoKey) - } - } + ExpoFpPlan.initialize(context) + val p = ExpoFpPlan.createPlanPresenter(planLink = ExpoFpLinkType.ExpoKey(expoKey)) + val ccProvider = createCrowdConnectedProvider(settingsMap) + if (ccProvider != null) p.setLocationProvider(ccProvider) + view.attachPresenter(p) } } \ No newline at end of file