package com.fireho.queroir import android.content.Intent import android.os.Bundle import android.os.Handler import android.os.Looper import android.util.Log import android.view.View import android.webkit.JavascriptInterface import android.webkit.WebView import androidx.activity.enableEdgeToEdge import dev.hotwire.navigation.activities.HotwireActivity import dev.hotwire.navigation.navigator.NavigatorConfiguration import dev.hotwire.navigation.util.applyDefaultImeWindowInsets class MainActivity : HotwireActivity() { private lateinit var qrCodeScanner: QrCodeScanner private var webView: WebView? = null override fun onCreate(savedInstanceState: Bundle?) { enableEdgeToEdge() super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) findViewById(R.id.main_nav_host).applyDefaultImeWindowInsets() // Initialize QR code scanner qrCodeScanner = QrCodeScanner(this) // Delay setup to ensure WebView is loaded Handler(Looper.getMainLooper()).postDelayed({ findWebViewAndSetupInterface() }, 1000) } /** * Find WebView and set up JavaScript interface */ private fun findWebViewAndSetupInterface() { try { // Find the WebView webView = findWebView() if (webView != null) { Log.d("MainActivity", "WebView found, setting up JavaScript interface") setupJavaScriptInterface(webView!!) } else { Log.e("MainActivity", "WebView not found, retrying in 1 second") // Retry after a delay Handler(Looper.getMainLooper()).postDelayed({ findWebViewAndSetupInterface() }, 1000) } } catch (e: Exception) { Log.e("MainActivity", "Error finding WebView", e) } } /** * Set up JavaScript interface for QR code scanning */ private fun setupJavaScriptInterface(webView: WebView) { try { Log.d("MainActivity", "Setting up JavaScript interface") // Add JavaScript interface webView.addJavascriptInterface(object { /** * Perform an action from JavaScript */ @JavascriptInterface fun perform(action: String) { Log.d("MainActivity", "perform action received: $action") if (action == "scanQrCode") { runOnUiThread { qrCodeScanner.scan() } } } }, "HotwireNative") // Inject JavaScript to set up the callbacks system val jsSetup = """ (function() { // Set up HotwireNative object if it doesn't exist window.HotwireNative = window.HotwireNative || {}; // Set a flag to indicate that HotwireNative is available window.HotwireNative.isAvailable = true; console.log('Setting up HotwireNative JavaScript interface'); // Initialize callbacks object if it doesn't exist if (!window.HotwireNative.callbacks) { window.HotwireNative.callbacks = {}; } // Add registerCallback function if it doesn't exist if (typeof window.HotwireNative.registerCallback !== 'function') { window.HotwireNative.registerCallback = function(name, callback) { window.HotwireNative.callbacks[name] = callback; console.log('Registered callback: ' + name); }; } console.log('HotwireNative JavaScript interface setup complete'); // Dispatch an event to notify the web app that HotwireNative is available var event = new CustomEvent('hotwireNativeAvailable'); document.dispatchEvent(event); })(); """.trimIndent() webView.evaluateJavascript(jsSetup) { result -> Log.d("MainActivity", "JavaScript setup result: $result") } Log.d("MainActivity", "JavaScript interface setup complete") } catch (e: Exception) { Log.e("MainActivity", "Error setting up JavaScript interface", e) } } /** * Find the WebView in the view hierarchy */ private fun findWebView(): WebView? { try { // Try to find WebView in the navigator host val navHost = findViewById(R.id.main_nav_host) // Log the view hierarchy for debugging Log.d("MainActivity", "NavHost: $navHost") // Try different approaches to find the WebView // Approach 1: Direct child val webView1 = navHost?.findViewById(android.R.id.content) if (webView1 != null) { Log.d("MainActivity", "WebView found using approach 1") return webView1 } // Approach 2: Search all children recursively val webView2 = findWebViewInViewHierarchy(navHost) if (webView2 != null) { Log.d("MainActivity", "WebView found using approach 2") return webView2 } Log.e("MainActivity", "WebView not found in view hierarchy") return null } catch (e: Exception) { Log.e("MainActivity", "Error finding WebView", e) return null } } /** * Find WebView in view hierarchy recursively */ private fun findWebViewInViewHierarchy(view: View?): WebView? { if (view == null) return null if (view is WebView) return view try { if (view is android.view.ViewGroup) { for (i in 0 until view.childCount) { val child = view.getChildAt(i) val webView = findWebViewInViewHierarchy(child) if (webView != null) return webView } } } catch (e: Exception) { Log.e("MainActivity", "Error searching view hierarchy", e) } return null } override fun navigatorConfigurations() = listOf( NavigatorConfiguration( name = "main", // startLocation = "https://hotwire-native-demo.dev", startLocation = "https://queroir.ai", navigatorHostId = R.id.main_nav_host ) ) // Handle QR code scan result override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) // Get the current WebView val currentWebView = webView if (currentWebView != null) { qrCodeScanner.handleScanResult(requestCode, resultCode, data, currentWebView) } else { Log.e("MainActivity", "No WebView available to handle QR code result") // Try to find WebView again val foundWebView = findWebView() if (foundWebView != null) { qrCodeScanner.handleScanResult(requestCode, resultCode, data, foundWebView) } else { Log.e("MainActivity", "Still no WebView available to handle QR code result") } } } }