Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,11 @@ dependencies {
implementation "com.facebook.react:react-native:+"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

implementation 'com.expofp:common:4.10.0'
implementation 'com.expofp:fplan:4.10.0'
implementation 'com.expofp:common:4.11.0'
implementation 'com.expofp:fplan:4.11.0'

implementation 'com.expofp:crowdconnected:4.10.0'
// implementation 'com.expofp:crowdconnectedbackground:4.10.0'
implementation 'com.expofp:crowdconnected:4.11.0'
// implementation 'com.expofp:crowdconnectedbackground:4.11.0'
implementation 'net.crowdconnected.android.core:android-core:2.0.2'
implementation 'net.crowdconnected.android.ips:android-ips:2.0.2'
implementation 'net.crowdconnected.android.geo:android-geo:2.0.2'
Expand Down
78 changes: 68 additions & 10 deletions android/src/main/java/com/expofp/ExpofpViewManager.kt
Original file line number Diff line number Diff line change
@@ -1,27 +1,20 @@
package com.expofp

import android.Manifest
import android.app.Activity
import android.app.AlertDialog
import android.app.Application
import android.os.Build
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.app.ActivityCompat
import com.expofp.common.GlobalLocationProvider
import com.expofp.crowdconnected.CrowdConnectedProvider
import com.expofp.crowdconnected.Mode
import com.expofp.crowdconnected.Settings
// import com.expofp.crowdconnectedbackground.CrowdConnectedBackgroundProvider
import com.expofp.fplan.FplanView
import com.expofp.fplan.models.FplanViewState
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

class ExpofpViewManager : SimpleViewManager<View>() {
private var reactContext: ThemedReactContext? = null
Expand All @@ -40,6 +33,67 @@ class ExpofpViewManager : SimpleViewManager<View>() {
super.onDropViewInstance(view)
}

private fun getExpoKeyFromUrl(url: String): String {
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")
}
})
}

@ReactProp(name = "settings")
fun setSettings(view: FplanView, settingsMap: ReadableMap?) {
println("setSettings: $settingsMap")
Expand Down Expand Up @@ -68,7 +122,11 @@ class ExpofpViewManager : SimpleViewManager<View>() {
GlobalLocationProvider.start()
}
if (view.state.equals(FplanViewState.Created)) {
view.load(it.getString("url") ?: "", com.expofp.fplan.models.Settings().withGlobalLocationProvider());
val url = it.getString("url") ?: ""
val expoKey = getExpoKeyFromUrl(url)

openMapForUrl(view, url)
triggerOfflinePlanDownload(expoKey)
}
}
}
Expand Down
54 changes: 52 additions & 2 deletions ios/ExpofpViewManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,63 @@ struct ExpoFP: View {

@State private var loadedUrl: NSString? = nil

private var defaultSettings: ExpoFpFplan.Settings { .init(useGlobalLocationProvider: true) }

private func expoKey(from urlString: String) -> String {
return (URL(string: urlString)?.host ?? "").components(separatedBy: ".").first ?? ""
}

private func openMap(for urlString: String) {
let key = expoKey(from: urlString)
print("expoKey: \(key)")

if let cachePath = SharedFplanView.getFilePathFromCache() {
let pathComponents = cachePath.absoluteString.components(separatedBy: "/")
let cachedExpoKey = pathComponents.count >= 2 ? pathComponents[pathComponents.count - 2] : ""
print("cachePath: \(cachePath.absoluteString)")
print("cachedExpoKey: \(cachedExpoKey)")
if cachedExpoKey == key {
print("loading from cache")
fplanView.openFile(htmlFilePathUrl: cachePath, params: nil, settings: defaultSettings)
return
} else {
print("cache key mismatch, expected: \(key), found: \(cachedExpoKey)")
}
}

if let path = Bundle.main.path(forResource: key, ofType: "zip", inDirectory: "maps") {
print("loading from preloaded map path: \(path)")
fplanView.openZip(path, params: nil, useGlobalLocationProvider: true)
return
}

print("loading from url")
fplanView.load(urlString, useGlobalLocationProvider: true)
}

private func downloadOffline(for urlString: String) {
print("downloading the map")
fplanView.downloadZipToCache(urlString) { htmlFilePath, error in
if let error = error {
print("error downloading the map: \(error)")
} else {
print("success downloading the map")
if let htmlFilePath = htmlFilePath {
print("htmlFilePath: \(htmlFilePath)")
}
}
}
}

var body: some View {
VStack
{
fplanView.onAppear{
if (loadedUrl !== dataStore.url) {
fplanView.load(dataStore.url as String, useGlobalLocationProvider: true)
if loadedUrl != dataStore.url {
let urlString = dataStore.url as String
openMap(for: urlString)
loadedUrl = dataStore.url
downloadOffline(for: urlString)
}
}.onDisappear{
fplanView.clear()
Expand Down