Skip to content

Commit

Permalink
Konbini Payments
Browse files Browse the repository at this point in the history
  • Loading branch information
AmniX committed Sep 17, 2024
1 parent cab131f commit a53a940
Show file tree
Hide file tree
Showing 41 changed files with 1,042 additions and 152 deletions.
6 changes: 6 additions & 0 deletions android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
alias(libs.plugins.androidLibrary)
alias(libs.plugins.kotlinAndroid)
alias(libs.plugins.compose.compiler)
alias(libs.plugins.kotlin.plugin.serialization)
id("kotlin-parcelize")
}

Expand Down Expand Up @@ -57,6 +58,7 @@ dependencies {
implementation(libs.material)
implementation(libs.kotlinx.coroutines.android)
implementation(libs.kotlinx.datetime)
implementation(libs.kotlinx.serialization.json)
implementation(libs.lifecycle.runtime.ktx)
implementation(libs.lifecycle.viewmodel.compose)
implementation(libs.activity.compose)
Expand All @@ -66,6 +68,10 @@ dependencies {
implementation(libs.ui.graphics)
implementation(libs.ui.tooling.preview)
implementation(libs.material3)
implementation(libs.compose.webview)
implementation(libs.voyager.navigator)
implementation(libs.voyager.screenModel)
implementation(libs.voyager.transitions)
testImplementation(libs.junit)
androidTestImplementation(libs.ext.junit)
androidTestImplementation(libs.espresso.core)
Expand Down
1 change: 1 addition & 0 deletions android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<application>
<activity
android:name=".KomojuPaymentActivity"
android:launchMode="singleInstance"
android:theme="@style/Komoju.Transparent.Activity" />
</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -1,38 +1,54 @@
package com.degica.komoju.android.sdk

import android.annotation.SuppressLint
import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.material3.Surface
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.core.content.IntentCompat
import com.degica.komoju.android.sdk.ui.screens.KomojuPaymentScreenNavHost
import androidx.lifecycle.ViewModel
import androidx.lifecycle.lifecycleScope
import cafe.adriel.voyager.navigator.Navigator
import cafe.adriel.voyager.transitions.SlideTransition
import com.degica.komoju.android.sdk.ui.screens.payment.KomojuPaymentScreen
import com.degica.komoju.android.sdk.ui.theme.KomojuMobileSdkTheme
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch

private const val ANIMATION_DURATION = 400
private const val ANIMATION_DURATION = 500

internal class KomojuPaymentViewModel : ViewModel() {
private val _isVisible = MutableStateFlow(false)
val isVisible = _isVisible.asStateFlow()

fun toggleVisiblity(value: Boolean){
_isVisible.value = value
}
}

internal class KomojuPaymentActivity : ComponentActivity() {
private val viewModel by viewModels<KomojuPaymentViewModel>()

private val configuration: KomojuSDK.Configuration by lazy {
IntentCompat.getParcelableExtra(
Expand All @@ -48,17 +64,16 @@ internal class KomojuPaymentActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
var isClosed by remember { mutableStateOf(true) }
val isVisible by viewModel.isVisible.collectAsState()
val animatedAlpha by animateFloatAsState(
targetValue = if (isClosed) .0f else .3f,
targetValue = if (isVisible) .3f else .0f,
label = "scrim_alpha_animation",
animationSpec = tween(durationMillis = ANIMATION_DURATION),
)
val coroutineScope = rememberCoroutineScope()
Surface(modifier = Modifier.fillMaxSize(), color = Color.Black.copy(alpha = animatedAlpha)) {
AnimatedVisibility(
isClosed.not(),
enter = slideInVertically(animationSpec = tween(ANIMATION_DURATION)) { it },
isVisible,
enter = slideInVertically(animationSpec = tween(ANIMATION_DURATION, easing = LinearEasing)) { it },
exit = slideOutVertically(
animationSpec = tween(ANIMATION_DURATION),
) { it },
Expand All @@ -71,36 +86,37 @@ internal class KomojuPaymentActivity : ComponentActivity() {
contentAlignment = Alignment.BottomCenter,
) {
KomojuMobileSdkTheme(configuration.language) {
KomojuPaymentScreenNavHost(
configuration,
onCompleted = {
coroutineScope.launch {
isClosed = true
delay(ANIMATION_DURATION.toLong()) // Let the animation finish
finish()
}
},
)
Box(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight(.9f),
) {
Navigator(
KomojuPaymentScreen(configuration),
) { navigator ->
SlideTransition(navigator)
}
}
}
}
}
}
LaunchedEffect(Unit) {
isClosed = false
viewModel.toggleVisiblity(true)
}
}
}

override fun finish() {
super.finish()
// TODO: Set Result
private fun handleIntentAction(intent: Intent, navigator: Navigator) {
// Handle onNewIntent
}

@SuppressLint("MissingSuperCall")
@Deprecated(
"This method has been deprecated in favor of using the\n {@link OnBackPressedDispatcher} via {@link #getOnBackPressedDispatcher()}.\n The OnBackPressedDispatcher controls how back button events are dispatched\n to one or more {@link OnBackPressedCallback} objects.",
)
override fun onBackPressed() {
// super.onBackPressed()
override fun finish() {
lifecycleScope.launch {
viewModel.toggleVisiblity(false)
delay(ANIMATION_DURATION.toLong()) // Let the animation finish
super.finish()
}
// TODO: Set Result
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.degica.komoju.android.sdk.ui.screens.payment.composables
package com.degica.komoju.android.sdk.ui.composables

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
Expand All @@ -18,7 +18,7 @@ import com.degica.komoju.android.sdk.ui.theme.Blue600
import com.degica.komoju.android.sdk.ui.theme.KomojuMobileSdkTheme

@Composable
internal fun PaymentButton(text: String, modifier: Modifier = Modifier, onClick: () -> Unit) {
internal fun PrimaryButton(text: String, modifier: Modifier = Modifier, onClick: () -> Unit) {
Button(
modifier = modifier,
onClick = onClick,
Expand All @@ -33,7 +33,7 @@ internal fun PaymentButton(text: String, modifier: Modifier = Modifier, onClick:
@Preview(showBackground = true, showSystemUi = true)
private fun PaymentButtonPreview() {
KomojuMobileSdkTheme(language = Language.ENGLISH) {
PaymentButton(
PrimaryButton(
modifier = Modifier
.padding(16.dp)
.fillMaxWidth(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.degica.komoju.android.sdk.ui.composables

import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp

@Composable
internal fun TextButton(modifier : Modifier = Modifier, text: String, onClick: () -> Unit) {
Button(
modifier = modifier,
onClick = onClick,
colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.surface, contentColor = Color.Black),
shape = RoundedCornerShape(8.dp),
) {
Text(modifier = Modifier.padding(8.dp), text = text, style = TextStyle(fontWeight = FontWeight.Normal), maxLines = 1)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.degica.komoju.android.sdk.ui.screens

import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import com.degica.komoju.android.sdk.KomojuSDK
import com.degica.komoju.android.sdk.ui.screens.status.PaymentStatusScreen
import com.degica.komoju.android.sdk.ui.screens.webview.WebViewScreen
import com.degica.komoju.mobile.sdk.entities.Payment

internal sealed class Router {
data object Pop : Router()
data object PopToRoot : Router()
data class Push(val route: KomojuPaymentRoute) : Router()
data class Replace(val route: KomojuPaymentRoute) : Router()
data class ReplaceAll(val route: KomojuPaymentRoute) : Router()
}

internal sealed interface KomojuPaymentRoute {
data class Status(val configuration: KomojuSDK.Configuration, val payment: Payment) : KomojuPaymentRoute
data class WebView(val url: String, val canComeBack: Boolean = false) : KomojuPaymentRoute

val screen
get() = when (this) {
is WebView -> WebViewScreen(this)
is Status -> PaymentStatusScreen(this)
}
}

@Composable
internal fun RouterEffect(router: Router?, onHandled: () -> Unit) {
val navigator = LocalNavigator.currentOrThrow
LaunchedEffect(router) {
when (router) {
is Router.Pop -> navigator.pop()
is Router.PopToRoot -> navigator.popUntilRoot()
is Router.Push -> navigator.push(router.route.screen)
is Router.Replace -> navigator.replace(router.route.screen)
is Router.ReplaceAll -> navigator.replaceAll(router.route.screen)
null -> Unit
}
onHandled()
}
}

This file was deleted.

Loading

0 comments on commit a53a940

Please sign in to comment.