1 package expo.modules.devlauncher.launcher.errors 2 3 import android.app.Activity 4 import android.content.Context 5 import android.content.Intent 6 import android.os.Bundle 7 import androidx.fragment.app.FragmentActivity 8 import com.facebook.react.ReactActivity 9 import expo.modules.devlauncher.databinding.ErrorFragmentBinding 10 import expo.modules.devlauncher.koin.DevLauncherKoinComponent 11 import expo.modules.devlauncher.launcher.DevLauncherControllerInterface 12 import kotlinx.coroutines.launch 13 import org.koin.core.component.inject 14 import java.lang.ref.WeakReference 15 16 class DevLauncherErrorActivity : 17 FragmentActivity(), DevLauncherKoinComponent { 18 19 private val controller: DevLauncherControllerInterface by inject() 20 private lateinit var binding: ErrorFragmentBinding 21 private val adapter = DevLauncherStackAdapter(this, null) 22 onCreatenull23 override fun onCreate(savedInstanceState: Bundle?) { 24 super.onCreate(savedInstanceState) 25 26 binding = ErrorFragmentBinding.inflate(layoutInflater) 27 binding.homeButton.setOnClickListener { this.launchHome() } 28 binding.reloadButton.setOnClickListener { this.reload() } 29 30 synchronized(DevLauncherErrorActivity) { 31 val error = currentError 32 if (error != null) { 33 displayError(currentError!!) 34 currentError = null 35 } else { 36 finish() 37 return 38 } 39 } 40 41 setContentView(binding.root) 42 } 43 onResumenull44 override fun onResume() { 45 super.onResume() 46 openedErrorActivity = WeakReference(this) 47 } 48 onPausenull49 override fun onPause() { 50 super.onPause() 51 openedErrorActivity = WeakReference(null) 52 } 53 displayErrornull54 fun displayError(error: DevLauncherAppError) { 55 adapter.data = error 56 57 binding.errorStack.let { 58 it.adapter = adapter 59 adapter.notifyDataSetChanged() 60 } 61 binding.errorDetails.text = error.message ?: "Unknown error" 62 } 63 launchHomenull64 private fun launchHome() { 65 synchronized(DevLauncherErrorActivity) { 66 currentError = null 67 } 68 69 controller.navigateToLauncher() 70 } 71 reloadnull72 private fun reload() { 73 synchronized(DevLauncherErrorActivity) { 74 currentError = null 75 } 76 77 val appUrl = controller.latestLoadedApp 78 79 if (appUrl == null) { 80 controller.navigateToLauncher() 81 return 82 } 83 84 controller.coroutineScope.launch { 85 controller 86 .loadApp( 87 appUrl, 88 controller.appHost.reactInstanceManager.currentReactContext?.currentActivity as? ReactActivity? 89 ) 90 } 91 } 92 onBackPressednull93 override fun onBackPressed() {} 94 95 companion object { 96 private var openedErrorActivity = WeakReference<DevLauncherErrorActivity?>(null) 97 private var currentError: DevLauncherAppError? = null 98 isVisiblenull99 fun isVisible(): Boolean { 100 val errorActivity = openedErrorActivity.get() 101 return !(errorActivity == null || errorActivity.isDestroyed || errorActivity.isFinishing) 102 } 103 showErrorIfNotVisiblenull104 fun showErrorIfNotVisible(activity: Activity, error: DevLauncherAppError) { 105 val errorActivity = openedErrorActivity.get() 106 if (errorActivity == null || errorActivity.isDestroyed || errorActivity.isFinishing) { 107 synchronized(this) { 108 currentError = error 109 } 110 111 activity.startActivity( 112 Intent(activity, DevLauncherErrorActivity::class.java) 113 ) 114 } 115 } 116 showErrornull117 fun showError(activity: Activity, error: DevLauncherAppError) { 118 val errorActivity = openedErrorActivity.get() 119 if (errorActivity == null || errorActivity.isDestroyed) { 120 synchronized(this) { 121 currentError = error 122 } 123 124 activity.startActivity( 125 Intent(activity, DevLauncherErrorActivity::class.java) 126 ) 127 } else { 128 errorActivity.displayError(error) 129 } 130 } 131 showFatalErrornull132 fun showFatalError(context: Context, error: DevLauncherAppError) { 133 synchronized(this) { 134 currentError = error 135 } 136 137 context.startActivity( 138 Intent(context, DevLauncherErrorActivity::class.java).apply { 139 addFlags( 140 Intent.FLAG_ACTIVITY_NEW_TASK or 141 Intent.FLAG_ACTIVITY_CLEAR_TASK or 142 Intent.FLAG_ACTIVITY_NO_ANIMATION 143 ) 144 } 145 ) 146 } 147 } 148 } 149