Skip to content

Commit 0e3f73d

Browse files
committed
feat: handle events
1 parent 2a83bbb commit 0e3f73d

File tree

2 files changed

+82
-3
lines changed

2 files changed

+82
-3
lines changed

app/src/main/java/to/bitkit/ui/ContentView.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,10 @@ private fun NavGraphBuilder.shop(
730730
ShopWebViewScreen (
731731
onClose = { navController.navigateToHome() },
732732
onBack = { navController.popBackStack() },
733-
page = navBackEntry.toRoute<Routes.ShopWebView>().page
733+
page = navBackEntry.toRoute<Routes.ShopWebView>().page,
734+
onPaymentIntent = { intent ->
735+
Logger.warn("Payment intent $intent", context = "ShopWebViewScreen")
736+
} // TODO HANDLE
734737
)
735738
}
736739
}

app/src/main/java/to/bitkit/ui/screens/shop/ShopWebViewScreen.kt

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package to.bitkit.ui.screens.shop
22

33
import android.annotation.SuppressLint
44
import android.graphics.Bitmap
5+
import android.util.Log
56
import android.view.ViewGroup
7+
import android.webkit.JavascriptInterface
68
import android.webkit.WebResourceError
79
import android.webkit.WebResourceRequest
810
import android.webkit.WebView
@@ -21,6 +23,9 @@ import androidx.compose.ui.Modifier
2123
import androidx.compose.ui.res.stringResource
2224
import androidx.compose.ui.tooling.preview.Preview
2325
import androidx.compose.ui.viewinterop.AndroidView
26+
import kotlinx.serialization.SerialName
27+
import kotlinx.serialization.Serializable
28+
import kotlinx.serialization.json.Json
2429
import to.bitkit.R
2530
import to.bitkit.env.Env
2631
import to.bitkit.ui.scaffold.AppTopBar
@@ -29,16 +34,51 @@ import to.bitkit.ui.scaffold.ScreenColumn
2934
import to.bitkit.ui.theme.AppThemeSurface
3035
import to.bitkit.utils.Logger
3136

37+
@Serializable
38+
data class WebViewMessage(
39+
val event: String,
40+
@SerialName("paymentUri")
41+
val paymentUri: String? = null
42+
)
43+
3244
@SuppressLint("SetJavaScriptEnabled")
3345
@Composable
3446
fun ShopWebViewScreen(
3547
onClose: () -> Unit,
3648
onBack: () -> Unit,
49+
onPaymentIntent: (String) -> Unit,
3750
page: String,
3851
) {
3952
var isLoading by remember { mutableStateOf(true) }
4053
var webView: WebView? by remember { mutableStateOf(null) }
4154

55+
// Create a JavaScript interface for message handling
56+
class WebViewInterface {
57+
@JavascriptInterface
58+
fun postMessage(message: String) {
59+
try {
60+
val json = Json { ignoreUnknownKeys = true }
61+
val data = json.decodeFromString<WebViewMessage>(message)
62+
63+
Log.d("WebView", "Received message: $message")
64+
65+
when (data.event) {
66+
"payment_intent" -> {
67+
data.paymentUri?.let { uri ->
68+
onPaymentIntent(uri)
69+
}
70+
}
71+
// Add more event types as needed
72+
else -> {
73+
Log.d("WebView", "Unknown event type: ${data.event}")
74+
}
75+
}
76+
} catch (e: Exception) {
77+
Log.e("WebView", "Error parsing message: $message", e)
78+
}
79+
}
80+
}
81+
4282
ScreenColumn {
4383
AppTopBar(
4484
titleText = stringResource(R.string.other__shop__discover__nav_title),
@@ -55,6 +95,7 @@ fun ShopWebViewScreen(
5595
ViewGroup.LayoutParams.MATCH_PARENT,
5696
ViewGroup.LayoutParams.MATCH_PARENT,
5797
)
98+
5899
webViewClient = object : WebViewClient() {
59100
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
60101
super.onPageStarted(view, url, favicon)
@@ -64,6 +105,27 @@ fun ShopWebViewScreen(
64105
override fun onPageFinished(view: WebView?, url: String?) {
65106
super.onPageFinished(view, url)
66107
isLoading = false
108+
109+
// Inject JavaScript to bridge postMessage to Android
110+
view?.evaluateJavascript("""
111+
window.ReactNativeWebView = {
112+
postMessage: function(data) {
113+
Android.postMessage(data);
114+
}
115+
};
116+
117+
// Override the default postMessage if it exists
118+
if (window.postMessage) {
119+
window.originalPostMessage = window.postMessage;
120+
window.postMessage = function(data) {
121+
if (typeof data === 'string') {
122+
Android.postMessage(data);
123+
} else {
124+
Android.postMessage(JSON.stringify(data));
125+
}
126+
};
127+
}
128+
""".trimIndent(), null)
67129
}
68130

69131
override fun onReceivedError(
@@ -74,16 +136,28 @@ fun ShopWebViewScreen(
74136
super.onReceivedError(view, request, error)
75137
Logger.warn("Error: ${error?.description}, Code: ${error?.errorCode}, URL: ${request?.url}", context = "ShopWebViewScreen")
76138
isLoading = false
139+
77140
error?.let {
78141
if (it.errorCode == WebViewClient.ERROR_HOST_LOOKUP ||
79142
it.errorCode == WebViewClient.ERROR_CONNECT ||
80-
it.errorCode == WebViewClient.ERROR_TIMEOUT) {
143+
it.errorCode == WebViewClient.ERROR_TIMEOUT ||
144+
it.errorCode == WebViewClient.ERROR_FILE_NOT_FOUND) {
81145
onClose()
82146
}
83147
}
84148
}
85149
}
86-
settings.javaScriptEnabled = true
150+
151+
// Configure WebView settings
152+
settings.apply {
153+
javaScriptEnabled = true
154+
domStorageEnabled = true
155+
allowContentAccess = true
156+
allowFileAccess = false
157+
}
158+
159+
addJavascriptInterface(WebViewInterface(), "Android")
160+
87161
loadUrl(Env.buildBitrefillUri(page = page))
88162
webView = this
89163
}
@@ -114,6 +188,8 @@ private fun Preview() {
114188
ShopWebViewScreen(
115189
onClose = {},
116190
onBack = {},
191+
onPaymentIntent = { uri ->
192+
},
117193
page = "esims",
118194
)
119195
}

0 commit comments

Comments
 (0)