Skip to content

Commit

Permalink
Merge branch 'trunk' into 12626-mobile-payments-what-is-tap-to-pay-sc…
Browse files Browse the repository at this point in the history
…reen-instruction-not-correct
  • Loading branch information
backwardstruck authored Oct 1, 2024
2 parents 5d54827 + ed9b240 commit cd51809
Show file tree
Hide file tree
Showing 37 changed files with 2,645 additions and 2,534 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<!--
Contains editorialized release notes. Raw release notes should go into `RELEASE-NOTES.txt`.
-->
## 20.6
We're excited to bring you new features in our WooCommerce app! Users can now set a password to protect products when signed in with site credentials, enhancing security for WooCommerce 8.1.0 and above. Also, promoting a Blaze product from the campaign detail will now trigger a smoother native flow. Enjoy the updates!

## 20.5
We’re excited to bring you a smoother experience with our latest update! We've resolved an issue that prevented renaming Product Variation Attributes and fixed a bug related to notification removal. Plus, users can now easily select product images when creating Blaze ads, and the Blaze feature is now fully enabled for sites with the Blaze for WooCommerce plugin active. Enjoy the improvements!

Expand Down
2 changes: 2 additions & 0 deletions RELEASE-NOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
20.7
-----
- [**] Improve barcode scanner reading accuracy [https://github.com/woocommerce/woocommerce-android/pull/12673]
- [*] [Login] Fix an issue where the app doesn't show the correct error screen when application passwords are disabled [https://github.com/woocommerce/woocommerce-android/pull/12717]
- [**] Fixed bug with coupons disappearing from the order creation screen unexpectedly [https://github.com/woocommerce/woocommerce-android/pull/12724]

20.6
-----
Expand Down
15 changes: 7 additions & 8 deletions WooCommerce/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ dependencies {
implementation "androidx.recyclerview:recyclerview-selection:1.1.0"
implementation "androidx.appcompat:appcompat:$appCompatVersion"
implementation "com.google.android.material:material:$materialVersion"
implementation "androidx.transition:transition-ktx:$transitionVersion"
implementation "androidx.transition:transition:$transitionVersion"
implementation "androidx.cardview:cardview:1.0.0"
implementation("androidx.browser:browser:1.5.0") {
exclude group: 'com.google.guava', module: 'listenablefuture'
Expand All @@ -249,8 +249,10 @@ dependencies {
implementation "androidx.datastore:datastore-preferences:1.0.0"
implementation "androidx.datastore:datastore:1.0.0"

implementation "androidx.navigation:navigation-fragment-ktx:$gradle.ext.navigationVersion"
implementation "androidx.navigation:navigation-ui-ktx:$gradle.ext.navigationVersion"
implementation "androidx.navigation:navigation-common:$gradle.ext.navigationVersion"
implementation "androidx.navigation:navigation-fragment:$gradle.ext.navigationVersion"
implementation "androidx.navigation:navigation-runtime:$gradle.ext.navigationVersion"
implementation "androidx.navigation:navigation-ui:$gradle.ext.navigationVersion"

implementation "androidx.work:work-runtime-ktx:$workManagerVersion"

Expand Down Expand Up @@ -320,8 +322,8 @@ dependencies {
implementation "com.github.bumptech.glide:glide:$glideVersion"
ksp "com.github.bumptech.glide:compiler:$glideVersion"
implementation "com.github.bumptech.glide:volley-integration:$glideVersion@aar"
implementation 'com.google.android.play:app-update-ktx:2.1.0'
implementation 'com.google.android.play:review-ktx:2.0.1'
implementation 'com.google.android.play:app-update:2.1.0'
implementation 'com.google.android.play:review:2.0.1'

implementation 'com.google.android.gms:play-services-code-scanner:16.1.0'

Expand Down Expand Up @@ -408,7 +410,6 @@ dependencies {
implementation "androidx.fragment:fragment-ktx:1.8.2"
implementation "androidx.activity:activity-ktx:1.8.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycleVersion"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion"
implementation "androidx.lifecycle:lifecycle-process:$lifecycleVersion"

// Coroutines
Expand Down Expand Up @@ -448,8 +449,6 @@ dependencies {
implementation 'androidx.hilt:hilt-navigation-compose:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout-compose:1.0.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2'
implementation "com.google.accompanist:accompanist-swiperefresh:$composeAccompanistVersion"
implementation "com.google.accompanist:accompanist-systemuicontroller:$composeAccompanistVersion"
implementation "io.coil-kt:coil-compose:$coilVersion"
implementation "io.coil-kt:coil-svg:$coilVersion"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ data class Order(
val attributesList: List<Attribute>,
val parent: Long? = null,
val configuration: ProductConfiguration? = null,
val configurationKey: Long? = null
val configurationKey: Long? = null,
val containsMetadata: Boolean = false
) : Parcelable {
@IgnoredOnParcel
val uniqueId: Long = ProductHelper.productOrVariationId(productId, variationId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ class OrderMapper @Inject constructor(
Item.Attribute(attribute.key.orEmpty(), attribute.value.orEmpty())
},
it.bundledBy?.toLongOrNull() ?: it.compositeParent?.toLongOrNull(),
configurationKey = it.configurationKey
configurationKey = it.configurationKey,
containsMetadata = it.metaData?.isNotEmpty() ?: false
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.woocommerce.android.analytics.AnalyticsTracker
import com.woocommerce.android.analytics.AnalyticsTrackerWrapper
import com.woocommerce.android.applicationpasswords.ApplicationPasswordGenerationException
import com.woocommerce.android.applicationpasswords.ApplicationPasswordsNotifier
import com.woocommerce.android.extensions.isNotNullOrEmpty
import com.woocommerce.android.model.UiString
import com.woocommerce.android.model.UiString.UiStringRes
import com.woocommerce.android.model.UiString.UiStringText
Expand Down Expand Up @@ -85,6 +86,10 @@ class LoginSiteCredentialsViewModel @Inject constructor(

private val loadingMessage = savedStateHandle.getStateFlow(viewModelScope, 0, "loading-message")

private val SiteModel?.fullAuthorizationUrl: String?
get() = this?.applicationPasswordsAuthorizeUrl
?.let { url -> "$url?app_name=$applicationPasswordsClientId&success_url=$REDIRECTION_URL" }

@OptIn(ExperimentalCoroutinesApi::class)
val viewState = state.flatMapLatest {
// Reset loading and error state when the state changes
Expand Down Expand Up @@ -240,18 +245,14 @@ class LoginSiteCredentialsViewModel @Inject constructor(
fetchedSiteId.map { if (it == -1) null else wpApiSiteRepository.getSiteByLocalId(it) }
) { loadingMessage, errorDialogMessage, site ->
ViewState.WebAuthorizationViewState(
authorizationUrl = generateAuthorizationUrl(site),
authorizationUrl = site?.fullAuthorizationUrl,
userAgent = userAgent,
loadingMessage = loadingMessage,
errorDialogMessage = errorDialogMessage
)
}
}

private fun generateAuthorizationUrl(site: SiteModel?) =
site?.applicationPasswordsAuthorizeUrl
?.let { url -> "$url?app_name=$applicationPasswordsClientId&success_url=$REDIRECTION_URL" }

private suspend fun login() {
val state = requireNotNull(this@LoginSiteCredentialsViewModel.viewState.value as ViewState.NativeLoginViewState)
loadingMessage.value = R.string.logging_in
Expand Down Expand Up @@ -308,10 +309,17 @@ class LoginSiteCredentialsViewModel @Inject constructor(
val errorMessage = detectedErrorMessage
?.toPresentableString()
?: resourceProvider.getString(R.string.error_generic)
ShowApplicationPasswordTutorialScreen(
url = generateAuthorizationUrl(site).orEmpty(),
errorMessage = errorMessage
).let { triggerEvent(it) }
if (site.fullAuthorizationUrl.isNotNullOrEmpty()) {
triggerEvent(
ShowApplicationPasswordTutorialScreen(
url = site.applicationPasswordsAuthorizeUrl,
errorMessage = errorMessage
)
)
} else {
analyticsTracker.track(AnalyticsEvent.APPLICATION_PASSWORDS_AUTHORIZATION_URL_NOT_AVAILABLE)
triggerEvent(ShowApplicationPasswordsUnavailableScreen(siteAddress, site.isJetpackConnected))
}
} else {
triggerEvent(ShowNonWooErrorScreen(siteAddress))
}
Expand Down Expand Up @@ -342,7 +350,7 @@ class LoginSiteCredentialsViewModel @Inject constructor(
// Otherwise, the web authorization flow will handle the login
if (state.value == State.NativeLogin) {
fetchUserInfo()
} else if (site.applicationPasswordsAuthorizeUrl == null) {
} else if (site.applicationPasswordsAuthorizeUrl.isNullOrEmpty()) {
analyticsTracker.track(AnalyticsEvent.APPLICATION_PASSWORDS_AUTHORIZATION_URL_NOT_AVAILABLE)
triggerEvent(ShowApplicationPasswordsUnavailableScreen(siteAddress, site.isJetpackConnected))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ import com.woocommerce.android.ui.orders.creation.OrderCreateEditViewModel.Mode.
import com.woocommerce.android.ui.orders.creation.OrderCreateEditViewModel.Mode.Edit
import com.woocommerce.android.ui.orders.creation.configuration.EditProductConfigurationResult
import com.woocommerce.android.ui.orders.creation.configuration.ProductConfigurationFragment
import com.woocommerce.android.ui.orders.creation.coupon.edit.OrderCreateCouponDetailsViewModel
import com.woocommerce.android.ui.orders.creation.coupon.edit.OrderCreateCouponEditFragment.Companion.KEY_COUPON_EDIT_RESULT
import com.woocommerce.android.ui.orders.creation.customerlist.OrderCustomerListFragment
import com.woocommerce.android.ui.orders.creation.giftcards.OrderCreateEditGiftCardFragment.Companion.GIFT_CARD_RESULT
import com.woocommerce.android.ui.orders.creation.giftcards.OrderCreateEditGiftCardViewModel.GiftCardResult
Expand Down Expand Up @@ -199,7 +201,7 @@ class OrderCreateEditFormFragment :
}

private fun handleCouponEditResult() {
args.couponEditResult?.let {
handleResult<OrderCreateCouponDetailsViewModel.CouponEditResult>(KEY_COUPON_EDIT_RESULT) {
viewModel.onCouponEditResult(it)
}
}
Expand Down Expand Up @@ -838,9 +840,10 @@ class OrderCreateEditFormFragment :
Column {
state.value.forEach { item ->
var isExpanded by rememberSaveable { mutableStateOf(false) }
val childrenConfigCount = item.getConfiguration()?.childrenConfiguration?.keys?.size ?: 0
when {
item is OrderCreationProduct.ProductItemWithRules &&
item.getConfiguration().childrenConfiguration?.keys?.size?.compareTo(0) == 1 -> {
item is OrderCreationProduct.ProductItemWithRules && childrenConfigCount > 0
-> {
val modifier = if (isExpanded) {
Modifier.border(
1.dp,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,6 @@ class OrderCreateEditViewModel @Inject constructor(
ScanningSource.ORDER_LIST
)
}
handleCouponEditResult()
launch {
updateAutoTaxRateSettingState()
updateTaxRateSelectorButtonState()
Expand Down Expand Up @@ -457,7 +456,6 @@ class OrderCreateEditViewModel @Inject constructor(
updateCouponAndDiscountButtonsState(order)
updateAddShippingButtonVisibility(order)
updateAddGiftCardButtonVisibility(order)
handleCouponEditResult()
updateTaxRateSelectorButtonState()
_pendingSelectedItems.value = _orderDraft.value.selectedItems()
}
Expand Down Expand Up @@ -555,12 +553,6 @@ class OrderCreateEditViewModel @Inject constructor(
ShippingAddress -> resourceProvider.getString(string.order_creation_tax_based_on_shipping_address)
}

private fun handleCouponEditResult() {
args.couponEditResult?.let {
handleCouponEditResult()
}
}

private fun handleCouponEditResult(couponEditResult: OrderCreateCouponDetailsViewModel.CouponEditResult) {
when (couponEditResult) {
is OrderCreateCouponDetailsViewModel.CouponEditResult.RemoveCoupon -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,14 @@ class OrderCreationProductMapper @Inject constructor(
(item.itemId in childrenMap.keys).not()
}.map { item ->
val productInfo = getProductInformation(item, currencySymbol)
createOrderCreationProduct(item, productInfo, rulesMap[item.productId])
}
.toMutableList()
if (item.containsMetadata) {
createOrderCreationProduct(item, productInfo, rulesMap[item.productId])
} else {
// If the Line item contains no metadata, the children and parent data will never be available
// We simply consider that the product is already loaded
createOrderCreationProduct(item, productInfo, rulesMap[item.productId], emptyList())
}
}.toMutableList()

for (parentId in childrenMap.keys) {
val parent = itemsMap[parentId] ?: continue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,14 @@ import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.woocommerce.android.R
import com.woocommerce.android.extensions.navigateBackWithResult
import com.woocommerce.android.ui.base.BaseFragment
import com.woocommerce.android.ui.compose.theme.WooThemeWithBackground
import com.woocommerce.android.ui.orders.creation.coupon.edit.OrderCreateCouponEditFragmentDirections.Companion.actionOrderCreationCouponEditFragmentToOrderCreationFragment
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class OrderCreateCouponEditFragment : BaseFragment() {
private val args: OrderCreateCouponEditFragmentArgs by navArgs()
private val viewModel by viewModels<OrderCreateCouponDetailsViewModel>()

override fun onCreateView(
Expand All @@ -44,19 +41,19 @@ class OrderCreateCouponEditFragment : BaseFragment() {
viewModel.event.observe(viewLifecycleOwner) {
when (it) {
is OrderCreateCouponDetailsViewModel.CouponEditResult.RemoveCoupon -> {
val action = actionOrderCreationCouponEditFragmentToOrderCreationFragment(
mode = args.orderCreationMode,
couponEditResult = OrderCreateCouponDetailsViewModel.CouponEditResult.RemoveCoupon(
it.couponCode
),
sku = null,
barcodeFormat = null
navigateBackWithResult(
key = KEY_COUPON_EDIT_RESULT,
result = it,
destinationId = R.id.orderCreationFragment
)
findNavController().navigate(action)
}
}
}
}

override fun getFragmentTitle() = getString(R.string.order_creation_remove_this_coupon)

companion object {
const val KEY_COUPON_EDIT_RESULT = "key_coupon_edit_result"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ data class CustomColors(
val paymentSuccessBackground: Color,
val paymentSuccessText: Color,
val paymentSuccessIcon: Color,
val paymentSuccessIconBackground: Color,
val dialogSubtitleHighlightBackground: Color = Color(0x14747480),
val homeBackground: Color,
)
Expand All @@ -38,23 +37,20 @@ private object WooPosColors {
val secondary = Color(0xFF0A9400)
val surface = Color(0xFF2E2E2E)

val greenNotFromPalette = Color(0xFF08FB87)

// LightColorPalette
val lightColorPaletteSecondary = Color(0xFF004B3E)
val lightColorPaletteSecondaryVariant = Color(0xFF50575E)
val lightColorPaletteBackground = Color(0xFFFDFDFD)

// DarkCustomColors
val darkCustomColorsError = Color(0xFFBE4400)
val darkCustomColorsPaymentSuccessBackground = Color(0xFF005139)
val darkCustomColorsPaymentSuccessIconBackground = Color(0xFF00AD64)
val darkCustomloadingSkeleton = Color(0xFF616161)
val darkCustomColorsSuccess = Color(0xFF06B166)
val darkCustomColorsHomeBackground = Color(0xFF1E1E1E)

// LightCustomColors
val lightCustomColorsError = Color(0xFFF16618)
val lightCustomColorsPaymentSuccessBackground = Color(0xFF98F179)
val lightCustomColorsSuccess = Color(0xFF03D479)
val lightCustomColorsLoadingSkeleton = Color(0xFFE1E1E1)
val lightCustomColorsBorder = Color(0xFFC6C6C8)

Expand Down Expand Up @@ -188,24 +184,22 @@ private val LightColorPalette = lightColors(
private val DarkCustomColors = CustomColors(
loadingSkeleton = WooPosColors.darkCustomloadingSkeleton,
border = WooPosColors.oldGrayMedium,
success = WooPosColors.darkCustomColorsSuccess,
success = WooPosColors.greenNotFromPalette,
error = WooPosColors.darkCustomColorsError,
paymentSuccessBackground = WooPosColors.darkCustomColorsPaymentSuccessBackground,
paymentSuccessBackground = WooPosColors.darkCustomColorsHomeBackground,
paymentSuccessText = WooPosColors.oldGrayLight,
paymentSuccessIcon = Color.White,
paymentSuccessIconBackground = WooPosColors.darkCustomColorsPaymentSuccessIconBackground,
paymentSuccessIcon = WooPosColors.darkCustomColorsHomeBackground,
homeBackground = WooPosColors.darkCustomColorsHomeBackground
)

private val LightCustomColors = CustomColors(
loadingSkeleton = WooPosColors.lightCustomColorsLoadingSkeleton,
border = WooPosColors.lightCustomColorsBorder,
success = WooPosColors.lightCustomColorsSuccess,
success = WooPosColors.greenNotFromPalette,
error = WooPosColors.lightCustomColorsError,
paymentSuccessBackground = WooPosColors.lightCustomColorsPaymentSuccessBackground,
paymentSuccessBackground = WooPosColors.White,
paymentSuccessText = WooPosColors.Purple90,
paymentSuccessIcon = WooPosColors.lightCustomColorsSuccess,
paymentSuccessIconBackground = Color.White,
paymentSuccessIcon = Color.White,
homeBackground = WooPosColors.Gray0
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ private fun CheckMarkIcon(
modifier = modifier
.size(size)
.shadow(8.dp, CircleShape)
.background(WooPosTheme.colors.paymentSuccessIconBackground, CircleShape)
.background(WooPosTheme.colors.success, CircleShape)
) {
Icon(
imageVector = Icons.Default.Check,
Expand Down
15 changes: 0 additions & 15 deletions WooCommerce/src/main/res/navigation/nav_graph_order_creations.xml
Original file line number Diff line number Diff line change
Expand Up @@ -308,21 +308,6 @@
<argument
android:name="orderCreationMode"
app:argType="com.woocommerce.android.ui.orders.creation.OrderCreateEditViewModel$Mode" />
<action
android:id="@+id/action_orderCreationCouponEditFragment_to_orderCreationFragment"
app:destination="@id/orderCreationFragment"
app:enterAnim="@null"
app:exitAnim="@null"
app:popEnterAnim="@null"
app:popExitAnim="@null"
app:popUpTo="@id/orderCreationFragment"
app:popUpToInclusive="true">
<argument
android:name="couponEditResult"
android:defaultValue="@null"
app:argType="com.woocommerce.android.ui.orders.creation.coupon.edit.OrderCreateCouponDetailsViewModel$CouponEditResult"
app:nullable="true" />
</action>
</fragment>
<fragment
android:id="@+id/customerListFragment"
Expand Down
Loading

0 comments on commit cd51809

Please sign in to comment.