Penguin integrated and framework files added to gitignore.
@ -0,0 +1,27 @@
|
|||||||
|
//package com.cloud.diplomaticquarterapp
|
||||||
|
package com.ejada.hmg
|
||||||
|
|
||||||
|
|
||||||
|
import io.flutter.app.FlutterApplication
|
||||||
|
|
||||||
|
class Application : FlutterApplication() {
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//import io.flutter.app.FlutterApplication
|
||||||
|
//import io.flutter.plugin.common.PluginRegistry
|
||||||
|
//import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
|
||||||
|
//import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService
|
||||||
|
//
|
||||||
|
//class Application : FlutterApplication(), PluginRegistrantCallback {
|
||||||
|
// override fun onCreate() {
|
||||||
|
// super.onCreate()
|
||||||
|
// FlutterFirebaseMessagingService.setPluginRegistrant(this)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// override fun registerWith(registry: PluginRegistry?) {
|
||||||
|
// FirebaseCloudMessagingPluginRegistrant.registerWith(registry)
|
||||||
|
// }
|
||||||
|
//}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
package com.ejada.hmg
|
||||||
|
|
||||||
|
import io.flutter.embedding.android.FlutterFragmentActivity
|
||||||
|
import android.util.Log
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.annotation.NonNull
|
||||||
|
import android.os.Build
|
||||||
|
import io.flutter.embedding.engine.FlutterEngine
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
|
||||||
|
class MainActivity : FlutterFragmentActivity(){
|
||||||
|
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
|
||||||
|
super.configureFlutterEngine(flutterEngine)
|
||||||
|
PenguinInPlatformBridge(flutterEngine, this).create()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRequestPermissionsResult(
|
||||||
|
requestCode: Int,
|
||||||
|
permissions: Array<out String>,
|
||||||
|
grantResults: IntArray
|
||||||
|
) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||||
|
val granted = grantResults.all { it == PackageManager.PERMISSION_GRANTED }
|
||||||
|
val intent = Intent("PERMISSION_RESULT_ACTION").apply {
|
||||||
|
putExtra("PERMISSION_GRANTED", granted)
|
||||||
|
}
|
||||||
|
sendBroadcast(intent)
|
||||||
|
// Log the request code and permission results
|
||||||
|
Log.d("PermissionsResult", "Request Code: $requestCode")
|
||||||
|
Log.d("PermissionsResult", "Permissions: ${permissions.joinToString()}")
|
||||||
|
Log.d("PermissionsResult", "Grant Results: ${grantResults.joinToString()}")
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package com.ejada.hmg.PermissionManager
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.os.Build
|
||||||
|
|
||||||
|
object PermissionHelper {
|
||||||
|
|
||||||
|
fun getRequiredPermissions(): Array<String> {
|
||||||
|
val permissions = mutableListOf(
|
||||||
|
Manifest.permission.INTERNET,
|
||||||
|
Manifest.permission.ACCESS_FINE_LOCATION,
|
||||||
|
Manifest.permission.ACCESS_COARSE_LOCATION,
|
||||||
|
Manifest.permission.ACCESS_NETWORK_STATE,
|
||||||
|
Manifest.permission.BLUETOOTH,
|
||||||
|
Manifest.permission.BLUETOOTH_ADMIN,
|
||||||
|
// Manifest.permission.ACTIVITY_RECOGNITION
|
||||||
|
)
|
||||||
|
|
||||||
|
// For Android 12 (API level 31) and above, add specific permissions
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { // Android 12 (API 31) and above
|
||||||
|
permissions.add(Manifest.permission.BLUETOOTH_SCAN)
|
||||||
|
permissions.add(Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
|
permissions.add(Manifest.permission.HIGH_SAMPLING_RATE_SENSORS)
|
||||||
|
}
|
||||||
|
|
||||||
|
return permissions.toTypedArray()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
package com.ejada.hmg.PermissionManager
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.core.app.ActivityCompat
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
|
||||||
|
class PermissionManager(
|
||||||
|
private val context: Context,
|
||||||
|
val listener: PermissionListener,
|
||||||
|
private val requestCode: Int,
|
||||||
|
vararg permissions: String
|
||||||
|
) {
|
||||||
|
|
||||||
|
private val permissionsArray = permissions
|
||||||
|
|
||||||
|
interface PermissionListener {
|
||||||
|
fun onPermissionGranted()
|
||||||
|
fun onPermissionDenied()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun arePermissionsGranted(): Boolean {
|
||||||
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
permissionsArray.all {
|
||||||
|
ContextCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun requestPermissions(activity: Activity) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
ActivityCompat.requestPermissions(activity, permissionsArray, requestCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun handlePermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
|
||||||
|
if (this.requestCode == requestCode) {
|
||||||
|
val allGranted = grantResults.all { it == PackageManager.PERMISSION_GRANTED }
|
||||||
|
if (allGranted) {
|
||||||
|
listener.onPermissionGranted()
|
||||||
|
} else {
|
||||||
|
listener.onPermissionDenied()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
package com.ejada.hmg.PermissionManager
|
||||||
|
|
||||||
|
// PermissionResultReceiver.kt
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
|
||||||
|
class PermissionResultReceiver(
|
||||||
|
private val callback: (Boolean) -> Unit
|
||||||
|
) : BroadcastReceiver() {
|
||||||
|
override fun onReceive(context: Context?, intent: Intent?) {
|
||||||
|
val granted = intent?.getBooleanExtra("PERMISSION_GRANTED", false) ?: false
|
||||||
|
callback(granted)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
package com.ejada.hmg
|
||||||
|
|
||||||
|
import com.ejada.hmg.MainActivity
|
||||||
|
import android.os.Build
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import com.ejada.hmg.penguin.PenguinView
|
||||||
|
import io.flutter.embedding.engine.FlutterEngine
|
||||||
|
import io.flutter.plugin.common.MethodCall
|
||||||
|
import io.flutter.plugin.common.MethodChannel
|
||||||
|
|
||||||
|
class PenguinInPlatformBridge(
|
||||||
|
private var flutterEngine: FlutterEngine,
|
||||||
|
private var mainActivity: MainActivity
|
||||||
|
) {
|
||||||
|
|
||||||
|
private lateinit var channel: MethodChannel
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val CHANNEL = "launch_penguin_ui"
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
fun create() {
|
||||||
|
channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
|
||||||
|
channel.setMethodCallHandler { call: MethodCall, result: MethodChannel.Result ->
|
||||||
|
when (call.method) {
|
||||||
|
"launchPenguin" -> {
|
||||||
|
print("the platform channel is being called")
|
||||||
|
val args = call.arguments as Map<String, Any>?
|
||||||
|
Log.d("TAG", "configureFlutterEngine: $args")
|
||||||
|
println("args")
|
||||||
|
args?.let {
|
||||||
|
PenguinView(
|
||||||
|
mainActivity,
|
||||||
|
100,
|
||||||
|
args,
|
||||||
|
flutterEngine.dartExecutor.binaryMessenger,
|
||||||
|
activity = mainActivity,
|
||||||
|
channel
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
result.notImplemented()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
package com.ejada.hmg.penguin
|
||||||
|
|
||||||
|
enum class PenguinMethod {
|
||||||
|
// initializePenguin("initializePenguin"),
|
||||||
|
// configurePenguin("configurePenguin"),
|
||||||
|
// showPenguinUI("showPenguinUI"),
|
||||||
|
// onPenNavUIDismiss("onPenNavUIDismiss"),
|
||||||
|
// onReportIssue("onReportIssue"),
|
||||||
|
// onPenNavSuccess("onPenNavSuccess"),
|
||||||
|
onPenNavInitializationError // onLocationOffCampus("onLocationOffCampus"),
|
||||||
|
// navigateToPOI("navigateToPOI"),
|
||||||
|
// openSharedLocation("openSharedLocation");
|
||||||
|
}
|
||||||
@ -0,0 +1,97 @@
|
|||||||
|
package com.ejada.hmg.penguin
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import com.peng.pennavmap.PlugAndPlaySDK
|
||||||
|
import com.peng.pennavmap.connections.ApiController
|
||||||
|
import com.peng.pennavmap.interfaces.RefIdDelegate
|
||||||
|
import com.peng.pennavmap.models.TokenModel
|
||||||
|
import com.peng.pennavmap.models.postmodels.PostToken
|
||||||
|
import com.peng.pennavmap.utils.AppSharedData
|
||||||
|
import okhttp3.ResponseBody
|
||||||
|
import retrofit2.Call
|
||||||
|
import retrofit2.Callback
|
||||||
|
import retrofit2.Response
|
||||||
|
import android.util.Log
|
||||||
|
|
||||||
|
|
||||||
|
class PenguinNavigator() {
|
||||||
|
|
||||||
|
fun navigateTo(mContext: Context, refID: String, delegate: RefIdDelegate,clientID : String,clientKey : String ) {
|
||||||
|
val postToken = PostToken(clientID, clientKey)
|
||||||
|
getToken(mContext, postToken, object : RefIdDelegate {
|
||||||
|
override fun onRefByIDSuccess(PoiId: String?) {
|
||||||
|
Log.e("navigateTo", "PoiId is+++++++ $PoiId")
|
||||||
|
|
||||||
|
PlugAndPlaySDK.navigateTo(mContext, refID, object : RefIdDelegate {
|
||||||
|
override fun onRefByIDSuccess(PoiId: String?) {
|
||||||
|
Log.e("navigateTo", "PoiId 2is+++++++ $PoiId")
|
||||||
|
|
||||||
|
delegate.onRefByIDSuccess(refID)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onGetByRefIDError(error: String?) {
|
||||||
|
delegate.onRefByIDSuccess(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onGetByRefIDError(error: String?) {
|
||||||
|
delegate.onRefByIDSuccess(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getToken(mContext: Context, postToken: PostToken?, apiTokenCallBack: RefIdDelegate) {
|
||||||
|
try {
|
||||||
|
// Create the API call
|
||||||
|
val purposesCall: Call<ResponseBody> = ApiController.getInstance(mContext)
|
||||||
|
.apiMethods
|
||||||
|
.getToken(postToken)
|
||||||
|
|
||||||
|
// Enqueue the call for asynchronous execution
|
||||||
|
purposesCall.enqueue(object : Callback<ResponseBody?> {
|
||||||
|
override fun onResponse(
|
||||||
|
call: Call<ResponseBody?>,
|
||||||
|
response: Response<ResponseBody?>
|
||||||
|
) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
try {
|
||||||
|
response.body()?.use { responseBody ->
|
||||||
|
val responseBodyString: String = responseBody.string() // Use `string()` to get the actual response content
|
||||||
|
if (responseBodyString.isNotEmpty()) {
|
||||||
|
val tokenModel = Gson().fromJson(responseBodyString, TokenModel::class.java)
|
||||||
|
if (tokenModel != null && tokenModel.token != null) {
|
||||||
|
AppSharedData.apiToken = tokenModel.token
|
||||||
|
apiTokenCallBack.onRefByIDSuccess(tokenModel.token)
|
||||||
|
} else {
|
||||||
|
apiTokenCallBack.onGetByRefIDError("Failed to parse token model")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
apiTokenCallBack.onGetByRefIDError("Response body is empty")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
apiTokenCallBack.onGetByRefIDError("An error occurred: ${e.message}")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
apiTokenCallBack.onGetByRefIDError("Unsuccessful response: " + response.code())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(call: Call<ResponseBody?>, t: Throwable) {
|
||||||
|
apiTokenCallBack.onGetByRefIDError(t.message)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (error: Exception) {
|
||||||
|
apiTokenCallBack.onGetByRefIDError("Exception during API call: $error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,321 @@
|
|||||||
|
package com.ejada.hmg.penguin
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Context.RECEIVER_EXPORTED
|
||||||
|
import android.content.IntentFilter
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.os.Build
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.RelativeLayout
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import com.ejada.hmg.PermissionManager.PermissionHelper
|
||||||
|
import com.ejada.hmg.PermissionManager.PermissionManager
|
||||||
|
import com.ejada.hmg.PermissionManager.PermissionResultReceiver
|
||||||
|
import com.ejada.hmg.MainActivity
|
||||||
|
import com.peng.pennavmap.PlugAndPlayConfiguration
|
||||||
|
import com.peng.pennavmap.PlugAndPlaySDK
|
||||||
|
import com.peng.pennavmap.enums.InitializationErrorType
|
||||||
|
import com.peng.pennavmap.interfaces.PenNavUIDelegate
|
||||||
|
import com.peng.pennavmap.utils.Languages
|
||||||
|
import io.flutter.plugin.common.BinaryMessenger
|
||||||
|
import io.flutter.plugin.common.MethodCall
|
||||||
|
import io.flutter.plugin.common.MethodChannel
|
||||||
|
import io.flutter.plugin.platform.PlatformView
|
||||||
|
import com.ejada.hmg.penguin.PenguinNavigator
|
||||||
|
import com.peng.pennavmap.interfaces.PIEventsDelegate
|
||||||
|
import com.peng.pennavmap.interfaces.PILocationDelegate
|
||||||
|
import com.peng.pennavmap.interfaces.RefIdDelegate
|
||||||
|
import com.peng.pennavmap.models.PIReportIssue
|
||||||
|
/**
|
||||||
|
* Custom PlatformView for displaying Penguin UI components within a Flutter app.
|
||||||
|
* Implements `PlatformView` for rendering the view, `MethodChannel.MethodCallHandler` for handling method calls,
|
||||||
|
* and `PenNavUIDelegate` for handling SDK events.
|
||||||
|
*/
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
internal class PenguinView(
|
||||||
|
context: Context,
|
||||||
|
id: Int,
|
||||||
|
val creationParams: Map<String, Any>,
|
||||||
|
messenger: BinaryMessenger,
|
||||||
|
activity: MainActivity,
|
||||||
|
val channel: MethodChannel
|
||||||
|
) : PlatformView, MethodChannel.MethodCallHandler, PenNavUIDelegate {
|
||||||
|
// The layout for displaying the Penguin UI
|
||||||
|
private val mapLayout: RelativeLayout = RelativeLayout(context)
|
||||||
|
private val _context: Context = context
|
||||||
|
|
||||||
|
private val permissionResultReceiver: PermissionResultReceiver
|
||||||
|
private val permissionIntentFilter = IntentFilter("PERMISSION_RESULT_ACTION")
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
const val PERMISSIONS_REQUEST_CODE = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
private lateinit var permissionManager: PermissionManager
|
||||||
|
|
||||||
|
// Reference to the main activity
|
||||||
|
private var _activity: Activity = activity
|
||||||
|
|
||||||
|
private lateinit var mContext: Context
|
||||||
|
|
||||||
|
lateinit var navigator: PenguinNavigator
|
||||||
|
|
||||||
|
init {
|
||||||
|
// Set layout parameters for the mapLayout
|
||||||
|
mapLayout.layoutParams = ViewGroup.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
|
)
|
||||||
|
|
||||||
|
mContext = context
|
||||||
|
|
||||||
|
|
||||||
|
permissionResultReceiver = PermissionResultReceiver { granted ->
|
||||||
|
if (granted) {
|
||||||
|
onPermissionsGranted()
|
||||||
|
} else {
|
||||||
|
onPermissionsDenied()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
mContext.registerReceiver(
|
||||||
|
permissionResultReceiver,
|
||||||
|
permissionIntentFilter,
|
||||||
|
RECEIVER_EXPORTED
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
mContext.registerReceiver(
|
||||||
|
permissionResultReceiver,
|
||||||
|
permissionIntentFilter,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the background color of the layout
|
||||||
|
mapLayout.setBackgroundColor(Color.RED)
|
||||||
|
|
||||||
|
permissionManager = PermissionManager(
|
||||||
|
context = mContext,
|
||||||
|
listener = object : PermissionManager.PermissionListener {
|
||||||
|
override fun onPermissionGranted() {
|
||||||
|
// Handle permissions granted
|
||||||
|
onPermissionsGranted()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPermissionDenied() {
|
||||||
|
// Handle permissions denied
|
||||||
|
onPermissionsDenied()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
requestCode = PERMISSIONS_REQUEST_CODE,
|
||||||
|
*PermissionHelper.getRequiredPermissions()
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!permissionManager.arePermissionsGranted()) {
|
||||||
|
permissionManager.requestPermissions(_activity)
|
||||||
|
} else {
|
||||||
|
// Permissions already granted
|
||||||
|
permissionManager.listener.onPermissionGranted()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onPermissionsGranted() {
|
||||||
|
// Handle the actions when permissions are granted
|
||||||
|
Log.d("PermissionsResult", "onPermissionsGranted")
|
||||||
|
// Register the platform view factory for creating custom views
|
||||||
|
|
||||||
|
// Initialize the Penguin SDK
|
||||||
|
initPenguin()
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onPermissionsDenied() {
|
||||||
|
// Handle the actions when permissions are denied
|
||||||
|
Log.d("PermissionsResult", "onPermissionsDenied")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the view associated with this PlatformView.
|
||||||
|
*
|
||||||
|
* @return The main view for this PlatformView.
|
||||||
|
*/
|
||||||
|
override fun getView(): View {
|
||||||
|
return mapLayout
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleans up resources associated with this PlatformView.
|
||||||
|
*/
|
||||||
|
override fun dispose() {
|
||||||
|
// Cleanup code if needed
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles method calls from Dart code.
|
||||||
|
*
|
||||||
|
* @param call The method call from Dart.
|
||||||
|
* @param result The result callback to send responses back to Dart.
|
||||||
|
*/
|
||||||
|
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
|
||||||
|
// Handle method calls from Dart code here
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the Penguin SDK with custom configuration and delegates.
|
||||||
|
*/
|
||||||
|
private fun initPenguin() {
|
||||||
|
navigator = PenguinNavigator()
|
||||||
|
// Configure the PlugAndPlaySDK
|
||||||
|
val language = when (creationParams["languageCode"] as String) {
|
||||||
|
"ar" -> Languages.ar
|
||||||
|
"en" -> Languages.en
|
||||||
|
else -> {
|
||||||
|
Languages.en
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.d(
|
||||||
|
"TAG",
|
||||||
|
"initPenguin: ${Languages.getLanguageEnum(creationParams["languageCode"] as String)}"
|
||||||
|
)
|
||||||
|
PlugAndPlaySDK.configuration = PlugAndPlayConfiguration.Builder()
|
||||||
|
.setBaseUrl(
|
||||||
|
creationParams["dataURL"] as String,
|
||||||
|
creationParams["positionURL"] as String
|
||||||
|
)
|
||||||
|
.setServiceName(
|
||||||
|
creationParams["dataServiceName"] as String,
|
||||||
|
creationParams["positionServiceName"] as String
|
||||||
|
)
|
||||||
|
.setClientData(
|
||||||
|
creationParams["clientID"] as String,
|
||||||
|
creationParams["clientKey"] as String
|
||||||
|
)
|
||||||
|
.setUserName(creationParams["username"] as String)
|
||||||
|
// .setLanguageID(Languages.en)
|
||||||
|
.setLanguageID(language)
|
||||||
|
.setSimulationModeEnabled(creationParams["isSimulationModeEnabled"] as Boolean)
|
||||||
|
.setEnableBackButton(true)
|
||||||
|
// .setDeepLinkData("deeplink")
|
||||||
|
.setCustomizeColor("#2CA0AF")
|
||||||
|
.setDeepLinkSchema("")
|
||||||
|
.setIsEnableReportIssue(true)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
// Set location delegate to handle location updates
|
||||||
|
// PlugAndPlaySDK.setPiLocationDelegate {
|
||||||
|
// Example code to handle location updates
|
||||||
|
// Uncomment and modify as needed
|
||||||
|
// if (location.size() > 0)
|
||||||
|
// Toast.makeText(_context, "Location Info Latitude: ${location[0]}, Longitude: ${location[1]}", Toast.LENGTH_SHORT).show()
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Set events delegate for reporting issues
|
||||||
|
// PlugAndPlaySDK.setPiEventsDelegate(new PIEventsDelegate() {
|
||||||
|
// @Override
|
||||||
|
// public void onReportIssue(PIReportIssue issue) {
|
||||||
|
// Log.e("Issue Reported: ", issue.getReportType());
|
||||||
|
// }
|
||||||
|
// // Implement issue reporting logic here }
|
||||||
|
// @Override
|
||||||
|
// public void onSharedLocation(String link) {
|
||||||
|
// // Implement Shared location logic here
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
|
||||||
|
// Start the Penguin SDK
|
||||||
|
PlugAndPlaySDK.start(mContext, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigates to the specified reference ID.
|
||||||
|
*
|
||||||
|
* @param refID The reference ID to navigate to.
|
||||||
|
*/
|
||||||
|
fun navigateTo(refID: String) {
|
||||||
|
try {
|
||||||
|
if (refID.isBlank()) {
|
||||||
|
Log.e("navigateTo", "Invalid refID: The reference ID is blank.")
|
||||||
|
}
|
||||||
|
// referenceId = refID
|
||||||
|
navigator.navigateTo(mContext, refID,object : RefIdDelegate {
|
||||||
|
override fun onRefByIDSuccess(PoiId: String?) {
|
||||||
|
Log.e("navigateTo", "PoiId is penguin view+++++++ $PoiId")
|
||||||
|
|
||||||
|
// channelFlutter.invokeMethod(
|
||||||
|
// PenguinMethod.navigateToPOI.name,
|
||||||
|
// "navigateTo Success"
|
||||||
|
// )
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onGetByRefIDError(error: String?) {
|
||||||
|
Log.e("navigateTo", "error is penguin view+++++++ $error")
|
||||||
|
|
||||||
|
// channelFlutter.invokeMethod(
|
||||||
|
// PenguinMethod.navigateToPOI.name,
|
||||||
|
// "navigateTo Failed: Invalid refID"
|
||||||
|
// )
|
||||||
|
}
|
||||||
|
} , creationParams["clientID"] as String, creationParams["clientKey"] as String )
|
||||||
|
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("navigateTo", "Exception occurred during navigation: ${e.message}", e)
|
||||||
|
// channelFlutter.invokeMethod(
|
||||||
|
// PenguinMethod.navigateToPOI.name,
|
||||||
|
// "Failed: Exception - ${e.message}"
|
||||||
|
// )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when Penguin UI setup is successful.
|
||||||
|
*
|
||||||
|
* @param warningCode Optional warning code received from the SDK.
|
||||||
|
*/
|
||||||
|
override fun onPenNavSuccess(warningCode: String?) {
|
||||||
|
val clinicId = creationParams["clinicID"] as String
|
||||||
|
|
||||||
|
if(clinicId.isEmpty()) return
|
||||||
|
|
||||||
|
navigateTo(clinicId)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when there is an initialization error with Penguin UI.
|
||||||
|
*
|
||||||
|
* @param description Description of the error.
|
||||||
|
* @param errorType Type of initialization error.
|
||||||
|
*/
|
||||||
|
override fun onPenNavInitializationError(
|
||||||
|
description: String?,
|
||||||
|
errorType: InitializationErrorType?
|
||||||
|
) {
|
||||||
|
val arguments: Map<String, Any?> = mapOf(
|
||||||
|
"description" to description,
|
||||||
|
"type" to errorType?.name
|
||||||
|
)
|
||||||
|
|
||||||
|
channel.invokeMethod(PenguinMethod.onPenNavInitializationError.name, arguments)
|
||||||
|
Toast.makeText(mContext, "Navigation Error: $description", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when Penguin UI is dismissed.
|
||||||
|
*/
|
||||||
|
override fun onPenNavUIDismiss() {
|
||||||
|
// Handle UI dismissal if needed
|
||||||
|
try {
|
||||||
|
mContext.unregisterReceiver(permissionResultReceiver)
|
||||||
|
dispose();
|
||||||
|
} catch (e: IllegalArgumentException) {
|
||||||
|
Log.e("PenguinView", "Receiver not registered: $e")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1021 B |
|
After Width: | Height: | Size: 180 B |
|
After Width: | Height: | Size: 1.0 KiB |
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/main"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context="com.cloud.diplomaticquarterapp.whatsapp.WhatsAppCodeActivity">
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:layout_gravity="center_horizontal">
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/publisher_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#FF9800" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:layout_gravity="center_horizontal">
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/subscriber_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#3F51B5" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:text="Remote"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
@ -0,0 +1,3 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
tools:keep="@drawable/*,@raw/slow_spring_board" />
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name">HMG Patient App</string>
|
||||||
|
|
||||||
|
<string name="geofence_unknown_error">
|
||||||
|
Unknown error: the Geofence service is not available now.
|
||||||
|
</string>
|
||||||
|
<string name="geofence_not_available">
|
||||||
|
Geofence service is not available now. Go to Settings>Location>Mode and choose High accuracy.
|
||||||
|
</string>
|
||||||
|
<string name="geofence_too_many_geofences">
|
||||||
|
Your app has registered too many geofences.
|
||||||
|
</string>
|
||||||
|
<string name="geofence_too_many_pending_intents">
|
||||||
|
You have provided too many PendingIntents to the addGeofences() call.
|
||||||
|
</string>
|
||||||
|
<string name="GEOFENCE_INSUFFICIENT_LOCATION_PERMISSION">
|
||||||
|
App do not have permission to access location service.
|
||||||
|
</string>
|
||||||
|
<string name="GEOFENCE_REQUEST_TOO_FREQUENT">
|
||||||
|
Geofence requests happened too frequently.
|
||||||
|
</string>
|
||||||
|
<string name="mapbox_access_token" translatable="false">sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg</string>
|
||||||
|
</resources>
|
||||||
@ -0,0 +1,505 @@
|
|||||||
|
PODS:
|
||||||
|
- amazon_payfort (1.1.4):
|
||||||
|
- Flutter
|
||||||
|
- PayFortSDK
|
||||||
|
- audio_session (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- barcode_scan2 (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- MTBBarcodeScanner
|
||||||
|
- SwiftProtobuf
|
||||||
|
- connectivity_plus (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- device_calendar (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- device_info_plus (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- DKImagePickerController/Core (4.3.9):
|
||||||
|
- DKImagePickerController/ImageDataManager
|
||||||
|
- DKImagePickerController/Resource
|
||||||
|
- DKImagePickerController/ImageDataManager (4.3.9)
|
||||||
|
- DKImagePickerController/PhotoGallery (4.3.9):
|
||||||
|
- DKImagePickerController/Core
|
||||||
|
- DKPhotoGallery
|
||||||
|
- DKImagePickerController/Resource (4.3.9)
|
||||||
|
- DKPhotoGallery (0.0.19):
|
||||||
|
- DKPhotoGallery/Core (= 0.0.19)
|
||||||
|
- DKPhotoGallery/Model (= 0.0.19)
|
||||||
|
- DKPhotoGallery/Preview (= 0.0.19)
|
||||||
|
- DKPhotoGallery/Resource (= 0.0.19)
|
||||||
|
- SDWebImage
|
||||||
|
- SwiftyGif
|
||||||
|
- DKPhotoGallery/Core (0.0.19):
|
||||||
|
- DKPhotoGallery/Model
|
||||||
|
- DKPhotoGallery/Preview
|
||||||
|
- SDWebImage
|
||||||
|
- SwiftyGif
|
||||||
|
- DKPhotoGallery/Model (0.0.19):
|
||||||
|
- SDWebImage
|
||||||
|
- SwiftyGif
|
||||||
|
- DKPhotoGallery/Preview (0.0.19):
|
||||||
|
- DKPhotoGallery/Model
|
||||||
|
- DKPhotoGallery/Resource
|
||||||
|
- SDWebImage
|
||||||
|
- SwiftyGif
|
||||||
|
- DKPhotoGallery/Resource (0.0.19):
|
||||||
|
- SDWebImage
|
||||||
|
- SwiftyGif
|
||||||
|
- file_picker (0.0.1):
|
||||||
|
- DKImagePickerController/PhotoGallery
|
||||||
|
- Flutter
|
||||||
|
- Firebase/Analytics (11.15.0):
|
||||||
|
- Firebase/Core
|
||||||
|
- Firebase/Core (11.15.0):
|
||||||
|
- Firebase/CoreOnly
|
||||||
|
- FirebaseAnalytics (~> 11.15.0)
|
||||||
|
- Firebase/CoreOnly (11.15.0):
|
||||||
|
- FirebaseCore (~> 11.15.0)
|
||||||
|
- Firebase/Messaging (11.15.0):
|
||||||
|
- Firebase/CoreOnly
|
||||||
|
- FirebaseMessaging (~> 11.15.0)
|
||||||
|
- firebase_analytics (11.6.0):
|
||||||
|
- Firebase/Analytics (= 11.15.0)
|
||||||
|
- firebase_core
|
||||||
|
- Flutter
|
||||||
|
- firebase_core (3.15.2):
|
||||||
|
- Firebase/CoreOnly (= 11.15.0)
|
||||||
|
- Flutter
|
||||||
|
- firebase_messaging (15.2.10):
|
||||||
|
- Firebase/Messaging (= 11.15.0)
|
||||||
|
- firebase_core
|
||||||
|
- Flutter
|
||||||
|
- FirebaseAnalytics (11.15.0):
|
||||||
|
- FirebaseAnalytics/Default (= 11.15.0)
|
||||||
|
- FirebaseCore (~> 11.15.0)
|
||||||
|
- FirebaseInstallations (~> 11.0)
|
||||||
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
||||||
|
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
||||||
|
- GoogleUtilities/Network (~> 8.1)
|
||||||
|
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
||||||
|
- nanopb (~> 3.30910.0)
|
||||||
|
- FirebaseAnalytics/Default (11.15.0):
|
||||||
|
- FirebaseCore (~> 11.15.0)
|
||||||
|
- FirebaseInstallations (~> 11.0)
|
||||||
|
- GoogleAppMeasurement/Default (= 11.15.0)
|
||||||
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
||||||
|
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
||||||
|
- GoogleUtilities/Network (~> 8.1)
|
||||||
|
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
||||||
|
- nanopb (~> 3.30910.0)
|
||||||
|
- FirebaseCore (11.15.0):
|
||||||
|
- FirebaseCoreInternal (~> 11.15.0)
|
||||||
|
- GoogleUtilities/Environment (~> 8.1)
|
||||||
|
- GoogleUtilities/Logger (~> 8.1)
|
||||||
|
- FirebaseCoreInternal (11.15.0):
|
||||||
|
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
||||||
|
- FirebaseInstallations (11.15.0):
|
||||||
|
- FirebaseCore (~> 11.15.0)
|
||||||
|
- GoogleUtilities/Environment (~> 8.1)
|
||||||
|
- GoogleUtilities/UserDefaults (~> 8.1)
|
||||||
|
- PromisesObjC (~> 2.4)
|
||||||
|
- FirebaseMessaging (11.15.0):
|
||||||
|
- FirebaseCore (~> 11.15.0)
|
||||||
|
- FirebaseInstallations (~> 11.0)
|
||||||
|
- GoogleDataTransport (~> 10.0)
|
||||||
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
||||||
|
- GoogleUtilities/Environment (~> 8.1)
|
||||||
|
- GoogleUtilities/Reachability (~> 8.1)
|
||||||
|
- GoogleUtilities/UserDefaults (~> 8.1)
|
||||||
|
- nanopb (~> 3.30910.0)
|
||||||
|
- FLAnimatedImage (1.0.17)
|
||||||
|
- Flutter (1.0.0)
|
||||||
|
- flutter_inappwebview_ios (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- flutter_inappwebview_ios/Core (= 0.0.1)
|
||||||
|
- OrderedSet (~> 6.0.3)
|
||||||
|
- flutter_inappwebview_ios/Core (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- OrderedSet (~> 6.0.3)
|
||||||
|
- flutter_ios_voip_kit_karmm (0.8.0):
|
||||||
|
- Flutter
|
||||||
|
- flutter_local_notifications (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- flutter_nfc_kit (3.6.0):
|
||||||
|
- Flutter
|
||||||
|
- flutter_zoom_videosdk (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- ZoomVideoSDK/CptShare (= 2.3.0)
|
||||||
|
- ZoomVideoSDK/zm_annoter_dynamic (= 2.3.0)
|
||||||
|
- ZoomVideoSDK/zoomcml (= 2.3.0)
|
||||||
|
- ZoomVideoSDK/ZoomVideoSDK (= 2.3.0)
|
||||||
|
- fluttertoast (0.0.2):
|
||||||
|
- Flutter
|
||||||
|
- geolocator_apple (1.2.0):
|
||||||
|
- Flutter
|
||||||
|
- FlutterMacOS
|
||||||
|
- Google-Maps-iOS-Utils (5.0.0):
|
||||||
|
- GoogleMaps (~> 8.0)
|
||||||
|
- google_maps_flutter_ios (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- Google-Maps-iOS-Utils (< 7.0, >= 5.0)
|
||||||
|
- GoogleMaps (< 10.0, >= 8.4)
|
||||||
|
- GoogleAdsOnDeviceConversion (2.1.0):
|
||||||
|
- GoogleUtilities/Logger (~> 8.1)
|
||||||
|
- GoogleUtilities/Network (~> 8.1)
|
||||||
|
- nanopb (~> 3.30910.0)
|
||||||
|
- GoogleAppMeasurement/Core (11.15.0):
|
||||||
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
||||||
|
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
||||||
|
- GoogleUtilities/Network (~> 8.1)
|
||||||
|
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
||||||
|
- nanopb (~> 3.30910.0)
|
||||||
|
- GoogleAppMeasurement/Default (11.15.0):
|
||||||
|
- GoogleAdsOnDeviceConversion (= 2.1.0)
|
||||||
|
- GoogleAppMeasurement/Core (= 11.15.0)
|
||||||
|
- GoogleAppMeasurement/IdentitySupport (= 11.15.0)
|
||||||
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
||||||
|
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
||||||
|
- GoogleUtilities/Network (~> 8.1)
|
||||||
|
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
||||||
|
- nanopb (~> 3.30910.0)
|
||||||
|
- GoogleAppMeasurement/IdentitySupport (11.15.0):
|
||||||
|
- GoogleAppMeasurement/Core (= 11.15.0)
|
||||||
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
||||||
|
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
||||||
|
- GoogleUtilities/Network (~> 8.1)
|
||||||
|
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
||||||
|
- nanopb (~> 3.30910.0)
|
||||||
|
- GoogleDataTransport (10.1.0):
|
||||||
|
- nanopb (~> 3.30910.0)
|
||||||
|
- PromisesObjC (~> 2.4)
|
||||||
|
- GoogleMaps (8.4.0):
|
||||||
|
- GoogleMaps/Maps (= 8.4.0)
|
||||||
|
- GoogleMaps/Base (8.4.0)
|
||||||
|
- GoogleMaps/Maps (8.4.0):
|
||||||
|
- GoogleMaps/Base
|
||||||
|
- GoogleUtilities/AppDelegateSwizzler (8.1.0):
|
||||||
|
- GoogleUtilities/Environment
|
||||||
|
- GoogleUtilities/Logger
|
||||||
|
- GoogleUtilities/Network
|
||||||
|
- GoogleUtilities/Privacy
|
||||||
|
- GoogleUtilities/Environment (8.1.0):
|
||||||
|
- GoogleUtilities/Privacy
|
||||||
|
- GoogleUtilities/Logger (8.1.0):
|
||||||
|
- GoogleUtilities/Environment
|
||||||
|
- GoogleUtilities/Privacy
|
||||||
|
- GoogleUtilities/MethodSwizzler (8.1.0):
|
||||||
|
- GoogleUtilities/Logger
|
||||||
|
- GoogleUtilities/Privacy
|
||||||
|
- GoogleUtilities/Network (8.1.0):
|
||||||
|
- GoogleUtilities/Logger
|
||||||
|
- "GoogleUtilities/NSData+zlib"
|
||||||
|
- GoogleUtilities/Privacy
|
||||||
|
- GoogleUtilities/Reachability
|
||||||
|
- "GoogleUtilities/NSData+zlib (8.1.0)":
|
||||||
|
- GoogleUtilities/Privacy
|
||||||
|
- GoogleUtilities/Privacy (8.1.0)
|
||||||
|
- GoogleUtilities/Reachability (8.1.0):
|
||||||
|
- GoogleUtilities/Logger
|
||||||
|
- GoogleUtilities/Privacy
|
||||||
|
- GoogleUtilities/UserDefaults (8.1.0):
|
||||||
|
- GoogleUtilities/Logger
|
||||||
|
- GoogleUtilities/Privacy
|
||||||
|
- health (13.1.4):
|
||||||
|
- Flutter
|
||||||
|
- image_picker_ios (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- just_audio (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- FlutterMacOS
|
||||||
|
- local_auth_darwin (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- FlutterMacOS
|
||||||
|
- manage_calendar_events (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- MapboxCommon (23.11.0)
|
||||||
|
- MapboxCoreMaps (10.19.1):
|
||||||
|
- MapboxCommon (~> 23.11)
|
||||||
|
- MapboxCoreNavigation (2.19.0):
|
||||||
|
- MapboxDirections (~> 2.14)
|
||||||
|
- MapboxNavigationNative (< 207.0.0, >= 206.0.1)
|
||||||
|
- MapboxDirections (2.14.2):
|
||||||
|
- Polyline (~> 5.0)
|
||||||
|
- Turf (~> 2.8.0)
|
||||||
|
- MapboxMaps (10.19.0):
|
||||||
|
- MapboxCommon (= 23.11.0)
|
||||||
|
- MapboxCoreMaps (= 10.19.1)
|
||||||
|
- MapboxMobileEvents (= 2.0.0)
|
||||||
|
- Turf (= 2.8.0)
|
||||||
|
- MapboxMobileEvents (2.0.0)
|
||||||
|
- MapboxNavigation (2.19.0):
|
||||||
|
- MapboxCoreNavigation (= 2.19.0)
|
||||||
|
- MapboxMaps (~> 10.18)
|
||||||
|
- MapboxSpeech (~> 2.0)
|
||||||
|
- Solar-dev (~> 3.0)
|
||||||
|
- MapboxNavigationNative (206.2.2):
|
||||||
|
- MapboxCommon (~> 23.10)
|
||||||
|
- MapboxSpeech (2.1.1)
|
||||||
|
- maps_launcher (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- MTBBarcodeScanner (5.0.11)
|
||||||
|
- nanopb (3.30910.0):
|
||||||
|
- nanopb/decode (= 3.30910.0)
|
||||||
|
- nanopb/encode (= 3.30910.0)
|
||||||
|
- nanopb/decode (3.30910.0)
|
||||||
|
- nanopb/encode (3.30910.0)
|
||||||
|
- network_info_plus (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- open_filex (0.0.2):
|
||||||
|
- Flutter
|
||||||
|
- OrderedSet (6.0.3)
|
||||||
|
- package_info_plus (0.4.5):
|
||||||
|
- Flutter
|
||||||
|
- path_provider_foundation (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- FlutterMacOS
|
||||||
|
- PayFortSDK (3.2.1)
|
||||||
|
- permission_handler_apple (9.3.0):
|
||||||
|
- Flutter
|
||||||
|
- Polyline (5.1.0)
|
||||||
|
- PromisesObjC (2.4.0)
|
||||||
|
- SDWebImage (5.21.2):
|
||||||
|
- SDWebImage/Core (= 5.21.2)
|
||||||
|
- SDWebImage/Core (5.21.2)
|
||||||
|
- share_plus (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- shared_preferences_foundation (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- FlutterMacOS
|
||||||
|
- Solar-dev (3.0.1)
|
||||||
|
- sqflite_darwin (0.0.4):
|
||||||
|
- Flutter
|
||||||
|
- FlutterMacOS
|
||||||
|
- SwiftProtobuf (1.31.0)
|
||||||
|
- SwiftyGif (5.4.5)
|
||||||
|
- Turf (2.8.0)
|
||||||
|
- url_launcher_ios (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- ZoomVideoSDK/CptShare (2.3.0)
|
||||||
|
- ZoomVideoSDK/zm_annoter_dynamic (2.3.0)
|
||||||
|
- ZoomVideoSDK/zoomcml (2.3.0)
|
||||||
|
- ZoomVideoSDK/ZoomVideoSDK (2.3.0)
|
||||||
|
|
||||||
|
DEPENDENCIES:
|
||||||
|
- amazon_payfort (from `.symlinks/plugins/amazon_payfort/ios`)
|
||||||
|
- audio_session (from `.symlinks/plugins/audio_session/ios`)
|
||||||
|
- barcode_scan2 (from `.symlinks/plugins/barcode_scan2/ios`)
|
||||||
|
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
|
||||||
|
- device_calendar (from `.symlinks/plugins/device_calendar/ios`)
|
||||||
|
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
||||||
|
- file_picker (from `.symlinks/plugins/file_picker/ios`)
|
||||||
|
- firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`)
|
||||||
|
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
|
||||||
|
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
|
||||||
|
- FLAnimatedImage
|
||||||
|
- Flutter (from `Flutter`)
|
||||||
|
- flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`)
|
||||||
|
- flutter_ios_voip_kit_karmm (from `.symlinks/plugins/flutter_ios_voip_kit_karmm/ios`)
|
||||||
|
- flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
|
||||||
|
- flutter_nfc_kit (from `.symlinks/plugins/flutter_nfc_kit/ios`)
|
||||||
|
- flutter_zoom_videosdk (from `.symlinks/plugins/flutter_zoom_videosdk/ios`)
|
||||||
|
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
|
||||||
|
- geolocator_apple (from `.symlinks/plugins/geolocator_apple/darwin`)
|
||||||
|
- google_maps_flutter_ios (from `.symlinks/plugins/google_maps_flutter_ios/ios`)
|
||||||
|
- health (from `.symlinks/plugins/health/ios`)
|
||||||
|
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
|
||||||
|
- just_audio (from `.symlinks/plugins/just_audio/darwin`)
|
||||||
|
- local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`)
|
||||||
|
- manage_calendar_events (from `.symlinks/plugins/manage_calendar_events/ios`)
|
||||||
|
- MapboxMaps (= 10.19.0)
|
||||||
|
- MapboxNavigation (= 2.19.0)
|
||||||
|
- maps_launcher (from `.symlinks/plugins/maps_launcher/ios`)
|
||||||
|
- network_info_plus (from `.symlinks/plugins/network_info_plus/ios`)
|
||||||
|
- open_filex (from `.symlinks/plugins/open_filex/ios`)
|
||||||
|
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||||
|
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
||||||
|
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
||||||
|
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
||||||
|
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||||
|
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
|
||||||
|
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||||
|
|
||||||
|
SPEC REPOS:
|
||||||
|
trunk:
|
||||||
|
- DKImagePickerController
|
||||||
|
- DKPhotoGallery
|
||||||
|
- Firebase
|
||||||
|
- FirebaseAnalytics
|
||||||
|
- FirebaseCore
|
||||||
|
- FirebaseCoreInternal
|
||||||
|
- FirebaseInstallations
|
||||||
|
- FirebaseMessaging
|
||||||
|
- FLAnimatedImage
|
||||||
|
- Google-Maps-iOS-Utils
|
||||||
|
- GoogleAdsOnDeviceConversion
|
||||||
|
- GoogleAppMeasurement
|
||||||
|
- GoogleDataTransport
|
||||||
|
- GoogleMaps
|
||||||
|
- GoogleUtilities
|
||||||
|
- MapboxCommon
|
||||||
|
- MapboxCoreMaps
|
||||||
|
- MapboxCoreNavigation
|
||||||
|
- MapboxDirections
|
||||||
|
- MapboxMaps
|
||||||
|
- MapboxMobileEvents
|
||||||
|
- MapboxNavigation
|
||||||
|
- MapboxNavigationNative
|
||||||
|
- MapboxSpeech
|
||||||
|
- MTBBarcodeScanner
|
||||||
|
- nanopb
|
||||||
|
- OrderedSet
|
||||||
|
- PayFortSDK
|
||||||
|
- Polyline
|
||||||
|
- PromisesObjC
|
||||||
|
- SDWebImage
|
||||||
|
- Solar-dev
|
||||||
|
- SwiftProtobuf
|
||||||
|
- SwiftyGif
|
||||||
|
- Turf
|
||||||
|
- ZoomVideoSDK
|
||||||
|
|
||||||
|
EXTERNAL SOURCES:
|
||||||
|
amazon_payfort:
|
||||||
|
:path: ".symlinks/plugins/amazon_payfort/ios"
|
||||||
|
audio_session:
|
||||||
|
:path: ".symlinks/plugins/audio_session/ios"
|
||||||
|
barcode_scan2:
|
||||||
|
:path: ".symlinks/plugins/barcode_scan2/ios"
|
||||||
|
connectivity_plus:
|
||||||
|
:path: ".symlinks/plugins/connectivity_plus/ios"
|
||||||
|
device_calendar:
|
||||||
|
:path: ".symlinks/plugins/device_calendar/ios"
|
||||||
|
device_info_plus:
|
||||||
|
:path: ".symlinks/plugins/device_info_plus/ios"
|
||||||
|
file_picker:
|
||||||
|
:path: ".symlinks/plugins/file_picker/ios"
|
||||||
|
firebase_analytics:
|
||||||
|
:path: ".symlinks/plugins/firebase_analytics/ios"
|
||||||
|
firebase_core:
|
||||||
|
:path: ".symlinks/plugins/firebase_core/ios"
|
||||||
|
firebase_messaging:
|
||||||
|
:path: ".symlinks/plugins/firebase_messaging/ios"
|
||||||
|
Flutter:
|
||||||
|
:path: Flutter
|
||||||
|
flutter_inappwebview_ios:
|
||||||
|
:path: ".symlinks/plugins/flutter_inappwebview_ios/ios"
|
||||||
|
flutter_ios_voip_kit_karmm:
|
||||||
|
:path: ".symlinks/plugins/flutter_ios_voip_kit_karmm/ios"
|
||||||
|
flutter_local_notifications:
|
||||||
|
:path: ".symlinks/plugins/flutter_local_notifications/ios"
|
||||||
|
flutter_nfc_kit:
|
||||||
|
:path: ".symlinks/plugins/flutter_nfc_kit/ios"
|
||||||
|
flutter_zoom_videosdk:
|
||||||
|
:path: ".symlinks/plugins/flutter_zoom_videosdk/ios"
|
||||||
|
fluttertoast:
|
||||||
|
:path: ".symlinks/plugins/fluttertoast/ios"
|
||||||
|
geolocator_apple:
|
||||||
|
:path: ".symlinks/plugins/geolocator_apple/darwin"
|
||||||
|
google_maps_flutter_ios:
|
||||||
|
:path: ".symlinks/plugins/google_maps_flutter_ios/ios"
|
||||||
|
health:
|
||||||
|
:path: ".symlinks/plugins/health/ios"
|
||||||
|
image_picker_ios:
|
||||||
|
:path: ".symlinks/plugins/image_picker_ios/ios"
|
||||||
|
just_audio:
|
||||||
|
:path: ".symlinks/plugins/just_audio/darwin"
|
||||||
|
local_auth_darwin:
|
||||||
|
:path: ".symlinks/plugins/local_auth_darwin/darwin"
|
||||||
|
manage_calendar_events:
|
||||||
|
:path: ".symlinks/plugins/manage_calendar_events/ios"
|
||||||
|
maps_launcher:
|
||||||
|
:path: ".symlinks/plugins/maps_launcher/ios"
|
||||||
|
network_info_plus:
|
||||||
|
:path: ".symlinks/plugins/network_info_plus/ios"
|
||||||
|
open_filex:
|
||||||
|
:path: ".symlinks/plugins/open_filex/ios"
|
||||||
|
package_info_plus:
|
||||||
|
:path: ".symlinks/plugins/package_info_plus/ios"
|
||||||
|
path_provider_foundation:
|
||||||
|
:path: ".symlinks/plugins/path_provider_foundation/darwin"
|
||||||
|
permission_handler_apple:
|
||||||
|
:path: ".symlinks/plugins/permission_handler_apple/ios"
|
||||||
|
share_plus:
|
||||||
|
:path: ".symlinks/plugins/share_plus/ios"
|
||||||
|
shared_preferences_foundation:
|
||||||
|
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
|
||||||
|
sqflite_darwin:
|
||||||
|
:path: ".symlinks/plugins/sqflite_darwin/darwin"
|
||||||
|
url_launcher_ios:
|
||||||
|
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
||||||
|
|
||||||
|
SPEC CHECKSUMS:
|
||||||
|
amazon_payfort: 4ad7a3413acc1c4c4022117a80d18fee23c572d3
|
||||||
|
audio_session: 9bb7f6c970f21241b19f5a3658097ae459681ba0
|
||||||
|
barcode_scan2: f80517f040989095c9b5067be77649bf6114442c
|
||||||
|
connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd
|
||||||
|
device_calendar: b55b2c5406cfba45c95a59f9059156daee1f74ed
|
||||||
|
device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe
|
||||||
|
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
|
||||||
|
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
|
||||||
|
file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
|
||||||
|
Firebase: d99ac19b909cd2c548339c2241ecd0d1599ab02e
|
||||||
|
firebase_analytics: 0e25ca1d4001ccedd40b4e5b74c0ec34e18f6425
|
||||||
|
firebase_core: 995454a784ff288be5689b796deb9e9fa3601818
|
||||||
|
firebase_messaging: f4a41dd102ac18b840eba3f39d67e77922d3f707
|
||||||
|
FirebaseAnalytics: 6433dfd311ba78084fc93bdfc145e8cb75740eae
|
||||||
|
FirebaseCore: efb3893e5b94f32b86e331e3bd6dadf18b66568e
|
||||||
|
FirebaseCoreInternal: 9afa45b1159304c963da48addb78275ef701c6b4
|
||||||
|
FirebaseInstallations: 317270fec08a5d418fdbc8429282238cab3ac843
|
||||||
|
FirebaseMessaging: 3b26e2cee503815e01c3701236b020aa9b576f09
|
||||||
|
FLAnimatedImage: bbf914596368867157cc71b38a8ec834b3eeb32b
|
||||||
|
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
|
||||||
|
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
|
||||||
|
flutter_ios_voip_kit_karmm: 371663476722afb631d5a13a39dee74c56c1abd0
|
||||||
|
flutter_local_notifications: a5a732f069baa862e728d839dd2ebb904737effb
|
||||||
|
flutter_nfc_kit: e1b71583eafd2c9650bc86844a7f2d185fb414f6
|
||||||
|
flutter_zoom_videosdk: db0f31b018783aa57f55ab0c94bc0abbe1127bae
|
||||||
|
fluttertoast: 2c67e14dce98bbdb200df9e1acf610d7a6264ea1
|
||||||
|
geolocator_apple: ab36aa0e8b7d7a2d7639b3b4e48308394e8cef5e
|
||||||
|
Google-Maps-iOS-Utils: 66d6de12be1ce6d3742a54661e7a79cb317a9321
|
||||||
|
google_maps_flutter_ios: 0291eb2aa252298a769b04d075e4a9d747ff7264
|
||||||
|
GoogleAdsOnDeviceConversion: 2be6297a4f048459e0ae17fad9bfd2844e10cf64
|
||||||
|
GoogleAppMeasurement: 700dce7541804bec33db590a5c496b663fbe2539
|
||||||
|
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
||||||
|
GoogleMaps: 8939898920281c649150e0af74aa291c60f2e77d
|
||||||
|
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
|
||||||
|
health: 32d2fbc7f26f9a2388d1a514ce168adbfa5bda65
|
||||||
|
image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
|
||||||
|
just_audio: 4e391f57b79cad2b0674030a00453ca5ce817eed
|
||||||
|
local_auth_darwin: d2e8c53ef0c4f43c646462e3415432c4dab3ae19
|
||||||
|
manage_calendar_events: fe1541069431af035ced925ebd9def8b4b271254
|
||||||
|
MapboxCommon: 119f3759f7dc9457f0695848108ab323eb643cb4
|
||||||
|
MapboxCoreMaps: ca17f67baced23f8c952166ac6314c35bad3f66c
|
||||||
|
MapboxCoreNavigation: 3be9990fae3ed732a101001746d0e3b4234ec023
|
||||||
|
MapboxDirections: d4fe7d43cff82aa0c15955d1b4563a5a01e2d4de
|
||||||
|
MapboxMaps: b7f29ec7c33f7dc6d2947c1148edce6db81db9a7
|
||||||
|
MapboxMobileEvents: d044b9edbe0ec7df60f6c2c9634fe9a7f449266b
|
||||||
|
MapboxNavigation: da9cf3d773ed5b0fa0fb388fccdaa117ee681f31
|
||||||
|
MapboxNavigationNative: 629e359f3d2590acd1ebbacaaf99e1a80ee57e42
|
||||||
|
MapboxSpeech: cd25ef99c3a3d2e0da72620ff558276ea5991a77
|
||||||
|
maps_launcher: edf829809ba9e894d70e569bab11c16352dedb45
|
||||||
|
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
|
||||||
|
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
|
||||||
|
network_info_plus: cf61925ab5205dce05a4f0895989afdb6aade5fc
|
||||||
|
open_filex: 432f3cd11432da3e39f47fcc0df2b1603854eff1
|
||||||
|
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
|
||||||
|
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
|
||||||
|
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
|
||||||
|
PayFortSDK: 233eabe9a45601fdbeac67fa6e5aae46ed8faf82
|
||||||
|
permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
|
||||||
|
Polyline: 2a1f29f87f8d9b7de868940f4f76deb8c678a5b1
|
||||||
|
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
||||||
|
SDWebImage: 9f177d83116802728e122410fb25ad88f5c7608a
|
||||||
|
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
|
||||||
|
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
|
||||||
|
Solar-dev: 4612dc9878b9fed2667d23b327f1d4e54e16e8d0
|
||||||
|
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
|
||||||
|
SwiftProtobuf: caa61117d9a5eeb60a52375f6685991a1fd4bd7b
|
||||||
|
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
|
||||||
|
Turf: aa2ede4298009639d10db36aba1a7ebaad072a5e
|
||||||
|
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
|
||||||
|
ZoomVideoSDK: e58f52e5f1d6c4bc46bcc7bd6875f916135fa2a2
|
||||||
|
|
||||||
|
PODFILE CHECKSUM: 5df9d8aa8f2c105eacd5ad7a310503d93c68c86b
|
||||||
|
|
||||||
|
COCOAPODS: 1.16.2
|
||||||
@ -0,0 +1,94 @@
|
|||||||
|
import Foundation
|
||||||
|
import FLAnimatedImage
|
||||||
|
|
||||||
|
|
||||||
|
var flutterMethodChannelPenguinIn:FlutterMethodChannel? = nil
|
||||||
|
fileprivate var mainViewController:FlutterViewController!
|
||||||
|
|
||||||
|
class HMGPenguinInPlatformBridge{
|
||||||
|
|
||||||
|
private let channelName = "launch_penguin_ui"
|
||||||
|
private static var shared_:HMGPenguinInPlatformBridge?
|
||||||
|
|
||||||
|
class func initialize(flutterViewController:FlutterViewController){
|
||||||
|
shared_ = HMGPenguinInPlatformBridge()
|
||||||
|
mainViewController = flutterViewController
|
||||||
|
shared_?.openChannel()
|
||||||
|
}
|
||||||
|
|
||||||
|
func shared() -> HMGPenguinInPlatformBridge{
|
||||||
|
assert((HMGPenguinInPlatformBridge.shared_ != nil), "HMGPenguinInPlatformBridge is not initialized, call initialize(mainViewController:MainFlutterVC) function first.")
|
||||||
|
return HMGPenguinInPlatformBridge.shared_!
|
||||||
|
}
|
||||||
|
|
||||||
|
private func openChannel(){
|
||||||
|
flutterMethodChannelPenguinIn = FlutterMethodChannel(name: channelName, binaryMessenger: mainViewController.binaryMessenger)
|
||||||
|
|
||||||
|
flutterMethodChannelPenguinIn?.setMethodCallHandler { (methodCall, result) in
|
||||||
|
print("Called function \(methodCall.method)")
|
||||||
|
|
||||||
|
if let arguments = methodCall.arguments as Any? {
|
||||||
|
if methodCall.method == "launchPenguin"{
|
||||||
|
print("====== launchPenguinView Launched =========")
|
||||||
|
self.launchPenguinView(arguments: arguments, result: result)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result(FlutterError(code: "INVALID_ARGUMENT", message: "Storyboard name is required", details: nil))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func launchPenguinView(arguments: Any, result: @escaping FlutterResult) {
|
||||||
|
|
||||||
|
let penguinView = PenguinView(
|
||||||
|
frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height),
|
||||||
|
viewIdentifier: 0,
|
||||||
|
arguments: arguments,
|
||||||
|
binaryMessenger: mainViewController.binaryMessenger
|
||||||
|
)
|
||||||
|
|
||||||
|
let penguinUIView = penguinView.view()
|
||||||
|
penguinUIView.frame = mainViewController.view.bounds
|
||||||
|
penguinUIView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||||
|
|
||||||
|
mainViewController.view.addSubview(penguinUIView)
|
||||||
|
|
||||||
|
guard let args = arguments as? [String: Any],
|
||||||
|
let loaderImageData = args["loaderImage"] as? FlutterStandardTypedData else {
|
||||||
|
print("loaderImage data not found in arguments")
|
||||||
|
result(FlutterError(code: "ARGUMENT_ERROR", message: "Missing loaderImage data", details: nil))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let loadingOverlay = UIView(frame: UIScreen.main.bounds)
|
||||||
|
loadingOverlay.backgroundColor = UIColor.black.withAlphaComponent(0.5) // Semi-transparent overlay
|
||||||
|
loadingOverlay.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||||
|
|
||||||
|
// Display the GIF using FLAnimatedImage
|
||||||
|
let animatedImage = FLAnimatedImage(animatedGIFData: loaderImageData.data)
|
||||||
|
let gifImageView = FLAnimatedImageView()
|
||||||
|
gifImageView.animatedImage = animatedImage
|
||||||
|
gifImageView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
|
||||||
|
gifImageView.center = loadingOverlay.center
|
||||||
|
gifImageView.contentMode = .scaleAspectFit
|
||||||
|
loadingOverlay.addSubview(gifImageView)
|
||||||
|
|
||||||
|
|
||||||
|
if let window = UIApplication.shared.windows.first {
|
||||||
|
window.addSubview(loadingOverlay)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
print("Error: Main window not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
penguinView.onSuccess = {
|
||||||
|
// Hide and remove the loader
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
loadingOverlay.removeFromSuperview()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// LocalizedFromFlutter.swift
|
||||||
|
// Runner
|
||||||
|
//
|
||||||
|
// Created by ZiKambrani on 10/04/1442 AH.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class FlutterText{
|
||||||
|
|
||||||
|
class func with(key:String,completion: @escaping (String)->Void){
|
||||||
|
flutterMethodChannelPenguinIn?.invokeMethod("localizedValue", arguments: key, result: { (result) in
|
||||||
|
if let localized = result as? String{
|
||||||
|
completion(localized)
|
||||||
|
}else{
|
||||||
|
completion(key)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,76 @@
|
|||||||
|
//
|
||||||
|
// PenguinModel.swift
|
||||||
|
// Runner
|
||||||
|
//
|
||||||
|
// Created by Amir on 06/08/2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// Define the model class
|
||||||
|
struct PenguinModel {
|
||||||
|
let baseURL: String
|
||||||
|
let dataURL: String
|
||||||
|
let dataServiceName: String
|
||||||
|
let positionURL: String
|
||||||
|
let clientKey: String
|
||||||
|
let storyboardName: String
|
||||||
|
let mapBoxKey: String
|
||||||
|
let clientID: String
|
||||||
|
let positionServiceName: String
|
||||||
|
let username: String
|
||||||
|
let isSimulationModeEnabled: Bool
|
||||||
|
let isShowUserName: Bool
|
||||||
|
let isUpdateUserLocationSmoothly: Bool
|
||||||
|
let isEnableReportIssue: Bool
|
||||||
|
let languageCode: String
|
||||||
|
let clinicID: String
|
||||||
|
let patientID: String
|
||||||
|
let projectID: String
|
||||||
|
|
||||||
|
// Initialize the model from a dictionary
|
||||||
|
init?(from dictionary: [String: Any]) {
|
||||||
|
guard
|
||||||
|
let baseURL = dictionary["baseURL"] as? String,
|
||||||
|
let dataURL = dictionary["dataURL"] as? String,
|
||||||
|
let dataServiceName = dictionary["dataServiceName"] as? String,
|
||||||
|
let positionURL = dictionary["positionURL"] as? String,
|
||||||
|
let clientKey = dictionary["clientKey"] as? String,
|
||||||
|
let storyboardName = dictionary["storyboardName"] as? String,
|
||||||
|
let mapBoxKey = dictionary["mapBoxKey"] as? String,
|
||||||
|
let clientID = dictionary["clientID"] as? String,
|
||||||
|
let positionServiceName = dictionary["positionServiceName"] as? String,
|
||||||
|
let username = dictionary["username"] as? String,
|
||||||
|
let isSimulationModeEnabled = dictionary["isSimulationModeEnabled"] as? Bool,
|
||||||
|
let isShowUserName = dictionary["isShowUserName"] as? Bool,
|
||||||
|
let isUpdateUserLocationSmoothly = dictionary["isUpdateUserLocationSmoothly"] as? Bool,
|
||||||
|
let isEnableReportIssue = dictionary["isEnableReportIssue"] as? Bool,
|
||||||
|
let languageCode = dictionary["languageCode"] as? String,
|
||||||
|
let clinicID = dictionary["clinicID"] as? String,
|
||||||
|
let patientID = dictionary["patientID"] as? String,
|
||||||
|
let projectID = dictionary["projectID"] as? String
|
||||||
|
else {
|
||||||
|
print("Initialization failed due to missing or invalid keys.")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
self.baseURL = baseURL
|
||||||
|
self.dataURL = dataURL
|
||||||
|
self.dataServiceName = dataServiceName
|
||||||
|
self.positionURL = positionURL
|
||||||
|
self.clientKey = clientKey
|
||||||
|
self.storyboardName = storyboardName
|
||||||
|
self.mapBoxKey = mapBoxKey
|
||||||
|
self.clientID = clientID
|
||||||
|
self.positionServiceName = positionServiceName
|
||||||
|
self.username = username
|
||||||
|
self.isSimulationModeEnabled = isSimulationModeEnabled
|
||||||
|
self.isShowUserName = isShowUserName
|
||||||
|
self.isUpdateUserLocationSmoothly = isUpdateUserLocationSmoothly
|
||||||
|
self.isEnableReportIssue = isEnableReportIssue
|
||||||
|
self.languageCode = languageCode
|
||||||
|
self.clinicID = clinicID
|
||||||
|
self.patientID = patientID
|
||||||
|
self.projectID = projectID
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
import PenNavUI
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class PenguinNavigator {
|
||||||
|
private var config: PenguinModel
|
||||||
|
|
||||||
|
init(config: PenguinModel) {
|
||||||
|
self.config = config
|
||||||
|
}
|
||||||
|
|
||||||
|
private func logError(_ message: String) {
|
||||||
|
// Centralized logging function
|
||||||
|
print("PenguinSDKNavigator Error: \(message)")
|
||||||
|
}
|
||||||
|
|
||||||
|
func navigateToPOI( referenceId:String,completion: @escaping (Bool, String?) -> Void) {
|
||||||
|
PenNavUIManager.shared.getToken(clientID: config.clientID, clientKey: config.clientKey) { [weak self] token, error in
|
||||||
|
|
||||||
|
if let error = error {
|
||||||
|
let errorMessage = "Token error while getting the for Navigate to method"
|
||||||
|
completion(false, "Failed to get token: \(errorMessage)")
|
||||||
|
|
||||||
|
print("Failed to get token: \(errorMessage)")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let token = token else {
|
||||||
|
completion(false, "Token is nil")
|
||||||
|
print("Token is nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
print("Token Generated")
|
||||||
|
print(token);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func handleNavigation(referenceId: String, token: String, completion: @escaping (Bool, String?) -> Void) {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
PenNavUIManager.shared.setToken(token: token)
|
||||||
|
|
||||||
|
PenNavUIManager.shared.navigate(to: referenceId) { [weak self] _, navError in
|
||||||
|
guard let self = self else { return }
|
||||||
|
|
||||||
|
if let navError = navError {
|
||||||
|
self.logError("Navigation error: Reference ID invalid")
|
||||||
|
completion(false, "Navigation error: \(navError.localizedDescription)")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Navigation successful
|
||||||
|
completion(true, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
//
|
||||||
|
// BlueGpsPlugin.swift
|
||||||
|
// Runner
|
||||||
|
//
|
||||||
|
// Created by Penguin .
|
||||||
|
//
|
||||||
|
|
||||||
|
//import Foundation
|
||||||
|
//import Flutter
|
||||||
|
//
|
||||||
|
///**
|
||||||
|
// * A Flutter plugin for integrating Penguin SDK functionality.
|
||||||
|
// * This class registers a view factory with the Flutter engine to create native views.
|
||||||
|
// */
|
||||||
|
//class PenguinPlugin: NSObject, FlutterPlugin {
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Registers the plugin with the Flutter engine.
|
||||||
|
// *
|
||||||
|
// * @param registrar The [FlutterPluginRegistrar] used to register the plugin.
|
||||||
|
// * This method is called when the plugin is initialized, and it sets up the communication
|
||||||
|
// * between Flutter and native code.
|
||||||
|
// */
|
||||||
|
// public static func register(with registrar: FlutterPluginRegistrar) {
|
||||||
|
// // Create an instance of PenguinViewFactory with the binary messenger from the registrar
|
||||||
|
// let factory = PenguinViewFactory(messenger: registrar.messenger())
|
||||||
|
//
|
||||||
|
// // Register the view factory with a unique ID for use in Flutter code
|
||||||
|
// registrar.register(factory, withId: "penguin_native")
|
||||||
|
// }
|
||||||
|
//}
|
||||||
@ -0,0 +1,445 @@
|
|||||||
|
//
|
||||||
|
|
||||||
|
// BlueGpsView.swift
|
||||||
|
|
||||||
|
// Runner
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
// Created by Penguin.
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import Flutter
|
||||||
|
import PenNavUI
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Flutter
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* A custom Flutter platform view for displaying Penguin UI components.
|
||||||
|
|
||||||
|
* This class integrates with the Penguin navigation SDK and handles UI events.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PenguinView: NSObject, FlutterPlatformView, PIEventsDelegate, PenNavInitializationDelegate
|
||||||
|
|
||||||
|
{
|
||||||
|
// The main view displayed within the platform view
|
||||||
|
|
||||||
|
private var _view: UIView
|
||||||
|
|
||||||
|
private var model: PenguinModel?
|
||||||
|
|
||||||
|
private var methodChannel: FlutterMethodChannel
|
||||||
|
|
||||||
|
var onSuccess: (() -> Void)?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* Initializes the PenguinView with the provided parameters.
|
||||||
|
|
||||||
|
*
|
||||||
|
|
||||||
|
* @param frame The frame of the view, specifying its size and position.
|
||||||
|
|
||||||
|
* @param viewId A unique identifier for this view instance.
|
||||||
|
|
||||||
|
* @param args Optional arguments provided for creating the view.
|
||||||
|
|
||||||
|
* @param messenger The [FlutterBinaryMessenger] used for communication with Dart.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
init(
|
||||||
|
|
||||||
|
frame: CGRect,
|
||||||
|
|
||||||
|
viewIdentifier viewId: Int64,
|
||||||
|
|
||||||
|
arguments args: Any?,
|
||||||
|
|
||||||
|
binaryMessenger messenger: FlutterBinaryMessenger?
|
||||||
|
|
||||||
|
) {
|
||||||
|
|
||||||
|
_view = UIView()
|
||||||
|
|
||||||
|
methodChannel = FlutterMethodChannel(name: "launch_penguin_ui", binaryMessenger: messenger!)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
super.init()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Get the screen's width and height to set the view's frame
|
||||||
|
|
||||||
|
let screenWidth = UIScreen.main.bounds.width
|
||||||
|
|
||||||
|
let screenHeight = UIScreen.main.bounds.height
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Uncomment to set the background color of the view
|
||||||
|
|
||||||
|
// _view.backgroundColor = UIColor.red
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Set the frame of the view to cover the entire screen
|
||||||
|
|
||||||
|
_view.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight)
|
||||||
|
|
||||||
|
print("========Inside Penguin View ========")
|
||||||
|
|
||||||
|
print(args)
|
||||||
|
|
||||||
|
guard let arguments = args as? [String: Any] else {
|
||||||
|
|
||||||
|
print("Error: Arguments are not in the expected format.")
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
print("===== i got tha Args=======")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Initialize the model from the arguments
|
||||||
|
|
||||||
|
if let penguinModel = PenguinModel(from: arguments) {
|
||||||
|
|
||||||
|
self.model = penguinModel
|
||||||
|
|
||||||
|
initPenguin(args: penguinModel)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
print("Error: Failed to initialize PenguinModel from arguments ")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the Penguin SDK with required configurations
|
||||||
|
|
||||||
|
// initPenguin( arguments: args)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* Initializes the Penguin SDK with custom configuration settings.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
func initPenguin(args: PenguinModel) {
|
||||||
|
|
||||||
|
// Set the initialization delegate to handle SDK initialization events
|
||||||
|
|
||||||
|
PenNavUIManager.shared.initializationDelegate = self
|
||||||
|
|
||||||
|
// Configure the Penguin SDK with necessary parameters
|
||||||
|
|
||||||
|
PenNavUIManager.shared
|
||||||
|
|
||||||
|
.setClientKey(args.clientKey)
|
||||||
|
|
||||||
|
.setClientID(args.clientID)
|
||||||
|
|
||||||
|
.setUsername(args.username)
|
||||||
|
|
||||||
|
.setSimulationModeEnabled(isEnable: args.isSimulationModeEnabled)
|
||||||
|
|
||||||
|
.setBaseURL(dataURL: args.dataURL, positionURL: args.positionURL)
|
||||||
|
|
||||||
|
.setServiceName(dataServiceName: args.dataServiceName, positionServiceName: args.positionServiceName)
|
||||||
|
|
||||||
|
.setIsShowUserName(args.isShowUserName)
|
||||||
|
|
||||||
|
.setIsUpdateUserLocationSmoothly(args.isUpdateUserLocationSmoothly)
|
||||||
|
|
||||||
|
.setEnableReportIssue(enable: args.isEnableReportIssue)
|
||||||
|
|
||||||
|
.setLanguage(args.languageCode)
|
||||||
|
|
||||||
|
.setBackButtonVisibility(true)
|
||||||
|
|
||||||
|
.build()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* Returns the main view associated with this platform view.
|
||||||
|
|
||||||
|
*
|
||||||
|
|
||||||
|
* @return The UIView instance that represents this platform view.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
func view() -> UIView {
|
||||||
|
|
||||||
|
return _view
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - PIEventsDelegate Methods
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* Called when the Penguin UI is dismissed.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
func onPenNavUIDismiss() {
|
||||||
|
|
||||||
|
// Handle UI dismissal if needed
|
||||||
|
|
||||||
|
print("====== onPenNavUIDismiss =========")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
self.view().removeFromSuperview()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* Called when a report issue is generated.
|
||||||
|
|
||||||
|
*
|
||||||
|
|
||||||
|
* @param issue The type of issue reported.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
func onReportIssue(_ issue: PenNavUI.IssueType) {
|
||||||
|
|
||||||
|
// Handle report issue events if needed
|
||||||
|
|
||||||
|
print("====== onReportIssueError =========")
|
||||||
|
|
||||||
|
methodChannel.invokeMethod("onReportIssue", arguments: ["issueType": issue])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* Called when the Penguin UI setup is successful.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
func onPenNavSuccess() {
|
||||||
|
|
||||||
|
print("====== onPenNavSuccess =========")
|
||||||
|
|
||||||
|
onSuccess?()
|
||||||
|
|
||||||
|
methodChannel.invokeMethod("onPenNavSuccess", arguments: nil)
|
||||||
|
|
||||||
|
// Obtain the FlutterViewController instance
|
||||||
|
|
||||||
|
let controller: FlutterViewController = UIApplication.shared.windows.first?.rootViewController as! FlutterViewController
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print("====== after controller onPenNavSuccess =========")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Set the events delegate to handle SDK events
|
||||||
|
|
||||||
|
PenNavUIManager.shared.eventsDelegate = self
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print("====== after eventsDelegate onPenNavSuccess =========")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Present the Penguin UI on top of the Flutter view controller
|
||||||
|
|
||||||
|
PenNavUIManager.shared.present(root: controller, view: _view)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print("====== after present onPenNavSuccess =========")
|
||||||
|
|
||||||
|
print(model?.clinicID)
|
||||||
|
|
||||||
|
print("====== after present onPenNavSuccess =========")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
guard let config = self.model else {
|
||||||
|
|
||||||
|
print("Error: Config Model is nil")
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
guard let clinicID = self.model?.clinicID,
|
||||||
|
|
||||||
|
let clientID = self.model?.clientID, !clientID.isEmpty else {
|
||||||
|
|
||||||
|
print("Error: Config Client ID is nil or empty")
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
let navigator = PenguinNavigator(config: config)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PenNavUIManager.shared.getToken(clientID: config.clientID, clientKey: config.clientKey) { [weak self] token, error in
|
||||||
|
|
||||||
|
if let error = error {
|
||||||
|
|
||||||
|
let errorMessage = "Token error while getting the for Navigate to method"
|
||||||
|
|
||||||
|
print("Failed to get token: \(errorMessage)")
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
guard let token = token else {
|
||||||
|
|
||||||
|
print("Token is nil")
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
print("Token Generated")
|
||||||
|
|
||||||
|
print(token);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
self?.handleNavigation(clinicID: clinicID, token: token) { success, errorMessage in
|
||||||
|
|
||||||
|
if success {
|
||||||
|
|
||||||
|
print("Navigation successful")
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
print("Navigation failed: \(errorMessage ?? "Unknown error")")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print("====== after Token onPenNavSuccess =========")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private func handleNavigation(clinicID: String, token: String, completion: @escaping (Bool, String?) -> Void) {
|
||||||
|
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
|
||||||
|
PenNavUIManager.shared.setToken(token: token)
|
||||||
|
|
||||||
|
PenNavUIManager.shared.navigate(to: clinicID)
|
||||||
|
|
||||||
|
completion(true,nil)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* Called when there is an initialization error with the Penguin UI.
|
||||||
|
|
||||||
|
*
|
||||||
|
|
||||||
|
* @param errorType The type of initialization error.
|
||||||
|
|
||||||
|
* @param errorDescription A description of the error.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
func onPenNavInitializationError(errorType: PenNavUI.PenNavUIError, errorDescription: String) {
|
||||||
|
|
||||||
|
// Handle initialization errors if needed
|
||||||
|
|
||||||
|
print("onPenNavInitializationErrorType: \(errorType.rawValue)")
|
||||||
|
|
||||||
|
print("onPenNavInitializationError: \(errorDescription)")
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,59 @@
|
|||||||
|
//
|
||||||
|
// BlueGpsViewFactory.swift
|
||||||
|
// Runner
|
||||||
|
//
|
||||||
|
// Created by Penguin .
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Flutter
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A factory class for creating instances of [PenguinView].
|
||||||
|
* This class implements `FlutterPlatformViewFactory` to create and manage native views.
|
||||||
|
*/
|
||||||
|
class PenguinViewFactory: NSObject, FlutterPlatformViewFactory {
|
||||||
|
|
||||||
|
// The binary messenger used for communication with the Flutter engine
|
||||||
|
private var messenger: FlutterBinaryMessenger
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the PenguinViewFactory with the given messenger.
|
||||||
|
*
|
||||||
|
* @param messenger The [FlutterBinaryMessenger] used to communicate with Dart code.
|
||||||
|
*/
|
||||||
|
init(messenger: FlutterBinaryMessenger) {
|
||||||
|
self.messenger = messenger
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of [PenguinView].
|
||||||
|
*
|
||||||
|
* @param frame The frame of the view, specifying its size and position.
|
||||||
|
* @param viewId A unique identifier for this view instance.
|
||||||
|
* @param args Optional arguments provided for creating the view.
|
||||||
|
* @return An instance of [PenguinView] configured with the provided parameters.
|
||||||
|
*/
|
||||||
|
func create(
|
||||||
|
withFrame frame: CGRect,
|
||||||
|
viewIdentifier viewId: Int64,
|
||||||
|
arguments args: Any?
|
||||||
|
) -> FlutterPlatformView {
|
||||||
|
return PenguinView(
|
||||||
|
frame: frame,
|
||||||
|
viewIdentifier: viewId,
|
||||||
|
arguments: args,
|
||||||
|
binaryMessenger: messenger)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the codec used for encoding and decoding method channel arguments.
|
||||||
|
* This method is required when `arguments` in `create` is not `nil`.
|
||||||
|
*
|
||||||
|
* @return A [FlutterMessageCodec] instance used for serialization.
|
||||||
|
*/
|
||||||
|
public func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {
|
||||||
|
return FlutterStandardMessageCodec.sharedInstance()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
class NavigationClinicDetails {
|
||||||
|
String? clinicId;
|
||||||
|
String? patientId;
|
||||||
|
String? projectId;
|
||||||
|
}
|
||||||
@ -0,0 +1,110 @@
|
|||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
class PenguinMethodChannel {
|
||||||
|
static const MethodChannel _channel = MethodChannel('launch_penguin_ui');
|
||||||
|
|
||||||
|
Future<Uint8List> loadGif() async {
|
||||||
|
return await rootBundle.load("assets/images/progress-loading-red-crop-1.gif").then((data) => data.buffer.asUint8List());
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<void> launch(String storyboardName, String languageCode, String username, {NavigationClinicDetails? details}) async {
|
||||||
|
// Uint8List image = await loadGif();
|
||||||
|
try {
|
||||||
|
await _channel.invokeMethod('launchPenguin', {
|
||||||
|
"storyboardName": storyboardName,
|
||||||
|
"baseURL": "https://prod.hmg.nav.penguinin.com",
|
||||||
|
// "dataURL": "https://hmg.nav.penguinin.com",
|
||||||
|
// "positionURL": "https://hmg.nav.penguinin.com",
|
||||||
|
// "dataURL": "https://hmg-v33.local.penguinin.com",
|
||||||
|
// "positionURL": "https://hmg-v33.local.penguinin.com",
|
||||||
|
"dataURL": "https://prod.hmg.nav.penguinin.com",
|
||||||
|
"positionURL": "https://prod.hmg.nav.penguinin.com",
|
||||||
|
"dataServiceName": "api",
|
||||||
|
"positionServiceName": "pe",
|
||||||
|
"clientID": "HMG",
|
||||||
|
// "username": "Haroon",
|
||||||
|
"username": username,
|
||||||
|
"isSimulationModeEnabled": false,
|
||||||
|
"isShowUserName": false,
|
||||||
|
"isUpdateUserLocationSmoothly": true,
|
||||||
|
"isEnableReportIssue": true,
|
||||||
|
"languageCode": languageCode,
|
||||||
|
"clientKey": "UGVuZ3VpbklOX1Blbk5hdl9QSUY=",
|
||||||
|
"mapBoxKey": "sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg",
|
||||||
|
"clinicID": details?.clinicId ?? "",
|
||||||
|
// "clinicID": "108", // 46 ,49, 133
|
||||||
|
"patientID": details?.patientId ?? "",
|
||||||
|
"projectID": details?.projectId ?? "",
|
||||||
|
// "loaderImage": image,
|
||||||
|
});
|
||||||
|
} on PlatformException catch (e) {
|
||||||
|
print("Failed to launch PenguinIn: '${e.message}'.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMethodCallHandler(){
|
||||||
|
_channel.setMethodCallHandler((MethodCall call) async {
|
||||||
|
try {
|
||||||
|
|
||||||
|
print(call.method);
|
||||||
|
|
||||||
|
switch (call.method) {
|
||||||
|
|
||||||
|
case PenguinMethodNames.onPenNavInitializationError:
|
||||||
|
_handleInitializationError(call.arguments); // Handle onPenNavInitializationError errors.
|
||||||
|
break;
|
||||||
|
case PenguinMethodNames.onPenNavUIDismiss:
|
||||||
|
//todo handle pen dismissable
|
||||||
|
// _handlePenNavUIDismiss(); // Handle UI dismissal event.
|
||||||
|
break;
|
||||||
|
case PenguinMethodNames.onReportIssue:
|
||||||
|
// Handle the report issue event.
|
||||||
|
_handleInitializationError(call.arguments);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_handleUnknownMethod(call.method); // Handle unknown method calls.
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print("Error handling method call '${call.method}': $e");
|
||||||
|
// Optionally, log this error to an external service
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
static void _handleUnknownMethod(String method) {
|
||||||
|
print("Unknown method: $method");
|
||||||
|
// Optionally, handle this unknown method case, such as reporting or ignoring it
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void _handleInitializationError(Map<dynamic, dynamic> error) {
|
||||||
|
final type = error['type'] as String?;
|
||||||
|
final description = error['description'] as String?;
|
||||||
|
print("Initialization Error: ${type ?? 'Unknown Type'}, ${description ?? 'No Description'}");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// Define constants for method names
|
||||||
|
class PenguinMethodNames {
|
||||||
|
static const String showPenguinUI = 'showPenguinUI';
|
||||||
|
static const String openSharedLocation = 'openSharedLocation';
|
||||||
|
|
||||||
|
// ---- Handler Method
|
||||||
|
static const String onPenNavSuccess = 'onPenNavSuccess'; // Tested Android,iOS
|
||||||
|
static const String onPenNavInitializationError = 'onPenNavInitializationError'; // Tested Android,iOS
|
||||||
|
static const String onPenNavUIDismiss = 'onPenNavUIDismiss'; //Tested Android,iOS
|
||||||
|
static const String onReportIssue = 'onReportIssue'; // Tested Android,iOS
|
||||||
|
static const String onLocationOffCampus = 'onLocationOffCampus'; // Tested iOS,Android
|
||||||
|
static const String navigateToPOI = 'navigateToPOI'; // Tested Android,iOS
|
||||||
|
}
|
||||||
|
|
||||||
|
class NavigationClinicDetails {
|
||||||
|
String? clinicId;
|
||||||
|
String? patientId;
|
||||||
|
String? projectId;
|
||||||
|
|
||||||
|
|
||||||
|
NavigationClinicDetails({this.clinicId, this.patientId, this.projectId});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||