From 6a6be051a0862bd944ac59e6eaea70b87d04b0f0 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Tue, 10 Dec 2024 15:23:28 +0100 Subject: [PATCH 01/17] Show subtitles for `processing` and `capturing` states --- .../home/totals/WooPosTotalsViewModel.kt | 29 +++++++++++-------- WooCommerce/src/main/res/values/strings.xml | 1 + 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModel.kt index 1e7b1d09aab..fe01fffe7ec 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModel.kt @@ -237,13 +237,12 @@ class WooPosTotalsViewModel @Inject constructor( cardReaderPaymentController?.paymentState?.collect { paymentState -> when (paymentState) { is CardReaderPaymentState.CollectingPayment -> handleCollectingPaymentState() - is CardReaderPaymentState.LoadingData -> - handleReaderLoadingPaymentState() + + is CardReaderPaymentState.LoadingData -> handleReaderLoadingPaymentState() is CardReaderPaymentState.ProcessingPayment, - is CardReaderPaymentState.PaymentCapturing, - CardReaderPaymentState.ReFetchingOrder -> { - uiState.value = buildPaymentProcessingState() + is CardReaderPaymentState.PaymentCapturing -> { + uiState.value = buildPaymentProcessingState(paymentState) childrenToParentEventSender.sendToParent(ChildToParentEvent.PaymentProcessing) } @@ -260,6 +259,8 @@ class WooPosTotalsViewModel @Inject constructor( childrenToParentEventSender.sendToParent(ChildToParentEvent.PaymentFailed) } + CardReaderPaymentState.ReFetchingOrder -> Unit + is CardReaderPaymentOrRefundState.CardReaderInteracRefundState, is CardReaderPaymentState.PaymentFailed.BuiltInReaderFailedPayment, is CardReaderPaymentState.PrintingReceipt, @@ -335,14 +336,18 @@ class WooPosTotalsViewModel @Inject constructor( ) } - private fun buildPaymentProcessingState(): PaymentProcessing = PaymentProcessing( - title = resourceProvider.getString( - R.string.woopos_success_totals_payment_processing_title - ), - subtitle = resourceProvider.getString( - R.string.woopos_success_totals_payment_processing_subtitle + private fun buildPaymentProcessingState(paymentState: CardReaderPaymentOrRefundState): PaymentProcessing { + val subtitle = when (paymentState) { + is CardReaderPaymentState.ProcessingPayment -> R.string.woo_pos_payment_remove_card + else -> R.string.woopos_success_totals_payment_processing_subtitle + } + return PaymentProcessing( + title = resourceProvider.getString( + R.string.woopos_success_totals_payment_processing_title + ), + subtitle = resourceProvider.getString(subtitle) ) - ) + } private fun createOrderDraft(productIds: List) { viewModelScope.launch { diff --git a/WooCommerce/src/main/res/values/strings.xml b/WooCommerce/src/main/res/values/strings.xml index 76dc1bb7ec7..f96a0559988 100644 --- a/WooCommerce/src/main/res/values/strings.xml +++ b/WooCommerce/src/main/res/values/strings.xml @@ -4312,6 +4312,7 @@ Try another payment method Try payment again Go back to checkout + Remove card Dimmed background. Tap to close the menu. Card reader connected From 052db516841ea79e95a6519ff80bf81d50b20daa Mon Sep 17 00:00:00 2001 From: samiuelson Date: Tue, 10 Dec 2024 16:49:03 +0100 Subject: [PATCH 02/17] Show lottie animations for payment capturing and processing --- WooCommerce/build.gradle | 3 + .../ui/woopos/common/composeui/WooPosTheme.kt | 3 + .../home/totals/WooPosTotalsViewModel.kt | 5 +- .../WooPosTotalsPaymentProcessingScreen.kt | 39 +- .../main/res/raw/woopos_card_ilustration.json | 4272 +++++++++++++++++ gradle.properties | 14 +- gradle/libs.versions.toml | 2 + 7 files changed, 4331 insertions(+), 7 deletions(-) create mode 100644 WooCommerce/src/main/res/raw/woopos_card_ilustration.json diff --git a/WooCommerce/build.gradle b/WooCommerce/build.gradle index 90aa0fbff66..4127e6c2b17 100644 --- a/WooCommerce/build.gradle +++ b/WooCommerce/build.gradle @@ -479,6 +479,9 @@ dependencies { coreLibraryDesugaring(libs.android.desugar) + // Lottie + implementation(libs.lottie.compose) + // CameraX implementation(libs.androidx.camera.camera2) implementation(libs.androidx.camera.lifecycle) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/composeui/WooPosTheme.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/composeui/WooPosTheme.kt index bd24abaddf6..a816614d677 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/composeui/WooPosTheme.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/composeui/WooPosTheme.kt @@ -24,6 +24,7 @@ data class CustomColors( val paymentProcessingBackground: Color, val paymentSuccessText: Color, val paymentSuccessIcon: Color, + val paymentProcessingText: Color, val dialogSubtitleHighlightBackground: Color = Color(0x14747480), val homeBackground: Color, ) @@ -196,6 +197,7 @@ private val DarkCustomColors = CustomColors( paymentSuccessBackground = WooPosColors.darkCustomColorsHomeBackground, paymentSuccessText = WooPosColors.oldGrayLight, paymentSuccessIcon = WooPosColors.darkCustomColorsHomeBackground, + paymentProcessingText = WooPosColors.White, homeBackground = WooPosColors.darkCustomColorsHomeBackground, paymentProcessingBackground = WooPosColors.WooPurple70, ) @@ -209,6 +211,7 @@ private val LightCustomColors = CustomColors( totalsBackground = WooPosColors.Gray0, paymentSuccessBackground = WooPosColors.White, paymentSuccessText = WooPosColors.Purple90, + paymentProcessingText = WooPosColors.White, paymentSuccessIcon = Color.White, homeBackground = WooPosColors.Gray0, paymentProcessingBackground = WooPosColors.WooPurple70, diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModel.kt index fe01fffe7ec..3ac508939ff 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModel.kt @@ -247,10 +247,7 @@ class WooPosTotalsViewModel @Inject constructor( } is CardReaderPaymentState.PaymentSuccessful -> { - uiState.value = - PaymentSuccess( - orderTotalText = paymentState.amountWithCurrencyLabel - ) + uiState.value = PaymentSuccess(orderTotalText = paymentState.amountWithCurrencyLabel) childrenToParentEventSender.sendToParent(ChildToParentEvent.OrderSuccessfullyPaid) } diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt index 72d7af39682..f8d2a8f23fa 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt @@ -4,13 +4,28 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import com.airbnb.lottie.compose.LottieAnimation +import com.airbnb.lottie.compose.LottieClipSpec +import com.airbnb.lottie.compose.LottieCompositionSpec +import com.airbnb.lottie.compose.LottieConstants +import com.airbnb.lottie.compose.rememberLottieComposition +import com.woocommerce.android.R import com.woocommerce.android.ui.woopos.common.composeui.WooPosPreview import com.woocommerce.android.ui.woopos.common.composeui.WooPosTheme +import com.woocommerce.android.ui.woopos.common.composeui.toAdaptivePadding import com.woocommerce.android.ui.woopos.home.totals.WooPosTotalsViewState @Composable @@ -28,8 +43,28 @@ fun WooPosPaymentProcessingScreen( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center, ) { - Text(text = state.title) - Text(text = state.subtitle) + Spacer(modifier = Modifier.height(16.dp.toAdaptivePadding())) + val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.woopos_card_ilustration)) + LottieAnimation( + modifier = Modifier.size(256.dp).padding(0.dp), + composition = composition, + iterations = LottieConstants.IterateForever, + clipToCompositionBounds = false, + clipSpec = LottieClipSpec.Markers("payment_processing_start", "payment_processing_end") + ) + Text( + text = state.title, + color = WooPosTheme.colors.paymentProcessingText, + style = MaterialTheme.typography.body1, + ) + Spacer(modifier = Modifier.height(16.dp.toAdaptivePadding())) + Text( + text = state.subtitle, + color = WooPosTheme.colors.paymentProcessingText, + style = MaterialTheme.typography.h4, + fontWeight = FontWeight.Bold, + ) + Spacer(modifier = Modifier.height(16.dp.toAdaptivePadding())) } } } diff --git a/WooCommerce/src/main/res/raw/woopos_card_ilustration.json b/WooCommerce/src/main/res/raw/woopos_card_ilustration.json new file mode 100644 index 00000000000..dfb1eed24fd --- /dev/null +++ b/WooCommerce/src/main/res/raw/woopos_card_ilustration.json @@ -0,0 +1,4272 @@ +{ + "v": "4.8.0", + "meta": { + "g": "LottieFiles AE 3.5.7", + "a": "", + "k": "", + "d": "", + "tc": "" + }, + "fr": 60, + "ip": 0, + "op": 792, + "w": 495, + "h": 522, + "nm": "card illustration (longer edition)", + "ddd": 0, + "assets": [], + "layers": [ + { + "ddd": 0, + "ind": 1, + "ty": 4, + "nm": "Shape Layer 7", + "sr": 1, + "ks": { + "o": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "t": 711.518, + "s": [ + 0 + ] + }, + { + "t": 720.99609375, + "s": [ + 100 + ] + } + ], + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 255, + 273, + 0 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 86.25, + -11, + 0 + ], + "ix": 1 + }, + "s": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.362, + 0.362, + 0.362 + ], + "y": [ + 1, + 1, + 1 + ] + }, + "o": { + "x": [ + 0.558, + 0.558, + 0.558 + ], + "y": [ + 0, + 0, + 0 + ] + }, + "t": 707.162, + "s": [ + 114, + 114, + 100 + ] + }, + { + "t": 731.337890625, + "s": [ + 160, + 160, + 100 + ] + } + ], + "ix": 6 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "v": [ + [ + 61, + -7.75 + ], + [ + 75.75, + 7 + ], + [ + 106.75, + -30.25 + ] + ], + "c": false + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [ + 0.011764706817, + 0.831372608858, + 0.474509833841, + 1 + ], + "ix": 3 + }, + "o": { + "a": 0, + "k": 100, + "ix": 4 + }, + "w": { + "a": 0, + "k": 13, + "ix": 5 + }, + "lc": 2, + "lj": 2, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 0, + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Shape 1", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "tm", + "s": { + "a": 0, + "k": 0, + "ix": 1 + }, + "e": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.362 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.558 + ], + "y": [ + 0 + ] + }, + "t": 707.162, + "s": [ + 0 + ] + }, + { + "t": 731.337890625, + "s": [ + 100 + ] + } + ], + "ix": 2 + }, + "o": { + "a": 0, + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1", + "mn": "ADBE Vector Filter - Trim", + "hd": false + } + ], + "ip": 2, + "op": 1823, + "st": 2, + "bm": 0 + }, + { + "ddd": 0, + "ind": 2, + "ty": 3, + "nm": "NULL ", + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 0, + "ix": 11 + }, + "r": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.476 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.816 + ], + "y": [ + 0 + ] + }, + "t": 0, + "s": [ + -5 + ] + }, + { + "i": { + "x": [ + 0.373 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 35, + "s": [ + 6 + ] + }, + { + "t": 71, + "s": [ + 0 + ] + } + ], + "ix": 10 + }, + "p": { + "a": 1, + "k": [ + { + "i": { + "x": 0.476, + "y": 1 + }, + "o": { + "x": 0.816, + "y": 0 + }, + "t": 0, + "s": [ + 279.5, + 418, + 0 + ], + "to": [ + 0, + 0, + 0 + ], + "ti": [ + 0, + 0, + 0 + ] + }, + { + "i": { + "x": 0.373, + "y": 1 + }, + "o": { + "x": 0.333, + "y": 0 + }, + "t": 35, + "s": [ + 279.5, + 396, + 0 + ], + "to": [ + 0, + 0, + 0 + ], + "ti": [ + 0, + 0, + 0 + ] + }, + { + "i": { + "x": 0.667, + "y": 0.667 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "t": 71, + "s": [ + 276.5, + 407, + 0 + ], + "to": [ + 0, + 0, + 0 + ], + "ti": [ + 0, + 0, + 0 + ] + }, + { + "i": { + "x": 0.667, + "y": 1 + }, + "o": { + "x": 0.333, + "y": 0 + }, + "t": 73, + "s": [ + 276.5, + 407, + 0 + ], + "to": [ + 0, + 0, + 0 + ], + "ti": [ + 0, + 0, + 0 + ] + }, + { + "i": { + "x": 0.667, + "y": 1 + }, + "o": { + "x": 0.333, + "y": 0 + }, + "t": 140.334, + "s": [ + 276.5, + 417, + 0 + ], + "to": [ + 0, + 0, + 0 + ], + "ti": [ + 0, + 0, + 0 + ] + }, + { + "i": { + "x": 0.667, + "y": 0.667 + }, + "o": { + "x": 0.333, + "y": 0.333 + }, + "t": 207.666, + "s": [ + 276.5, + 407, + 0 + ], + "to": [ + 0, + 0, + 0 + ], + "ti": [ + 0, + 0, + 0 + ] + }, + { + "i": { + "x": 0.667, + "y": 1 + }, + "o": { + "x": 0.333, + "y": 0 + }, + "t": 208, + "s": [ + 276.5, + 407, + 0 + ], + "to": [ + 0, + 0, + 0 + ], + "ti": [ + 0, + 0, + 0 + ] + }, + { + "i": { + "x": 0.667, + "y": 1 + }, + "o": { + "x": 0.333, + "y": 0 + }, + "t": 275.334, + "s": [ + 276.5, + 417, + 0 + ], + "to": [ + 0, + 0, + 0 + ], + "ti": [ + 0, + 0, + 0 + ] + }, + { + "i": { + "x": 0.667, + "y": 0.667 + }, + "o": { + "x": 0.333, + "y": 0.333 + }, + "t": 342.666, + "s": [ + 276.5, + 407, + 0 + ], + "to": [ + 0, + 0, + 0 + ], + "ti": [ + 0, + 0, + 0 + ] + }, + { + "i": { + "x": 0.667, + "y": 1 + }, + "o": { + "x": 0.333, + "y": 0 + }, + "t": 343, + "s": [ + 276.5, + 407, + 0 + ], + "to": [ + 0, + 0, + 0 + ], + "ti": [ + 0, + 0, + 0 + ] + }, + { + "i": { + "x": 0.667, + "y": 1 + }, + "o": { + "x": 0.333, + "y": 0 + }, + "t": 410.334, + "s": [ + 276.5, + 417, + 0 + ], + "to": [ + 0, + 0, + 0 + ], + "ti": [ + 0, + 0, + 0 + ] + }, + { + "t": 477.666015625, + "s": [ + 276.5, + 407, + 0 + ] + } + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 50, + 50, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6 + } + }, + "ao": 0, + "ip": 0, + "op": 2401, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 3, + "ty": 3, + "nm": "NULL CONTROL ", + "parent": 2, + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 0, + "ix": 11 + }, + "r": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.219 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.687 + ], + "y": [ + 0 + ] + }, + "t": 378, + "s": [ + 10 + ] + }, + { + "t": 412, + "s": [ + 0 + ] + } + ], + "ix": 10 + }, + "p": { + "a": 1, + "k": [ + { + "i": { + "x": 0.476, + "y": 1 + }, + "o": { + "x": 0.816, + "y": 0 + }, + "t": 0, + "s": [ + -2.899, + 32.601, + 0 + ], + "to": [ + 0, + 0, + 0 + ], + "ti": [ + 0, + 0, + 0 + ] + }, + { + "i": { + "x": 0.373, + "y": 1 + }, + "o": { + "x": 0.333, + "y": 0 + }, + "t": 28, + "s": [ + -2.899, + -46.399, + 0 + ], + "to": [ + 0, + 0, + 0 + ], + "ti": [ + 0, + 0, + 0 + ] + }, + { + "i": { + "x": 0.833, + "y": 0.833 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "t": 59, + "s": [ + -2.899, + -36.399, + 0 + ], + "to": [ + 0, + 0, + 0 + ], + "ti": [ + 0, + 0, + 0 + ] + }, + { + "i": { + "x": 0.219, + "y": 1 + }, + "o": { + "x": 0.687, + "y": 0 + }, + "t": 378, + "s": [ + -2.899, + -36.399, + 0 + ], + "to": [ + 0, + 0, + 0 + ], + "ti": [ + 0, + 0, + 0 + ] + }, + { + "t": 412, + "s": [ + 23.101, + -90.399, + 0 + ] + } + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 50, + 50, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6 + } + }, + "ao": 0, + "ip": 0, + "op": 2401, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 4, + "ty": 3, + "nm": "NULL CONTROL 1", + "parent": 3, + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 0, + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 1, + "k": [ + { + "i": { + "x": 0.363, + "y": 1 + }, + "o": { + "x": 0.758, + "y": 0 + }, + "t": 678, + "s": [ + -39.5, + 50, + 0 + ], + "to": [ + 0, + 0, + 0 + ], + "ti": [ + 0, + 0, + 0 + ] + }, + { + "t": 710, + "s": [ + 50, + 50, + 0 + ] + } + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 50, + 50, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6 + } + }, + "ao": 0, + "ip": 0, + "op": 2401, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 5, + "ty": 4, + "nm": "Shape Layer 4", + "parent": 4, + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 50, + 50, + 0 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + -81.399, + 67.601, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "d": 1, + "ty": "el", + "s": { + "a": 0, + "k": [ + 248.201, + 248.201 + ], + "ix": 2 + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 3 + }, + "nm": "Ellipse Path 1", + "mn": "ADBE Vector Shape - Ellipse", + "hd": false + }, + { + "ty": "tm", + "s": { + "a": 0, + "k": 44, + "ix": 1 + }, + "e": { + "a": 0, + "k": 56, + "ix": 2 + }, + "o": { + "a": 0, + "k": -90, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1", + "mn": "ADBE Vector Filter - Trim", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "t": 425, + "s": [ + 0.403921598547, + 0.262745098039, + 0.6, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0 + ] + }, + "t": 438, + "s": [ + 0.533333361149, + 0.384313762188, + 0.764705955982, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 470, + "s": [ + 0.533333361149, + 0.384313762188, + 0.764705955982, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 510, + "s": [ + 0.403921598547, + 0.262745098039, + 0.6, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 549, + "s": [ + 0.533333361149, + 0.384313762188, + 0.764705955982, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 589, + "s": [ + 0.403921604156, + 0.262745112181, + 0.600000023842, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 628, + "s": [ + 0.533333361149, + 0.384313762188, + 0.764705955982, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 669, + "s": [ + 0.403921604156, + 0.262745112181, + 0.600000023842, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 708, + "s": [ + 0.533333361149, + 0.384313762188, + 0.764705955982, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0 + ] + }, + "t": 749, + "s": [ + 0.403921604156, + 0.262745112181, + 0.600000023842, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 786, + "s": [ + 0.533333361149, + 0.384313762188, + 0.764705955982, + 1 + ] + }, + { + "t": 827, + "s": [ + 0.403921604156, + 0.262745112181, + 0.600000023842, + 1 + ] + } + ], + "ix": 3 + }, + "o": { + "a": 0, + "k": 100, + "ix": 4 + }, + "w": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 470, + "s": [ + 14 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 510, + "s": [ + 22 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 549, + "s": [ + 14 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 589, + "s": [ + 22 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 628, + "s": [ + 14 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 0.99 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 669, + "s": [ + 22 + ] + }, + { + "t": 690, + "s": [ + 0 + ] + } + ], + "ix": 5 + }, + "lc": 1, + "lj": 1, + "ml": 4, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + -81.399, + 67.601 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 0, + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Ellipse 1", + "np": 4, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 2401, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 6, + "ty": 4, + "nm": "Shape Layer 3", + "parent": 4, + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 50, + 50, + 0 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + -81.399, + 67.601, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "d": 1, + "ty": "el", + "s": { + "a": 0, + "k": [ + 183.201, + 183.201 + ], + "ix": 2 + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 3 + }, + "nm": "Ellipse Path 1", + "mn": "ADBE Vector Shape - Ellipse", + "hd": false + }, + { + "ty": "tm", + "s": { + "a": 0, + "k": 44, + "ix": 1 + }, + "e": { + "a": 0, + "k": 56, + "ix": 2 + }, + "o": { + "a": 0, + "k": -90, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1", + "mn": "ADBE Vector Filter - Trim", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "t": 425, + "s": [ + 0.403921598547, + 0.262745098039, + 0.6, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + -0.612 + ] + }, + "t": 438, + "s": [ + 0.541176497936, + 0.380392193794, + 0.792156934738, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 461, + "s": [ + 0.533333361149, + 0.384313762188, + 0.764705955982, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 501, + "s": [ + 0.403921598547, + 0.262745098039, + 0.6, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 540, + "s": [ + 0.533333361149, + 0.384313762188, + 0.764705955982, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 580, + "s": [ + 0.403921604156, + 0.262745112181, + 0.600000023842, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 619, + "s": [ + 0.533333361149, + 0.384313762188, + 0.764705955982, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 660, + "s": [ + 0.403921604156, + 0.262745112181, + 0.600000023842, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 699, + "s": [ + 0.533333361149, + 0.384313762188, + 0.764705955982, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0 + ] + }, + "t": 740, + "s": [ + 0.403921604156, + 0.262745112181, + 0.600000023842, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 777, + "s": [ + 0.533333361149, + 0.384313762188, + 0.764705955982, + 1 + ] + }, + { + "t": 818, + "s": [ + 0.403921604156, + 0.262745112181, + 0.600000023842, + 1 + ] + } + ], + "ix": 3 + }, + "o": { + "a": 0, + "k": 100, + "ix": 4 + }, + "w": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 461, + "s": [ + 14 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 501, + "s": [ + 22 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 540, + "s": [ + 14 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 580, + "s": [ + 22 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 619, + "s": [ + 14 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 660, + "s": [ + 22 + ] + }, + { + "t": 690, + "s": [ + 0 + ] + } + ], + "ix": 5 + }, + "lc": 1, + "lj": 1, + "ml": 4, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + -81.399, + 67.601 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 0, + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Ellipse 1", + "np": 4, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 2401, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 7, + "ty": 4, + "nm": "Shape Layer 2", + "parent": 4, + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 50, + 50, + 0 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + -81.399, + 67.601, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "d": 1, + "ty": "el", + "s": { + "a": 0, + "k": [ + 116.201, + 116.201 + ], + "ix": 2 + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 3 + }, + "nm": "Ellipse Path 1", + "mn": "ADBE Vector Shape - Ellipse", + "hd": false + }, + { + "ty": "tm", + "s": { + "a": 0, + "k": 44, + "ix": 1 + }, + "e": { + "a": 0, + "k": 56, + "ix": 2 + }, + "o": { + "a": 0, + "k": -90, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1", + "mn": "ADBE Vector Filter - Trim", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "t": 425, + "s": [ + 0.403921598547, + 0.262745098039, + 0.6, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + -0.612 + ] + }, + "t": 438, + "s": [ + 0.541176497936, + 0.380392193794, + 0.792156934738, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 452, + "s": [ + 0.533333361149, + 0.384313762188, + 0.764705955982, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 492, + "s": [ + 0.403921598547, + 0.262745098039, + 0.6, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 531, + "s": [ + 0.533333361149, + 0.384313762188, + 0.764705955982, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 571, + "s": [ + 0.403921604156, + 0.262745112181, + 0.600000023842, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 610, + "s": [ + 0.533333361149, + 0.384313762188, + 0.764705955982, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 651, + "s": [ + 0.403921604156, + 0.262745112181, + 0.600000023842, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 690, + "s": [ + 0.533333361149, + 0.384313762188, + 0.764705955982, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0 + ] + }, + "t": 731, + "s": [ + 0.403921604156, + 0.262745112181, + 0.600000023842, + 1 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 768, + "s": [ + 0.533333361149, + 0.384313762188, + 0.764705955982, + 1 + ] + }, + { + "t": 809, + "s": [ + 0.403921604156, + 0.262745112181, + 0.600000023842, + 1 + ] + } + ], + "ix": 3 + }, + "o": { + "a": 0, + "k": 100, + "ix": 4 + }, + "w": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 452, + "s": [ + 14 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 492, + "s": [ + 22 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 531, + "s": [ + 14 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 571, + "s": [ + 22 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 610, + "s": [ + 14 + ] + }, + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 651, + "s": [ + 22 + ] + }, + { + "t": 690, + "s": [ + 0 + ] + } + ], + "ix": 5 + }, + "lc": 1, + "lj": 1, + "ml": 4, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + -81.399, + 67.601 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 0, + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Ellipse 1", + "np": 4, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 2401, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 8, + "ty": 4, + "nm": "Shape Layer 1", + "parent": 3, + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 50, + 50, + 0 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + -4.77, + 42.309, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ty": "rc", + "d": 1, + "s": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.363, + 0.363 + ], + "y": [ + 1, + 1 + ] + }, + "o": { + "x": [ + 0.758, + 0.758 + ], + "y": [ + 0, + 0 + ] + }, + "t": 672, + "s": [ + 262.461, + 228.617 + ] + }, + { + "t": 717.41796875, + "s": [ + 270, + 270 + ] + } + ], + "ix": 2 + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 3 + }, + "r": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.363 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.758 + ], + "y": [ + 0 + ] + }, + "t": 672, + "s": [ + 28 + ] + }, + { + "t": 717.41796875, + "s": [ + 164 + ] + } + ], + "ix": 4 + }, + "nm": "Rectangle Path 1", + "mn": "ADBE Vector Shape - Rect", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 682.988, + "s": [ + 0.745098039216, + 0.627450980392, + 0.949019667682, + 1 + ] + }, + { + "t": 700.5703125, + "s": [ + 1, + 1, + 1, + 1 + ] + } + ], + "ix": 4 + }, + "o": { + "a": 0, + "k": 100, + "ix": 5 + }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + -4.77, + 42.309 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 0, + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Rectangle 1", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 2401, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 9, + "ty": 3, + "nm": "NULL CONTROL 4", + "parent": 3, + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 0, + "ix": 11 + }, + "r": { + "a": 0, + "k": -10, + "ix": 10 + }, + "p": { + "a": 1, + "k": [ + { + "i": { + "x": 0.562, + "y": 0.562 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "t": 98, + "s": [ + 152.23, + 12.453, + 0 + ], + "to": [ + 5.883, + 0, + 0 + ], + "ti": [ + 0, + -5.883, + 0 + ] + }, + { + "i": { + "x": 0.656, + "y": 0.656 + }, + "o": { + "x": 0.311, + "y": 0.311 + }, + "t": 127.998, + "s": [ + 162.882, + 23.105, + 0 + ], + "to": [ + 0, + 5.883, + 0 + ], + "ti": [ + 5.883, + 0, + 0 + ] + }, + { + "i": { + "x": 0.689, + "y": 0.689 + }, + "o": { + "x": 0.343, + "y": 0.343 + }, + "t": 157.998, + "s": [ + 152.23, + 33.758, + 0 + ], + "to": [ + -5.883, + 0, + 0 + ], + "ti": [ + 0, + 5.883, + 0 + ] + }, + { + "i": { + "x": 0.833, + "y": 0.833 + }, + "o": { + "x": 0.437, + "y": 0.437 + }, + "t": 187.998, + "s": [ + 141.577, + 23.105, + 0 + ], + "to": [ + 0, + -5.883, + 0 + ], + "ti": [ + -5.883, + 0, + 0 + ] + }, + { + "i": { + "x": 0.562, + "y": 0.562 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "t": 218, + "s": [ + 152.23, + 12.453, + 0 + ], + "to": [ + 5.883, + 0, + 0 + ], + "ti": [ + 0, + -5.883, + 0 + ] + }, + { + "i": { + "x": 0.656, + "y": 0.656 + }, + "o": { + "x": 0.311, + "y": 0.311 + }, + "t": 248, + "s": [ + 162.882, + 23.105, + 0 + ], + "to": [ + 0, + 5.883, + 0 + ], + "ti": [ + 5.883, + 0, + 0 + ] + }, + { + "i": { + "x": 0.689, + "y": 0.689 + }, + "o": { + "x": 0.343, + "y": 0.343 + }, + "t": 278, + "s": [ + 152.23, + 33.758, + 0 + ], + "to": [ + -5.883, + 0, + 0 + ], + "ti": [ + 0, + 5.883, + 0 + ] + }, + { + "i": { + "x": 0.833, + "y": 0.833 + }, + "o": { + "x": 0.437, + "y": 0.437 + }, + "t": 308, + "s": [ + 141.577, + 23.105, + 0 + ], + "to": [ + 0, + -5.883, + 0 + ], + "ti": [ + -5.883, + 0, + 0 + ] + }, + { + "i": { + "x": 0.562, + "y": 0.562 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "t": 338, + "s": [ + 152.23, + 12.453, + 0 + ], + "to": [ + 5.883, + 0, + 0 + ], + "ti": [ + 0, + -5.883, + 0 + ] + }, + { + "i": { + "x": 0.656, + "y": 0.656 + }, + "o": { + "x": 0.311, + "y": 0.311 + }, + "t": 368, + "s": [ + 162.882, + 23.105, + 0 + ], + "to": [ + 0, + 5.883, + 0 + ], + "ti": [ + 5.883, + 0, + 0 + ] + }, + { + "i": { + "x": 0.689, + "y": 0.689 + }, + "o": { + "x": 0.343, + "y": 0.343 + }, + "t": 398, + "s": [ + 152.23, + 33.758, + 0 + ], + "to": [ + -5.883, + 0, + 0 + ], + "ti": [ + 0, + 5.883, + 0 + ] + }, + { + "i": { + "x": 0.833, + "y": 0.833 + }, + "o": { + "x": 0.437, + "y": 0.437 + }, + "t": 428, + "s": [ + 141.577, + 23.105, + 0 + ], + "to": [ + 0, + -5.883, + 0 + ], + "ti": [ + -5.883, + 0, + 0 + ] + }, + { + "t": 458, + "s": [ + 152.23, + 12.453, + 0 + ] + } + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 50, + 50, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6 + } + }, + "ao": 0, + "ip": 0, + "op": 2401, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 10, + "ty": 3, + "nm": "NULL CONTROL 3", + "parent": 9, + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 0, + "ix": 11 + }, + "r": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.476 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.816 + ], + "y": [ + 0 + ] + }, + "t": 6, + "s": [ + 30 + ] + }, + { + "i": { + "x": [ + 0.373 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "t": 34, + "s": [ + 50 + ] + }, + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0 + ] + }, + "t": 71, + "s": [ + 41 + ] + }, + { + "i": { + "x": [ + 0.219 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.687 + ], + "y": [ + 0 + ] + }, + "t": 378, + "s": [ + 41 + ] + }, + { + "t": 412, + "s": [ + 13 + ] + } + ], + "ix": 10 + }, + "p": { + "a": 1, + "k": [ + { + "i": { + "x": 0.476, + "y": 1 + }, + "o": { + "x": 0.816, + "y": 0 + }, + "t": 6, + "s": [ + 50, + 114, + 0 + ], + "to": [ + 0, + 0, + 0 + ], + "ti": [ + 0, + 0, + 0 + ] + }, + { + "i": { + "x": 0.373, + "y": 1 + }, + "o": { + "x": 0.333, + "y": 0 + }, + "t": 34, + "s": [ + 50, + 30, + 0 + ], + "to": [ + 0, + 0, + 0 + ], + "ti": [ + 0, + 0, + 0 + ] + }, + { + "i": { + "x": 0.833, + "y": 0.833 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "t": 71, + "s": [ + 50, + 50, + 0 + ], + "to": [ + 0, + 0, + 0 + ], + "ti": [ + 0, + 0, + 0 + ] + }, + { + "i": { + "x": 0.219, + "y": 1 + }, + "o": { + "x": 0.687, + "y": 0 + }, + "t": 378, + "s": [ + 50, + 50, + 0 + ], + "to": [ + 0, + 0, + 0 + ], + "ti": [ + 0, + 0, + 0 + ] + }, + { + "t": 412, + "s": [ + 22, + 120, + 0 + ] + } + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 50, + 50, + 0 + ], + "ix": 1 + }, + "s": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.219, + 0.219, + 0.219 + ], + "y": [ + 1, + 1, + 1 + ] + }, + "o": { + "x": [ + 0.687, + 0.687, + 0.687 + ], + "y": [ + 0, + 0, + 0 + ] + }, + "t": 378, + "s": [ + 110, + 110, + 100 + ] + }, + { + "t": 412, + "s": [ + 98, + 98, + 100 + ] + } + ], + "ix": 6 + } + }, + "ao": 0, + "ip": 0, + "op": 2401, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 11, + "ty": 4, + "nm": "Shape Layer 5", + "parent": 10, + "td": 1, + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + -34.21, + 4.143, + 0 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + -4.77, + 42.309, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ty": "rc", + "d": 1, + "s": { + "a": 0, + "k": [ + 248.461, + 155.617 + ], + "ix": 2 + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 28, + "ix": 4 + }, + "nm": "Rectangle Path 1", + "mn": "ADBE Vector Shape - Rect", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.403921598547, + 0.262745098039, + 0.6, + 1 + ], + "ix": 4 + }, + "o": { + "a": 0, + "k": 100, + "ix": 5 + }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + -4.77, + 42.309 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 0, + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Rectangle 1", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 413, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 12, + "ty": 4, + "nm": "Shape Layer 6", + "parent": 8, + "tt": 1, + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 0, + "k": -17, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 93.808, + 0.822, + 0 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + -4.77, + 42.309, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 110, + 110, + 100 + ], + "ix": 6 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ty": "rc", + "d": 1, + "s": { + "a": 0, + "k": [ + 354.461, + 196.617 + ], + "ix": 2 + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 0, + "ix": 4 + }, + "nm": "Rectangle Path 1", + "mn": "ADBE Vector Shape - Rect", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.20000001496, + 0.137254901961, + 0.337254901961, + 1 + ], + "ix": 4 + }, + "o": { + "a": 0, + "k": 100, + "ix": 5 + }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + -4.77, + 42.309 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 0, + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Rectangle 1", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 413, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 13, + "ty": 4, + "nm": "Shape Layer 8", + "parent": 10, + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + -34.21, + 4.143, + 0 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + -4.77, + 42.309, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ty": "rc", + "d": 1, + "s": { + "a": 0, + "k": [ + 248.461, + 155.617 + ], + "ix": 2 + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 28, + "ix": 4 + }, + "nm": "Rectangle Path 1", + "mn": "ADBE Vector Shape - Rect", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.403921598547, + 0.262745098039, + 0.6, + 1 + ], + "ix": 4 + }, + "o": { + "a": 0, + "k": 100, + "ix": 5 + }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + -4.77, + 42.309 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 0, + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Rectangle 1", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 413, + "st": 0, + "bm": 0 + } + ], + "markers": [ + { + "tm": 0, + "cm": "reader_loading_entry_start", + "dr": 0 + }, + { + "tm": 0, + "cm": "reader_awaiting_start", + "dr": 0 + }, + { + "tm": 0, + "cm": "reader_awaiting_end", + "dr": 0 + }, + { + "tm": 469, + "cm": "payment_processing_start", + "dr": 0 + }, + { + "tm": 619, + "cm": "payment_processing_end", + "dr": 0 + } + ] +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index b5559839f0d..c6ea0229456 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,19 @@ android.useAndroidX=true android.enableJetifier=false android.nonTransitiveRClass=true -android.enableR8.fullMode=false +android.enableR8.fullMode=true # Dependency Analysis Plugin dependency.analysis.android.ignored.variants=release,vanillaDebug,vanillaRelease,wasabiDebug,wasabiRelease,jalapenoRelease + +# Enable Gradle Daemon +org.gradle.daemon=true + +# Enable parallel builds +org.gradle.parallel=true + +# Enable configuration on demand +org.gradle.configureondemand=true + +# Enable incremental compilation +kotlin.incremental=true \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e8b35551339..bc316491db3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -73,6 +73,7 @@ java = '11' jetty-webapp = '9.4.51.v20230217' json-path = '2.9.0' junit = '4.13.2' +lottie = '5.2.0' kotlin = '2.0.21' kotlinx-coroutines = '1.8.1' ksp = '2.0.21-1.0.27' @@ -213,6 +214,7 @@ jackson-databind = { group = "com.fasterxml.jackson.core", name = "jackson-datab jetty-webapp = { group = "org.eclipse.jetty", name = "jetty-webapp", version.ref = "jetty-webapp" } json-path = { group = "com.jayway.jsonpath", name = "json-path", version.ref = "json-path" } junit = { group = "junit", name = "junit", version.ref = "junit" } +lottie-compose = { group = "com.airbnb.android", name = "lottie-compose", version.ref = "lottie" } kotlin-test-junit = { group = "org.jetbrains.kotlin", name = "kotlin-test-junit", version.ref = "kotlin" } kotlinx-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "kotlinx-coroutines" } kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" } From f919b572be3f1863bdb21f46f0ea1b97923228b0 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Tue, 10 Dec 2024 16:54:38 +0100 Subject: [PATCH 03/17] Revert accidental gradle.properties changes --- gradle.properties | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/gradle.properties b/gradle.properties index c6ea0229456..401ad1c005b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,26 +1,12 @@ org.gradle.jvmargs=-Xmx8g ksp.allow.all.target.configuration=false - # Enables Gradle Build Cache - https://docs.gradle.org/current/userguide/build_cache.html org.gradle.caching=true - android.useAndroidX=true android.enableJetifier=false android.nonTransitiveRClass=true -android.enableR8.fullMode=true +android.enableR8.fullMode=false # Dependency Analysis Plugin -dependency.analysis.android.ignored.variants=release,vanillaDebug,vanillaRelease,wasabiDebug,wasabiRelease,jalapenoRelease - -# Enable Gradle Daemon -org.gradle.daemon=true - -# Enable parallel builds -org.gradle.parallel=true - -# Enable configuration on demand -org.gradle.configureondemand=true - -# Enable incremental compilation -kotlin.incremental=true \ No newline at end of file +dependency.analysis.android.ignored.variants=release,vanillaDebug,vanillaRelease,wasabiDebug,wasabiRelease,jalapenoRelease \ No newline at end of file From 4de5bae0bef84457347e2702ed19dc3c889df1e2 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Tue, 10 Dec 2024 18:18:22 +0100 Subject: [PATCH 04/17] Animate "reader ready" state in Totals --- .../ui/woopos/home/totals/WooPosTotalsScreen.kt | 17 ++++++++++++----- .../main/res/raw/woopos_card_ilustration.json | 9 +++++++-- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsScreen.kt index 8d0086c929c..3c1116edae4 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsScreen.kt @@ -26,6 +26,7 @@ import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -36,6 +37,11 @@ import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel +import com.airbnb.lottie.compose.LottieAnimation +import com.airbnb.lottie.compose.LottieClipSpec +import com.airbnb.lottie.compose.LottieCompositionSpec +import com.airbnb.lottie.compose.LottieConstants +import com.airbnb.lottie.compose.rememberLottieComposition import com.woocommerce.android.R import com.woocommerce.android.ui.woopos.common.composeui.WooPosPreview import com.woocommerce.android.ui.woopos.common.composeui.WooPosTheme @@ -176,11 +182,12 @@ private fun PreparingReader(readerStatus: WooPosTotalsViewState.ReaderStatus) { @Composable private fun ReaderReadyForPayment(readerStatus: WooPosTotalsViewState.ReaderStatus) { - Icon( - modifier = Modifier.size(164.dp), - painter = painterResource(id = R.drawable.woopos_ic_collect_payment), - contentDescription = "Collect Payment", - tint = Color.Unspecified, + val tapCardAnimation by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.woopos_card_ilustration)) + LottieAnimation( + modifier = Modifier.size(256.dp).padding(0.dp), + composition = tapCardAnimation, + clipSpec = LottieClipSpec.Markers("reader_awaiting_start", "reader_awaiting_end"), + iterations = LottieConstants.IterateForever, ) Spacer(modifier = Modifier.height(20.dp.toAdaptivePadding())) Text( diff --git a/WooCommerce/src/main/res/raw/woopos_card_ilustration.json b/WooCommerce/src/main/res/raw/woopos_card_ilustration.json index dfb1eed24fd..395a8bf1f9b 100644 --- a/WooCommerce/src/main/res/raw/woopos_card_ilustration.json +++ b/WooCommerce/src/main/res/raw/woopos_card_ilustration.json @@ -4249,12 +4249,17 @@ "dr": 0 }, { - "tm": 0, + "tm": 71, + "cm": "reader_loading_entry_end", + "dr": 0 + }, + { + "tm": 92, "cm": "reader_awaiting_start", "dr": 0 }, { - "tm": 0, + "tm": 337, "cm": "reader_awaiting_end", "dr": 0 }, From 54e65c69a46fe8040ba9f16ff18efeff84423b86 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 11 Dec 2024 12:19:06 +0100 Subject: [PATCH 05/17] Revert accidental change to gradle.properties --- gradle.properties | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 401ad1c005b..a9cdcd14e30 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,10 @@ org.gradle.jvmargs=-Xmx8g ksp.allow.all.target.configuration=false + # Enables Gradle Build Cache - https://docs.gradle.org/current/userguide/build_cache.html org.gradle.caching=true +org.gradle.configuration-cache=true + android.useAndroidX=true android.enableJetifier=false @@ -9,4 +12,4 @@ android.nonTransitiveRClass=true android.enableR8.fullMode=false # Dependency Analysis Plugin -dependency.analysis.android.ignored.variants=release,vanillaDebug,vanillaRelease,wasabiDebug,wasabiRelease,jalapenoRelease \ No newline at end of file +dependency.analysis.android.ignored.variants=release,vanillaDebug,vanillaRelease,wasabiDebug,wasabiRelease,jalapenoRelease From b183afbb5416a349115060466f92e75f3324ea3c Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 11 Dec 2024 12:19:39 +0100 Subject: [PATCH 06/17] Revert accidental change to gradle.properties --- gradle.properties | 1 - 1 file changed, 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index a9cdcd14e30..b5559839f0d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,6 @@ ksp.allow.all.target.configuration=false # Enables Gradle Build Cache - https://docs.gradle.org/current/userguide/build_cache.html org.gradle.caching=true -org.gradle.configuration-cache=true android.useAndroidX=true android.enableJetifier=false From d82111caf0e654c0dc575b43c843d5983752dfb1 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 11 Dec 2024 13:11:17 +0100 Subject: [PATCH 07/17] Update unit tests --- .../android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt index d2af9dbcf91..a97b106a3b2 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt @@ -1084,6 +1084,8 @@ class WooPosTotalsViewModelTest { .thenReturn("Ready for payment") whenever(resourceProvider.getString(R.string.woopos_totals_reader_ready_for_payment_subtitle)) .thenReturn("Tap, swipe or insert card") + whenever(resourceProvider.getString(R.string.woo_pos_payment_remove_card)) + .thenReturn("Remove card") val productIds = listOf(1L, 2L, 3L) val orderId = 23L From 2f4ab2e2c3c2bccda2feb1d3dc3dc1f882af86aa Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 11 Dec 2024 13:48:01 +0100 Subject: [PATCH 08/17] Add tests: * given order draft created and reader connected, when payment is processed, should show processing state * given order draft created and reader connected, when payment is captured, should show processing state --- .../home/totals/WooPosTotalsViewModelTest.kt | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt index a97b106a3b2..a8d58bf3cbc 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt @@ -530,6 +530,8 @@ class WooPosTotalsViewModelTest { .thenReturn("Getting ready") whenever(resourceProvider.getString(R.string.woopos_totals_reader_checking_order)) .thenReturn("Checking order") + whenever(resourceProvider.getString(R.string.woopos_totals_reader_preparing_reader_for_payment)) + .thenReturn("Preparing reader for payment") whenever(networkStatus.isConnected()).thenReturn(true) val productIds = listOf(1L, 2L, 3L) @@ -898,6 +900,82 @@ class WooPosTotalsViewModelTest { assertThat(totalState.readerStatus).isInstanceOf(WooPosTotalsViewState.ReaderStatus.ReadyForPayment::class.java) } + @Test + fun `given order draft created and reader connected, when payment is captured, should show processing state`() = runTest { + // GIVEN + whenever( + resourceProvider.getString( + R.string.woopos_success_totals_payment_processing_title + ) + ).thenReturn("Processing payment") + whenever( + resourceProvider.getString( + R.string.woopos_success_totals_payment_processing_subtitle + ) + ).thenReturn("Please wait…") + whenever(networkStatus.isConnected()).thenReturn(true) + val readerStatus = MutableStateFlow(CardReaderStatus.Connected(mock())) + whenever(cardReaderFacade.readerStatus).thenReturn(readerStatus) + val mockCardReaderPaymentController: CardReaderPaymentController = mock() + val factory: CardReaderPaymentControllerFactory = mock() + whenever(factory.create(any(), any(), any(), any())).thenReturn(mockCardReaderPaymentController) + val paymentState = + MutableStateFlow( + CardReaderPaymentState.CollectingPayment.ExternalReaderCollectPaymentState("") {} + ) + whenever(mockCardReaderPaymentController.paymentState).thenReturn(paymentState) + + // WHEN + val vm = createViewModelAndSetupForSuccessfulOrderCreation(controllerFactory = factory) + paymentState.value = CardReaderPaymentState.PaymentCapturing.ExternalReaderPaymentCapturing("") + + // THEN + val processingState = vm.state.value as WooPosTotalsViewState.PaymentProcessing + assertThat(processingState).isInstanceOf(WooPosTotalsViewState.PaymentProcessing::class.java) + with(processingState){ + assertThat(title).isEqualTo("Processing payment") + assertThat(subtitle).isEqualTo("Please wait…") + } + } + + @Test + fun `given order draft created and reader connected, when payment is processed, should show processing state`() = runTest { + // GIVEN + whenever( + resourceProvider.getString( + R.string.woopos_success_totals_payment_processing_title + ) + ).thenReturn("Processing payment") + whenever( + resourceProvider.getString( + R.string.woopos_success_totals_payment_processing_subtitle + ) + ).thenReturn("Please wait…") + whenever(networkStatus.isConnected()).thenReturn(true) + val readerStatus = MutableStateFlow(CardReaderStatus.Connected(mock())) + whenever(cardReaderFacade.readerStatus).thenReturn(readerStatus) + val mockCardReaderPaymentController: CardReaderPaymentController = mock() + val factory: CardReaderPaymentControllerFactory = mock() + whenever(factory.create(any(), any(), any(), any())).thenReturn(mockCardReaderPaymentController) + val paymentState = + MutableStateFlow( + CardReaderPaymentState.CollectingPayment.ExternalReaderCollectPaymentState("") {} + ) + whenever(mockCardReaderPaymentController.paymentState).thenReturn(paymentState) + + // WHEN + val vm = createViewModelAndSetupForSuccessfulOrderCreation(controllerFactory = factory) + paymentState.value = CardReaderPaymentState.ProcessingPayment.ExternalReaderProcessingPayment("") {} + + // THEN + val processingState = vm.state.value as WooPosTotalsViewState.PaymentProcessing + assertThat(processingState).isInstanceOf(WooPosTotalsViewState.PaymentProcessing::class.java) + with(processingState){ + assertThat(title).isEqualTo("Processing payment") + assertThat(subtitle).isEqualTo("Remove card") + } + } + @Test fun `given payment failed with retry action, when retry clicked, then should retry previous payment action`() = runTest { // GIVEN From 0866ff8703d21b7940ce7b9133da08d249bba519 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 11 Dec 2024 14:50:13 +0100 Subject: [PATCH 09/17] Add payment processing screen enter animation --- .../WooPosTotalsPaymentProcessingScreen.kt | 51 +++++++++++++++---- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt index f8d2a8f23fa..f1858f061d8 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt @@ -1,5 +1,9 @@ package com.woocommerce.android.ui.woopos.home.totals.payment.processing +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.core.animateDpAsState +import androidx.compose.animation.core.tween +import androidx.compose.animation.fadeIn import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -12,7 +16,11 @@ import androidx.compose.foundation.layout.size import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight @@ -27,11 +35,19 @@ import com.woocommerce.android.ui.woopos.common.composeui.WooPosPreview import com.woocommerce.android.ui.woopos.common.composeui.WooPosTheme import com.woocommerce.android.ui.woopos.common.composeui.toAdaptivePadding import com.woocommerce.android.ui.woopos.home.totals.WooPosTotalsViewState +import kotlinx.coroutines.delay + +private const val ENTER_ANIMATION_DURATION = 280 @Composable fun WooPosPaymentProcessingScreen( state: WooPosTotalsViewState.PaymentProcessing, ) { + var enterAnimationStarted by remember { mutableStateOf(false) } + LaunchedEffect(Unit) { + delay(50) + enterAnimationStarted = true + } Box( modifier = Modifier .background(color = WooPosTheme.colors.paymentProcessingBackground) @@ -52,18 +68,31 @@ fun WooPosPaymentProcessingScreen( clipToCompositionBounds = false, clipSpec = LottieClipSpec.Markers("payment_processing_start", "payment_processing_end") ) - Text( - text = state.title, - color = WooPosTheme.colors.paymentProcessingText, - style = MaterialTheme.typography.body1, - ) - Spacer(modifier = Modifier.height(16.dp.toAdaptivePadding())) - Text( - text = state.subtitle, - color = WooPosTheme.colors.paymentProcessingText, - style = MaterialTheme.typography.h4, - fontWeight = FontWeight.Bold, + val marginBetweenAnimatedIconAndText by animateDpAsState( + targetValue = if (enterAnimationStarted) 0.dp else 256.dp, + animationSpec = tween(durationMillis = ENTER_ANIMATION_DURATION) ) + Spacer(modifier = Modifier.height(marginBetweenAnimatedIconAndText.toAdaptivePadding())) + AnimatedVisibility( + visible = enterAnimationStarted, + enter = fadeIn(animationSpec = tween(durationMillis = ENTER_ANIMATION_DURATION * 2)), + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text( + text = state.title, + color = WooPosTheme.colors.paymentProcessingText, + style = MaterialTheme.typography.h6, + fontWeight = FontWeight.Normal, + ) + Spacer(modifier = Modifier.height(16.dp.toAdaptivePadding())) + Text( + text = state.subtitle, + color = WooPosTheme.colors.paymentProcessingText, + style = MaterialTheme.typography.h4, + fontWeight = FontWeight.Bold, + ) + } + } Spacer(modifier = Modifier.height(16.dp.toAdaptivePadding())) } } From bebd92af2c1055dd8e2ef14007af5d7e5a9bca62 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 11 Dec 2024 14:51:49 +0100 Subject: [PATCH 10/17] Satisfy detekt's complaints --- .../ui/woopos/home/totals/WooPosTotalsViewModelTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt index a8d58bf3cbc..bd5b23786a5 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt @@ -932,7 +932,7 @@ class WooPosTotalsViewModelTest { // THEN val processingState = vm.state.value as WooPosTotalsViewState.PaymentProcessing assertThat(processingState).isInstanceOf(WooPosTotalsViewState.PaymentProcessing::class.java) - with(processingState){ + with(processingState) { assertThat(title).isEqualTo("Processing payment") assertThat(subtitle).isEqualTo("Please wait…") } @@ -970,7 +970,7 @@ class WooPosTotalsViewModelTest { // THEN val processingState = vm.state.value as WooPosTotalsViewState.PaymentProcessing assertThat(processingState).isInstanceOf(WooPosTotalsViewState.PaymentProcessing::class.java) - with(processingState){ + with(processingState) { assertThat(title).isEqualTo("Processing payment") assertThat(subtitle).isEqualTo("Remove card") } From f388120666d49cd2458b3118e21839f2c86ca970 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 11 Dec 2024 14:53:03 +0100 Subject: [PATCH 11/17] Tune up animation --- .../processing/WooPosTotalsPaymentProcessingScreen.kt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt index f1858f061d8..1c24333235f 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt @@ -3,7 +3,6 @@ package com.woocommerce.android.ui.woopos.home.totals.payment.processing import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.core.animateDpAsState import androidx.compose.animation.core.tween -import androidx.compose.animation.fadeIn import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -73,10 +72,7 @@ fun WooPosPaymentProcessingScreen( animationSpec = tween(durationMillis = ENTER_ANIMATION_DURATION) ) Spacer(modifier = Modifier.height(marginBetweenAnimatedIconAndText.toAdaptivePadding())) - AnimatedVisibility( - visible = enterAnimationStarted, - enter = fadeIn(animationSpec = tween(durationMillis = ENTER_ANIMATION_DURATION * 2)), - ) { + AnimatedVisibility(visible = enterAnimationStarted) { Column(horizontalAlignment = Alignment.CenterHorizontally) { Text( text = state.title, From d79fe17670a25f3f8d16224a9797e7dd16623e7a Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 11 Dec 2024 14:57:55 +0100 Subject: [PATCH 12/17] Clean up code --- .../payment/processing/WooPosTotalsPaymentProcessingScreen.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt index 1c24333235f..64421b0b803 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt @@ -2,7 +2,6 @@ package com.woocommerce.android.ui.woopos.home.totals.payment.processing import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.core.animateDpAsState -import androidx.compose.animation.core.tween import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -36,8 +35,6 @@ import com.woocommerce.android.ui.woopos.common.composeui.toAdaptivePadding import com.woocommerce.android.ui.woopos.home.totals.WooPosTotalsViewState import kotlinx.coroutines.delay -private const val ENTER_ANIMATION_DURATION = 280 - @Composable fun WooPosPaymentProcessingScreen( state: WooPosTotalsViewState.PaymentProcessing, @@ -69,7 +66,6 @@ fun WooPosPaymentProcessingScreen( ) val marginBetweenAnimatedIconAndText by animateDpAsState( targetValue = if (enterAnimationStarted) 0.dp else 256.dp, - animationSpec = tween(durationMillis = ENTER_ANIMATION_DURATION) ) Spacer(modifier = Modifier.height(marginBetweenAnimatedIconAndText.toAdaptivePadding())) AnimatedVisibility(visible = enterAnimationStarted) { From 7d0bbf0543e277f8bbd497cfb6e769e9ff79eef7 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 11 Dec 2024 15:40:17 +0100 Subject: [PATCH 13/17] Clean up tests --- .../home/totals/WooPosTotalsViewModelTest.kt | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt index bd5b23786a5..6b0e64707eb 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt @@ -298,6 +298,8 @@ class WooPosTotalsViewModelTest { fun `given OnNewTransactionClicked, should send NewTransactionClicked event and reset state to initial`() = runTest { // GIVEN + whenever(resourceProvider.getString(R.string.woopos_success_totals_payment_failed_title)) + .thenReturn("Payment failed") val parentToChildrenEventReceiver: WooPosParentToChildrenEventReceiver = mock { on { events }.thenReturn(mock()) } @@ -941,16 +943,6 @@ class WooPosTotalsViewModelTest { @Test fun `given order draft created and reader connected, when payment is processed, should show processing state`() = runTest { // GIVEN - whenever( - resourceProvider.getString( - R.string.woopos_success_totals_payment_processing_title - ) - ).thenReturn("Processing payment") - whenever( - resourceProvider.getString( - R.string.woopos_success_totals_payment_processing_subtitle - ) - ).thenReturn("Please wait…") whenever(networkStatus.isConnected()).thenReturn(true) val readerStatus = MutableStateFlow(CardReaderStatus.Connected(mock())) whenever(cardReaderFacade.readerStatus).thenReturn(readerStatus) @@ -1105,10 +1097,6 @@ class WooPosTotalsViewModelTest { @Test fun `given payment failed, when go back to checkout clicked, then should inform home about the situation`() = runTest { // GIVEN - whenever(resourceProvider.getString(R.string.woopos_success_totals_payment_processing_title)) - .thenReturn("Processing payment") - whenever(resourceProvider.getString(R.string.woopos_success_totals_payment_processing_subtitle)) - .thenReturn("Please wait…") whenever(resourceProvider.getString(R.string.woopos_success_totals_payment_failed_title)) .thenReturn("Payment failed") whenever(resourceProvider.getString(R.string.woo_pos_payment_failed_try_again)) From 876841477e1c1532e3ea4eb35d2943ba5a5e33db Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 11 Dec 2024 15:55:32 +0100 Subject: [PATCH 14/17] Remove redundant code --- .../payment/processing/WooPosTotalsPaymentProcessingScreen.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt index 64421b0b803..29ab8750f14 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt @@ -58,7 +58,7 @@ fun WooPosPaymentProcessingScreen( Spacer(modifier = Modifier.height(16.dp.toAdaptivePadding())) val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.woopos_card_ilustration)) LottieAnimation( - modifier = Modifier.size(256.dp).padding(0.dp), + modifier = Modifier.size(256.dp), composition = composition, iterations = LottieConstants.IterateForever, clipToCompositionBounds = false, From 9171931d9e0a41f33d795e95748a699369118489 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 11 Dec 2024 15:56:30 +0100 Subject: [PATCH 15/17] Remove redundant code --- .../android/ui/woopos/home/totals/WooPosTotalsScreen.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsScreen.kt index 3c1116edae4..0c22c3fcd82 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsScreen.kt @@ -184,7 +184,7 @@ private fun PreparingReader(readerStatus: WooPosTotalsViewState.ReaderStatus) { private fun ReaderReadyForPayment(readerStatus: WooPosTotalsViewState.ReaderStatus) { val tapCardAnimation by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.woopos_card_ilustration)) LottieAnimation( - modifier = Modifier.size(256.dp).padding(0.dp), + modifier = Modifier.size(256.dp), composition = tapCardAnimation, clipSpec = LottieClipSpec.Markers("reader_awaiting_start", "reader_awaiting_end"), iterations = LottieConstants.IterateForever, From a16613c7c9b4342b4ed12081895c0c87163ef6d3 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 11 Dec 2024 16:11:28 +0100 Subject: [PATCH 16/17] Satisfy detekt's complaints --- .../payment/processing/WooPosTotalsPaymentProcessingScreen.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt index 29ab8750f14..3f96b07676b 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt @@ -9,7 +9,6 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material.MaterialTheme import androidx.compose.material.Text From fadb13d9b62e4bc98243638d7820024c11edd62e Mon Sep 17 00:00:00 2001 From: samiuelson Date: Thu, 12 Dec 2024 16:48:12 +0100 Subject: [PATCH 17/17] Rename Processing UI state to InProgress --- .../home/WooPosHomeChildToParentCommunication.kt | 2 +- .../android/ui/woopos/home/WooPosHomeViewModel.kt | 2 +- .../ui/woopos/home/totals/WooPosTotalsScreen.kt | 8 ++++---- .../ui/woopos/home/totals/WooPosTotalsViewModel.kt | 10 +++++----- .../ui/woopos/home/totals/WooPosTotalsViewState.kt | 2 +- .../WooPosTotalsPaymentInProgressScreen.kt} | 12 ++++++------ .../ui/woopos/home/WooPosHomeViewModelTest.kt | 6 +++--- .../woopos/home/totals/WooPosTotalsViewModelTest.kt | 10 +++++----- 8 files changed, 26 insertions(+), 26 deletions(-) rename WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/{processing/WooPosTotalsPaymentProcessingScreen.kt => inprogress/WooPosTotalsPaymentInProgressScreen.kt} (93%) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeChildToParentCommunication.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeChildToParentCommunication.kt index 75dc773b717..1e872f88f18 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeChildToParentCommunication.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeChildToParentCommunication.kt @@ -26,7 +26,7 @@ sealed class ChildToParentEvent { data class ItemClickedInProductSelector(val itemData: WooPosItemsViewModel.ItemClickedData) : ChildToParentEvent() data object NewTransactionClicked : ChildToParentEvent() data object PaymentCollecting : ChildToParentEvent() - data object PaymentProcessing : ChildToParentEvent() + data object PaymentInProgress : ChildToParentEvent() data object PaymentFailed : ChildToParentEvent() data object RetryFailedPaymentClicked : ChildToParentEvent() data object GoBackToCheckoutAfterFailedPayment : ChildToParentEvent() diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModel.kt index f352566836a..f4e7127073f 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModel.kt @@ -117,7 +117,7 @@ class WooPosHomeViewModel @Inject constructor( screenPositionState = ScreenPositionState.Checkout.CartWithTotals ) } - is ChildToParentEvent.PaymentProcessing, + is ChildToParentEvent.PaymentInProgress, is ChildToParentEvent.PaymentFailed -> { _state.value = _state.value.copy( screenPositionState = ScreenPositionState.Checkout.FullScreenTotals diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsScreen.kt index cd3d6319efd..07610f1abe6 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsScreen.kt @@ -53,7 +53,7 @@ import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosShimme import com.woocommerce.android.ui.woopos.common.composeui.toAdaptivePadding import com.woocommerce.android.ui.woopos.home.totals.WooPosTotalsViewState.Totals.CashPaymentAvailability import com.woocommerce.android.ui.woopos.home.totals.payment.failed.WooPosPaymentFailedScreen -import com.woocommerce.android.ui.woopos.home.totals.payment.processing.WooPosPaymentProcessingScreen +import com.woocommerce.android.ui.woopos.home.totals.payment.inprogress.WooPosPaymentInProgressScreen import com.woocommerce.android.ui.woopos.home.totals.payment.receipt.WooPosTotalsPaymentReceiptScreen import com.woocommerce.android.ui.woopos.home.totals.payment.success.WooPosPaymentSuccessScreen import com.woocommerce.android.ui.woopos.root.navigation.WooPosNavigationEvent @@ -125,9 +125,9 @@ private fun WooPosTotalsScreen( } } - StateChangeAnimated(visible = state is WooPosTotalsViewState.PaymentProcessing) { - if (state is WooPosTotalsViewState.PaymentProcessing) { - WooPosPaymentProcessingScreen(state) + StateChangeAnimated(visible = state is WooPosTotalsViewState.PaymentInProgress) { + if (state is WooPosTotalsViewState.PaymentInProgress) { + WooPosPaymentInProgressScreen(state) } } diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModel.kt index 11068b544c2..93edf07bb33 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModel.kt @@ -24,7 +24,7 @@ import com.woocommerce.android.ui.woopos.home.WooPosParentToChildrenEventReceive import com.woocommerce.android.ui.woopos.home.items.WooPosItemsViewModel import com.woocommerce.android.ui.woopos.home.items.navigation.WooPosItemsNavigator import com.woocommerce.android.ui.woopos.home.totals.WooPosTotalsViewState.PaymentFailed -import com.woocommerce.android.ui.woopos.home.totals.WooPosTotalsViewState.PaymentProcessing +import com.woocommerce.android.ui.woopos.home.totals.WooPosTotalsViewState.PaymentInProgress import com.woocommerce.android.ui.woopos.home.totals.WooPosTotalsViewState.ReceiptSending import com.woocommerce.android.ui.woopos.home.totals.payment.receipt.WooPosTotalsPaymentReceiptIsSendingSupported import com.woocommerce.android.ui.woopos.home.totals.payment.receipt.WooPosTotalsPaymentReceiptIsSendingSupported.Companion.WC_VERSION_SUPPORTS_SENDING_RECEIPTS_BY_EMAIL @@ -282,8 +282,8 @@ class WooPosTotalsViewModel @Inject constructor( is CardReaderPaymentState.ProcessingPayment, is CardReaderPaymentState.PaymentCapturing -> { - uiState.value = buildPaymentProcessingState(paymentState) - childrenToParentEventSender.sendToParent(ChildToParentEvent.PaymentProcessing) + uiState.value = buildPaymentInProgressState(paymentState) + childrenToParentEventSender.sendToParent(ChildToParentEvent.PaymentInProgress) } is CardReaderPaymentState.PaymentSuccessful -> { @@ -366,12 +366,12 @@ class WooPosTotalsViewModel @Inject constructor( ) } - private fun buildPaymentProcessingState(paymentState: CardReaderPaymentOrRefundState): PaymentProcessing { + private fun buildPaymentInProgressState(paymentState: CardReaderPaymentOrRefundState): PaymentInProgress { val subtitle = when (paymentState) { is CardReaderPaymentState.ProcessingPayment -> R.string.woo_pos_payment_remove_card else -> R.string.woopos_success_totals_payment_processing_subtitle } - return PaymentProcessing( + return PaymentInProgress( title = resourceProvider.getString( R.string.woopos_success_totals_payment_processing_title ), diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewState.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewState.kt index 0d50e2c599d..bfed71e8cbd 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewState.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewState.kt @@ -64,7 +64,7 @@ sealed class WooPosTotalsViewState : Parcelable { ) } - data class PaymentProcessing( + data class PaymentInProgress( val title: String, val subtitle: String, ) : WooPosTotalsViewState() diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/inprogress/WooPosTotalsPaymentInProgressScreen.kt similarity index 93% rename from WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt rename to WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/inprogress/WooPosTotalsPaymentInProgressScreen.kt index 3f96b07676b..927753caa77 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/processing/WooPosTotalsPaymentProcessingScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/inprogress/WooPosTotalsPaymentInProgressScreen.kt @@ -1,4 +1,4 @@ -package com.woocommerce.android.ui.woopos.home.totals.payment.processing +package com.woocommerce.android.ui.woopos.home.totals.payment.inprogress import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.core.animateDpAsState @@ -35,8 +35,8 @@ import com.woocommerce.android.ui.woopos.home.totals.WooPosTotalsViewState import kotlinx.coroutines.delay @Composable -fun WooPosPaymentProcessingScreen( - state: WooPosTotalsViewState.PaymentProcessing, +fun WooPosPaymentInProgressScreen( + state: WooPosTotalsViewState.PaymentInProgress, ) { var enterAnimationStarted by remember { mutableStateOf(false) } LaunchedEffect(Unit) { @@ -91,10 +91,10 @@ fun WooPosPaymentProcessingScreen( @WooPosPreview @Composable -fun WooPosPaymentProcessingScreenPreview() { +fun WooPosPaymentInProgressScreenPreview() { WooPosTheme { - WooPosPaymentProcessingScreen( - state = WooPosTotalsViewState.PaymentProcessing( + WooPosPaymentInProgressScreen( + state = WooPosTotalsViewState.PaymentInProgress( title = "Processing payment", subtitle = "Please wait...", ) diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModelTest.kt index a8ab23b81f9..52064fca867 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModelTest.kt @@ -313,7 +313,7 @@ class WooPosHomeViewModelTest { ).isEqualTo(WooPosHomeState.ScreenPositionState.Checkout.CartWithTotals) // WHEN - events.emit(ChildToParentEvent.PaymentProcessing) + events.emit(ChildToParentEvent.PaymentInProgress) // THEN assertThat( @@ -332,7 +332,7 @@ class WooPosHomeViewModelTest { assertThat( viewModel.state.value.screenPositionState ).isEqualTo(WooPosHomeState.ScreenPositionState.Checkout.CartWithTotals) - events.emit(ChildToParentEvent.PaymentProcessing) + events.emit(ChildToParentEvent.PaymentInProgress) assertThat( viewModel.state.value.screenPositionState ).isEqualTo(WooPosHomeState.ScreenPositionState.Checkout.FullScreenTotals) @@ -357,7 +357,7 @@ class WooPosHomeViewModelTest { assertThat( viewModel.state.value.screenPositionState ).isEqualTo(WooPosHomeState.ScreenPositionState.Checkout.CartWithTotals) - events.emit(ChildToParentEvent.PaymentProcessing) + events.emit(ChildToParentEvent.PaymentInProgress) assertThat( viewModel.state.value.screenPositionState ).isEqualTo(WooPosHomeState.ScreenPositionState.Checkout.FullScreenTotals) diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt index 15c5aadd7e9..92d5dcdd0e6 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt @@ -754,7 +754,7 @@ class WooPosTotalsViewModelTest { paymentState.value = CardReaderPaymentState.ProcessingPayment.ExternalReaderProcessingPayment("") {} // THEN - assertThat(vm.state.value).isInstanceOf(WooPosTotalsViewState.PaymentProcessing::class.java) + assertThat(vm.state.value).isInstanceOf(WooPosTotalsViewState.PaymentInProgress::class.java) } @Test @@ -820,8 +820,8 @@ class WooPosTotalsViewModelTest { paymentState.value = CardReaderPaymentState.PaymentCapturing.ExternalReaderPaymentCapturing("") // THEN - val processingState = vm.state.value as WooPosTotalsViewState.PaymentProcessing - assertThat(processingState).isInstanceOf(WooPosTotalsViewState.PaymentProcessing::class.java) + val processingState = vm.state.value as WooPosTotalsViewState.PaymentInProgress + assertThat(processingState).isInstanceOf(WooPosTotalsViewState.PaymentInProgress::class.java) with(processingState) { assertThat(title).isEqualTo("Processing payment") assertThat(subtitle).isEqualTo("Please wait…") @@ -848,8 +848,8 @@ class WooPosTotalsViewModelTest { paymentState.value = CardReaderPaymentState.ProcessingPayment.ExternalReaderProcessingPayment("") {} // THEN - val processingState = vm.state.value as WooPosTotalsViewState.PaymentProcessing - assertThat(processingState).isInstanceOf(WooPosTotalsViewState.PaymentProcessing::class.java) + val processingState = vm.state.value as WooPosTotalsViewState.PaymentInProgress + assertThat(processingState).isInstanceOf(WooPosTotalsViewState.PaymentInProgress::class.java) with(processingState) { assertThat(title).isEqualTo("Processing payment") assertThat(subtitle).isEqualTo("Remove card")