diff --git a/README.md b/README.md index c8b9bbe..d17c30c 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ This **Komoju Mobile SDK** allows you to seamlessly integrate secure and reliable payment experiences into your Naive Android and iOS app. +[API DOCS](https://cautious-adventure-g6zje9v.pages.github.io/) + ## Get Started ### Android diff --git a/android/src/main/java/com/komoju/android/sdk/KomojuPaymentActivity.kt b/android/src/main/java/com/komoju/android/sdk/KomojuPaymentActivity.kt index d0d2faa..2230fab 100644 --- a/android/src/main/java/com/komoju/android/sdk/KomojuPaymentActivity.kt +++ b/android/src/main/java/com/komoju/android/sdk/KomojuPaymentActivity.kt @@ -63,7 +63,6 @@ internal class KomojuPaymentActivity : ComponentActivity() { super.onCreate(savedInstanceState) setContent { val isVisible by viewModel.isVisible.collectAsStateWithLifecycle() - val router by viewModel.router.collectAsStateWithLifecycle() val animatedAlpha by animateFloatAsState( targetValue = if (isVisible) .3f else .0f, label = "scrim_alpha_animation", @@ -94,7 +93,7 @@ internal class KomojuPaymentActivity : ComponentActivity() { KomojuPaymentScreen(viewModel.configuration), ) { navigator -> SlideTransition(navigator) - RouterEffect(router, viewModel::onRouteConsumed) + RouterEffect(viewModel.router.collectAsStateWithLifecycle(), viewModel::onRouteConsumed) NewIntentEffect(LocalContext.current, viewModel::onNewDeeplink) } } diff --git a/android/src/main/java/com/komoju/android/sdk/navigation/RouterStateScreenModel.kt b/android/src/main/java/com/komoju/android/sdk/navigation/RouterStateScreenModel.kt new file mode 100644 index 0000000..2516610 --- /dev/null +++ b/android/src/main/java/com/komoju/android/sdk/navigation/RouterStateScreenModel.kt @@ -0,0 +1,24 @@ +package com.komoju.android.sdk.navigation + +import cafe.adriel.voyager.core.model.ScreenModel +import com.komoju.android.sdk.ui.screens.Router +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow + +internal abstract class RouterStateScreenModel(initialState: S) : ScreenModel { + + protected val mutableState: MutableStateFlow = MutableStateFlow(initialState) + val state: StateFlow = mutableState.asStateFlow() + + protected val mutableRouter = MutableStateFlow(null) + val router = mutableRouter.asStateFlow() + + fun onRouteConsumed() { + mutableRouter.value = null + } + + protected fun MutableStateFlow.pop() { + value = Router.Pop + } +} diff --git a/android/src/main/java/com/komoju/android/sdk/ui/screens/KomojuPaymentRoutes.kt b/android/src/main/java/com/komoju/android/sdk/ui/screens/KomojuPaymentRoutes.kt index cdec1ba..2058efc 100644 --- a/android/src/main/java/com/komoju/android/sdk/ui/screens/KomojuPaymentRoutes.kt +++ b/android/src/main/java/com/komoju/android/sdk/ui/screens/KomojuPaymentRoutes.kt @@ -3,8 +3,11 @@ package com.komoju.android.sdk.ui.screens import android.content.Context import android.content.Intent import android.net.Uri +import androidx.activity.compose.LocalOnBackPressedDispatcherOwner import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.State +import androidx.compose.runtime.getValue import androidx.compose.ui.platform.LocalContext import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.currentOrThrow @@ -55,12 +58,14 @@ internal sealed interface KomojuPaymentRoute { } @Composable -internal fun RouterEffect(router: Router?, onHandled: () -> Unit) { +internal fun RouterEffect(routerState: State, onHandled: () -> Unit) { val navigator = LocalNavigator.currentOrThrow val context = LocalContext.current + val router = routerState.value + val backPressDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher LaunchedEffect(router) { when (router) { - is Router.Pop -> navigator.pop() + is Router.Pop -> if (navigator.pop().not()) backPressDispatcher?.onBackPressed() is Router.PopAll -> navigator.popAll() is Router.PopToRoot -> navigator.popUntilRoot() is Router.Push -> navigator.push(router.route.screen) diff --git a/android/src/main/java/com/komoju/android/sdk/ui/screens/awating/KonbiniAwaitingPaymentScreen.kt b/android/src/main/java/com/komoju/android/sdk/ui/screens/awating/KonbiniAwaitingPaymentScreen.kt index 413d17c..40efafa 100644 --- a/android/src/main/java/com/komoju/android/sdk/ui/screens/awating/KonbiniAwaitingPaymentScreen.kt +++ b/android/src/main/java/com/komoju/android/sdk/ui/screens/awating/KonbiniAwaitingPaymentScreen.kt @@ -53,8 +53,7 @@ internal data class KonbiniAwaitingPaymentScreen(val route: KomojuPaymentRoute.K override fun Content() { val screenModel = rememberScreenModel { KonbiniAwaitingPaymentScreenModel(route.configuration, route.payment) } val uiState by screenModel.state.collectAsStateWithLifecycle() - val router by screenModel.router.collectAsStateWithLifecycle() - RouterEffect(router, screenModel::onRouteConsumed) + RouterEffect(screenModel.router.collectAsStateWithLifecycle(), screenModel::onRouteConsumed) uiState.payment?.let { PaymentStatus(it, onPrimaryButtonClicked = screenModel::onPrimaryButtonClicked, onSecondaryButtonClicked = screenModel::onSecondaryButtonClicked) } diff --git a/android/src/main/java/com/komoju/android/sdk/ui/screens/awating/KonbiniAwaitingPaymentScreenModel.kt b/android/src/main/java/com/komoju/android/sdk/ui/screens/awating/KonbiniAwaitingPaymentScreenModel.kt index 859f922..a5cf71c 100644 --- a/android/src/main/java/com/komoju/android/sdk/ui/screens/awating/KonbiniAwaitingPaymentScreenModel.kt +++ b/android/src/main/java/com/komoju/android/sdk/ui/screens/awating/KonbiniAwaitingPaymentScreenModel.kt @@ -1,39 +1,32 @@ package com.komoju.android.sdk.ui.screens.awating -import cafe.adriel.voyager.core.model.StateScreenModel import cafe.adriel.voyager.core.model.screenModelScope import com.komoju.android.sdk.KomojuSDK +import com.komoju.android.sdk.navigation.RouterStateScreenModel import com.komoju.android.sdk.ui.screens.KomojuPaymentRoute import com.komoju.android.sdk.ui.screens.Router import com.komoju.mobile.sdk.entities.Payment import com.komoju.mobile.sdk.remote.apis.KomojuRemoteApi -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch internal class KonbiniAwaitingPaymentScreenModel(private val config: KomojuSDK.Configuration, private val payment: Payment? = null) : - StateScreenModel(KonbiniAwaitingPaymentUiState(payment)) { + RouterStateScreenModel(KonbiniAwaitingPaymentUiState(payment)) { private val komojuApi = KomojuRemoteApi(config.publishableKey, config.language.languageCode) - private val _router = MutableStateFlow(null) - val router = _router.asStateFlow() - - fun onRouteConsumed() { - _router.value = null - } fun onPrimaryButtonClicked() { when (val payment = state.value.payment) { - is Payment.Konbini -> _router.value = Router.Push(KomojuPaymentRoute.WebView(payment.instructionURL, canComeBack = true)) + is Payment.Konbini -> mutableRouter.value = Router.Push(KomojuPaymentRoute.WebView(payment.instructionURL, canComeBack = true)) else -> Unit } } fun onSecondaryButtonClicked() { - when (val payment = state.value.payment) { - is Payment.Konbini -> refreshPayment() - else -> Unit - } +// when (state.value.payment) { +// is Payment.Konbini -> refreshPayment() +// else -> Unit +// } + mutableRouter.value = Router.Pop } fun refreshPayment() { diff --git a/android/src/main/java/com/komoju/android/sdk/ui/screens/failed/PaymentFailedScreen.kt b/android/src/main/java/com/komoju/android/sdk/ui/screens/failed/PaymentFailedScreen.kt index 71a5825..3412cb2 100644 --- a/android/src/main/java/com/komoju/android/sdk/ui/screens/failed/PaymentFailedScreen.kt +++ b/android/src/main/java/com/komoju/android/sdk/ui/screens/failed/PaymentFailedScreen.kt @@ -1,6 +1,5 @@ package com.komoju.android.sdk.ui.screens.failed -import androidx.activity.compose.LocalOnBackPressedDispatcherOwner import androidx.compose.foundation.Image import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box @@ -19,14 +18,15 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import cafe.adriel.voyager.core.model.rememberScreenModel import cafe.adriel.voyager.core.screen.Screen import com.komoju.android.sdk.R import com.komoju.android.sdk.ui.composables.PrimaryButton import com.komoju.android.sdk.ui.screens.KomojuPaymentRoute -import com.komoju.android.sdk.ui.theme.KomojuMobileSdkTheme +import com.komoju.android.sdk.ui.screens.RouterEffect import com.komoju.android.sdk.ui.theme.LocalI18nTexts internal class PaymentFailedScreen(private val route: KomojuPaymentRoute.PaymentFailed) : Screen { @@ -43,9 +43,10 @@ enum class Reason { } @Composable -private fun PaymentFailedScreenContent(route: KomojuPaymentRoute.PaymentFailed) { - val onBackPressDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher +private fun Screen.PaymentFailedScreenContent(route: KomojuPaymentRoute.PaymentFailed) { val i18nTexts = LocalI18nTexts.current + val screenModel = rememberScreenModel { PaymentFailedScreenModel() } + RouterEffect(screenModel.router.collectAsStateWithLifecycle(), screenModel::onRouteConsumed) Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.CenterEnd) { Icon( @@ -53,9 +54,7 @@ private fun PaymentFailedScreenContent(route: KomojuPaymentRoute.PaymentFailed) "Close Button", modifier = Modifier .padding(16.dp) - .clickable { - onBackPressDispatcher?.onBackPressed() - }, + .clickable(onClick = screenModel::onCloseButtonClicked), ) } Image(painterResource(R.drawable.komoju_ic_payment_status_failed), "status_icon") @@ -77,15 +76,7 @@ private fun PaymentFailedScreenContent(route: KomojuPaymentRoute.PaymentFailed) .padding(16.dp), text = i18nTexts["BACK_TO_STORE"], ) { - onBackPressDispatcher?.onBackPressed() + screenModel.onBackToStoreButtonClicked() } } } - -@Composable -@Preview -private fun PaymentSuccessScreenContentPreview() { - KomojuMobileSdkTheme { - PaymentFailedScreenContent(KomojuPaymentRoute.PaymentFailed(Reason.USER_CANCEL)) - } -} diff --git a/android/src/main/java/com/komoju/android/sdk/ui/screens/failed/PaymentFailedScreenModel.kt b/android/src/main/java/com/komoju/android/sdk/ui/screens/failed/PaymentFailedScreenModel.kt new file mode 100644 index 0000000..8f1fdcc --- /dev/null +++ b/android/src/main/java/com/komoju/android/sdk/ui/screens/failed/PaymentFailedScreenModel.kt @@ -0,0 +1,13 @@ +package com.komoju.android.sdk.ui.screens.failed + +import com.komoju.android.sdk.navigation.RouterStateScreenModel + +internal class PaymentFailedScreenModel : RouterStateScreenModel(Unit) { + fun onCloseButtonClicked() { + mutableRouter.pop() + } + + fun onBackToStoreButtonClicked() { + mutableRouter.pop() + } +} diff --git a/android/src/main/java/com/komoju/android/sdk/ui/screens/payment/KomojuPaymentScreen.kt b/android/src/main/java/com/komoju/android/sdk/ui/screens/payment/KomojuPaymentScreen.kt index ea37acc..072ef23 100644 --- a/android/src/main/java/com/komoju/android/sdk/ui/screens/payment/KomojuPaymentScreen.kt +++ b/android/src/main/java/com/komoju/android/sdk/ui/screens/payment/KomojuPaymentScreen.kt @@ -1,7 +1,6 @@ package com.komoju.android.sdk.ui.screens.payment import android.os.Parcelable -import androidx.activity.compose.LocalOnBackPressedDispatcherOwner import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable @@ -41,19 +40,16 @@ internal data class KomojuPaymentScreen(private val sdkConfiguration: KomojuSDK. override fun Content() { val screenViewModel = rememberScreenModel { KomojuPaymentScreenModel(sdkConfiguration) } val uiState by screenViewModel.state.collectAsStateWithLifecycle() - val router by screenViewModel.router.collectAsStateWithLifecycle() - val onBackPressDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher LaunchedEffect(sdkConfiguration.sessionId) { screenViewModel.init() } - RouterEffect(router, screenViewModel::onRouteHandled) - + RouterEffect(screenViewModel.router.collectAsStateWithLifecycle(), screenViewModel::onRouteConsumed) Box { if (uiState.session != null) { Column { Column(modifier = Modifier.verticalScroll(rememberScrollState())) { PaymentSheetHandle(LocalI18nTexts.current["PAYMENT_OPTIONS"], onCloseClicked = { - onBackPressDispatcher?.onBackPressed() + screenViewModel.onCloseClicked() }) PaymentMethodsRow( paymentMethods = uiState.session!!.paymentMethods, diff --git a/android/src/main/java/com/komoju/android/sdk/ui/screens/payment/KomojuPaymentScreenModel.kt b/android/src/main/java/com/komoju/android/sdk/ui/screens/payment/KomojuPaymentScreenModel.kt index 0a90e96..de5a474 100644 --- a/android/src/main/java/com/komoju/android/sdk/ui/screens/payment/KomojuPaymentScreenModel.kt +++ b/android/src/main/java/com/komoju/android/sdk/ui/screens/payment/KomojuPaymentScreenModel.kt @@ -1,8 +1,8 @@ package com.komoju.android.sdk.ui.screens.payment -import cafe.adriel.voyager.core.model.StateScreenModel import cafe.adriel.voyager.core.model.screenModelScope import com.komoju.android.sdk.KomojuSDK +import com.komoju.android.sdk.navigation.RouterStateScreenModel import com.komoju.android.sdk.ui.screens.KomojuPaymentRoute import com.komoju.android.sdk.ui.screens.Router import com.komoju.android.sdk.ui.screens.failed.Reason @@ -21,17 +21,12 @@ import com.komoju.mobile.sdk.entities.SecureTokenResponse.Status.OK import com.komoju.mobile.sdk.entities.SecureTokenResponse.Status.SKIPPED import com.komoju.mobile.sdk.entities.SecureTokenResponse.Status.UNKNOWN import com.komoju.mobile.sdk.remote.apis.KomojuRemoteApi -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch -internal class KomojuPaymentScreenModel(private val config: KomojuSDK.Configuration) : StateScreenModel(KomojuPaymentUIState()) { +internal class KomojuPaymentScreenModel(private val config: KomojuSDK.Configuration) : RouterStateScreenModel(KomojuPaymentUIState()) { private val komojuApi: KomojuRemoteApi = KomojuRemoteApi(config.publishableKey, config.language.languageCode) - private val _router = MutableStateFlow(null) - val router = _router.asStateFlow() - fun init() { val sessionId = config.sessionId if (sessionId != null) { @@ -114,26 +109,26 @@ internal class KomojuPaymentScreenModel(private val config: KomojuSDK.Configurat komojuApi.tokens.generateSecureToken(request).onSuccess { when (it.status) { OK, SKIPPED -> - _router.value = + mutableRouter.value = Router.ReplaceAll( KomojuPaymentRoute.ProcessPayment( config, processType = KomojuPaymentRoute.ProcessPayment.ProcessType.PayByToken(it.id, request.amount, request.currency), ), ) - NEEDS_VERIFY -> _router.value = Router.ReplaceAll(KomojuPaymentRoute.WebView(url = it.authURL, isJavaScriptEnabled = true)) - ERRORED, UNKNOWN -> _router.value = Router.ReplaceAll(KomojuPaymentRoute.PaymentFailed(Reason.CREDIT_CARD_ERROR)) + NEEDS_VERIFY -> mutableRouter.value = Router.ReplaceAll(KomojuPaymentRoute.WebView(url = it.authURL, isJavaScriptEnabled = true)) + ERRORED, UNKNOWN -> mutableRouter.value = Router.ReplaceAll(KomojuPaymentRoute.PaymentFailed(Reason.CREDIT_CARD_ERROR)) } }.onFailure { - _router.value = Router.ReplaceAll(KomojuPaymentRoute.PaymentFailed(Reason.CREDIT_CARD_ERROR)) + mutableRouter.value = Router.ReplaceAll(KomojuPaymentRoute.PaymentFailed(Reason.CREDIT_CARD_ERROR)) } } } private fun Payment.handle() { when (this) { - is Payment.Konbini -> _router.value = Router.Replace(KomojuPaymentRoute.KonbiniAwaitingPayment(config, payment = this)) - is Payment.PayPay -> _router.value = Router.Handle(url = redirectURL) + is Payment.Konbini -> mutableRouter.value = Router.Replace(KomojuPaymentRoute.KonbiniAwaitingPayment(config, payment = this)) + is Payment.PayPay -> mutableRouter.value = Router.Handle(url = redirectURL) else -> Unit } } @@ -219,7 +214,7 @@ internal class KomojuPaymentScreenModel(private val config: KomojuSDK.Configurat is PaymentMethod.WebMoney -> TODO() } - fun onRouteHandled() { - _router.value = null + fun onCloseClicked() { + mutableRouter.pop() } } diff --git a/android/src/main/java/com/komoju/android/sdk/ui/screens/verify/ProcessPaymentScreen.kt b/android/src/main/java/com/komoju/android/sdk/ui/screens/verify/ProcessPaymentScreen.kt index 5b732fb..8df74ed 100644 --- a/android/src/main/java/com/komoju/android/sdk/ui/screens/verify/ProcessPaymentScreen.kt +++ b/android/src/main/java/com/komoju/android/sdk/ui/screens/verify/ProcessPaymentScreen.kt @@ -24,11 +24,10 @@ internal class ProcessPaymentScreen(private val route: KomojuPaymentRoute.Proces @Composable private fun Screen.VerifyPaymentScreenContent(route: KomojuPaymentRoute.ProcessPayment) { val screenViewModel = rememberScreenModel { VerifyPaymentScreenModel(route.configuration) } - val router by screenViewModel.router.collectAsStateWithLifecycle() LaunchedEffect(Unit) { screenViewModel.process(route.processType) } - RouterEffect(router, screenViewModel::onRouteHandled) + RouterEffect(screenViewModel.router.collectAsStateWithLifecycle(), screenViewModel::onRouteConsumed) Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { ThemedCircularProgressIndicator() } diff --git a/android/src/main/java/com/komoju/android/sdk/ui/screens/verify/VerifyPaymentScreenModel.kt b/android/src/main/java/com/komoju/android/sdk/ui/screens/verify/VerifyPaymentScreenModel.kt index 02a730b..bef9dcd 100644 --- a/android/src/main/java/com/komoju/android/sdk/ui/screens/verify/VerifyPaymentScreenModel.kt +++ b/android/src/main/java/com/komoju/android/sdk/ui/screens/verify/VerifyPaymentScreenModel.kt @@ -1,24 +1,19 @@ package com.komoju.android.sdk.ui.screens.verify -import cafe.adriel.voyager.core.model.ScreenModel import cafe.adriel.voyager.core.model.screenModelScope import com.komoju.android.sdk.KomojuSDK +import com.komoju.android.sdk.navigation.RouterStateScreenModel import com.komoju.android.sdk.ui.screens.KomojuPaymentRoute import com.komoju.android.sdk.ui.screens.Router import com.komoju.android.sdk.ui.screens.failed.Reason import com.komoju.mobile.sdk.entities.PaymentStatus import com.komoju.mobile.sdk.remote.apis.KomojuRemoteApi -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch -internal class VerifyPaymentScreenModel(private val config: KomojuSDK.Configuration) : ScreenModel { +internal class VerifyPaymentScreenModel(private val config: KomojuSDK.Configuration) : RouterStateScreenModel(Unit) { private val komojuApi: KomojuRemoteApi = KomojuRemoteApi(config.publishableKey, config.language.languageCode) - private val _router = MutableStateFlow(null) - val router = _router.asStateFlow() - fun process(type: KomojuPaymentRoute.ProcessPayment.ProcessType) { screenModelScope.launch { when (type) { @@ -31,20 +26,26 @@ internal class VerifyPaymentScreenModel(private val config: KomojuSDK.Configurat private suspend fun processBySession() { komojuApi.sessions.verifyPaymentBySessionID(config.sessionId.orEmpty()).onSuccess { paymentDetails -> - _router.value = when (paymentDetails.status) { + mutableRouter.value = when (paymentDetails.status) { PaymentStatus.COMPLETED, PaymentStatus.CAPTURED -> Router.ReplaceAll(KomojuPaymentRoute.PaymentSuccess) else -> Router.ReplaceAll(KomojuPaymentRoute.PaymentFailed(Reason.OTHER)) } }.onFailure { - _router.value = Router.ReplaceAll(KomojuPaymentRoute.PaymentFailed(Reason.OTHER)) + mutableRouter.value = Router.ReplaceAll(KomojuPaymentRoute.PaymentFailed(Reason.OTHER)) } } private suspend fun payByToken(token: String, amount: String, currency: String) { komojuApi.sessions.pay(config.sessionId.orEmpty(), token, amount, currency).onSuccess { response -> - if (response.status == PaymentStatus.CAPTURED) processBySession() else _router.value = Router.ReplaceAll(KomojuPaymentRoute.PaymentFailed(Reason.CREDIT_CARD_ERROR)) + if (response.status == + PaymentStatus.CAPTURED + ) { + processBySession() + } else { + mutableRouter.value = Router.ReplaceAll(KomojuPaymentRoute.PaymentFailed(Reason.CREDIT_CARD_ERROR)) + } }.onFailure { - _router.value = Router.ReplaceAll(KomojuPaymentRoute.PaymentFailed(Reason.CREDIT_CARD_ERROR)) + mutableRouter.value = Router.ReplaceAll(KomojuPaymentRoute.PaymentFailed(Reason.CREDIT_CARD_ERROR)) } } @@ -53,15 +54,11 @@ internal class VerifyPaymentScreenModel(private val config: KomojuSDK.Configurat if (isVerifiedByToken) { with(verifyTokenAndPay) { payByToken(token, amount, currency) } } else { - _router.value = + mutableRouter.value = Router.ReplaceAll(KomojuPaymentRoute.PaymentFailed(Reason.CREDIT_CARD_ERROR)) } }.onFailure { - _router.value = Router.ReplaceAll(KomojuPaymentRoute.PaymentFailed(Reason.CREDIT_CARD_ERROR)) + mutableRouter.value = Router.ReplaceAll(KomojuPaymentRoute.PaymentFailed(Reason.CREDIT_CARD_ERROR)) } } - - fun onRouteHandled() { - _router.value = null - } } diff --git a/android/src/main/java/com/komoju/android/sdk/ui/screens/webview/WebViewScreen.kt b/android/src/main/java/com/komoju/android/sdk/ui/screens/webview/WebViewScreen.kt index a7f21ef..615c53a 100644 --- a/android/src/main/java/com/komoju/android/sdk/ui/screens/webview/WebViewScreen.kt +++ b/android/src/main/java/com/komoju/android/sdk/ui/screens/webview/WebViewScreen.kt @@ -28,6 +28,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -37,6 +38,7 @@ import com.kevinnzou.web.LoadingState import com.kevinnzou.web.WebView import com.kevinnzou.web.rememberWebViewState import com.komoju.android.sdk.ui.screens.KomojuPaymentRoute +import com.komoju.android.sdk.ui.theme.LocalConfigurableTheme internal data class WebViewScreen(val route: KomojuPaymentRoute.WebView) : Screen { @Composable @@ -107,13 +109,21 @@ private fun WebViewScreenContent(route: KomojuPaymentRoute.WebView) { LinearProgressIndicator( progress = { loadingState.progress }, modifier = Modifier.fillMaxWidth(), + color = Color(LocalConfigurableTheme.current.loaderColor), ) } WebView( - modifier = Modifier.fillMaxSize().background(MaterialTheme.colorScheme.surface), + modifier = Modifier + .fillMaxSize() + .background(MaterialTheme.colorScheme.surface), state = state, - onCreated = { - it.settings.javaScriptEnabled = route.isJavaScriptEnabled + onCreated = { nativeWebView -> + nativeWebView.clipToOutline = true + nativeWebView.setBackgroundColor(android.graphics.Color.TRANSPARENT) + nativeWebView.settings.apply { + domStorageEnabled = true + javaScriptEnabled = route.isJavaScriptEnabled + } }, captureBackPresses = false, chromeClient = remember { WebChromeClient() },