Skip to content

Commit

Permalink
Merge branch 'trunk' into issue/fix-custom-package-units
Browse files Browse the repository at this point in the history
  • Loading branch information
atorresveiga authored Jan 4, 2025
2 parents 0c2272e + 9153b1d commit a7633b5
Show file tree
Hide file tree
Showing 16 changed files with 331 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@ enum class AnalyticsEvent(override val siteless: Boolean = false) : IAnalyticsEv
FILTER_ORDERS_BY_STATUS_DIALOG_OPTION_SELECTED,
ORDER_FILTER_LIST_CLEAR_MENU_BUTTON_TAPPED,

ORDERS_LIST_BULK_UPDATE_SELECTION_ENABLED,
ORDERS_LIST_BULK_UPDATE_REQUESTED,
ORDERS_LIST_BULK_UPDATE_CONFIRMED,
ORDERS_LIST_BULK_UPDATE_SUCCESS,
ORDERS_LIST_BULK_UPDATE_FAILURE,

// -- Payments
PAYMENTS_FLOW_ORDER_COLLECT_PAYMENT_TAPPED,
PAYMENTS_FLOW_COMPLETED,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,8 @@ class AnalyticsTracker private constructor(
const val VALUE_SORT_DATE_ASC = "date,ascending"
const val VALUE_SORT_DATE_DESC = "date,descending"

const val KEY_SELECTED_ORDERS_COUNT = "selected_orders_count"

const val VALUE_API_SUCCESS = "success"
const val VALUE_API_FAILED = "failed"
const val VALUE_SHIPMENT_TRACK = "track"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ class LoginActivity :
}

override fun showMagicLinkSentScreen(email: String?, allowPassword: Boolean) {
val loginMagicLinkSentFragment = LoginMagicLinkSentImprovedFragment.newInstance(email, true)
val loginMagicLinkSentFragment = LoginMagicLinkSentImprovedFragment.newInstance(email, allowPassword)
changeFragment(loginMagicLinkSentFragment, true, LoginMagicLinkSentImprovedFragment.TAG, false)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,3 @@ class DefaultOrderItemDetailsLookup(
override fun getPosition() = position
override fun getSelectionKey() = orderId
}

class SelectableOrderItemDetailsLookup(
private val position: Int,
private val orderId: Long
) : ItemDetailsLookup.ItemDetails<Long>() {
override fun getPosition() = position
override fun getSelectionKey() = orderId
override fun inSelectionHotspot(e: MotionEvent) = true
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ class OrderNavigator @Inject constructor() {
val action = OrderDetailFragmentDirections
.actionOrderDetailFragmentToOrderStatusSelectorDialog(
currentStatus = target.currentStatus,
orderStatusList = target.orderStatusList
orderStatusList = target.orderStatusList,
positiveButtonLabel = R.string.apply
)
fragment.findNavController().navigateSafely(action)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ class OrderSelectionItemKeyProvider(private val recyclerView: RecyclerView) :
}
}

override fun getPosition(key: Long): Int {
return (recyclerView.adapter as? OrderListAdapter)?.currentList
?.indexOfFirst { item ->
item is OrderListItemUIType.OrderListItemUI && item.orderId == key
} ?: RecyclerView.NO_POSITION
}
override fun getPosition(key: Long): Int =
(recyclerView.adapter as? OrderListAdapter)?.orderIdAndPosition[key] ?: RecyclerView.NO_POSITION
}
Original file line number Diff line number Diff line change
Expand Up @@ -1173,7 +1173,8 @@ class OrderCreateEditFormFragment :
OrderCreateEditFormFragmentDirections
.actionOrderCreationFragmentToOrderStatusSelectorDialog(
currentStatus = event.currentStatus,
orderStatusList = event.orderStatusList
orderStatusList = event.orderStatusList,
positiveButtonLabel = R.string.apply
).let { findNavController().navigateSafely(it) }

is ShowSnackbar -> uiMessageResolver.showSnack(event.message)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,22 @@ class OrderStatusSelectorDialog : DialogFragment() {

val selectedIndex = getCurrentOrderStatusIndex()

return MaterialAlertDialogBuilder(requireActivity())
val dialog = MaterialAlertDialogBuilder(requireActivity())
.setTitle(resources.getString(R.string.orderstatus_select_status))
.setCancelable(true)
.setSingleChoiceItems(orderStatusList.map { it.label }.toTypedArray(), selectedIndex) { _, which ->
.setSingleChoiceItems(orderStatusList.map { it.label }.toTypedArray(), selectedIndex) { dialog, which ->
selectedOrderStatus = orderStatusList[which].statusKey

// Casting to `AlertDialog` as `MaterialAlertDialogBuilder` creates it.
(dialog as? androidx.appcompat.app.AlertDialog)?.getButton(Dialog.BUTTON_POSITIVE)?.isEnabled =
selectedOrderStatus.isNotEmpty()

AnalyticsTracker.track(
AnalyticsEvent.FILTER_ORDERS_BY_STATUS_DIALOG_OPTION_SELECTED,
mapOf("status" to selectedOrderStatus)
)
}
.setPositiveButton(R.string.apply) { _, _ ->
.setPositiveButton(navArgs.positiveButtonLabel) { _, _ ->
val newSelectedIndex = getCurrentOrderStatusIndex()
if (newSelectedIndex != selectedIndex) {
AnalyticsTracker.track(
Expand All @@ -68,6 +73,12 @@ class OrderStatusSelectorDialog : DialogFragment() {
dialog.dismiss()
}
.create()

dialog.setOnShowListener {
dialog.getButton(Dialog.BUTTON_POSITIVE).isEnabled = selectedOrderStatus.isNotEmpty()
}

return dialog
}

override fun onResume() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import com.woocommerce.android.ui.orders.list.OrderListItemUIType.SectionHeader
import com.woocommerce.android.util.CurrencyFormatter
import com.woocommerce.android.widgets.tags.TagView
import org.wordpress.android.fluxc.model.WCOrderStatusModel

class OrderListAdapter(
val listener: OrderListListener,
val currencyFormatter: CurrencyFormatter
Expand All @@ -38,6 +39,7 @@ class OrderListAdapter(
var activeOrderStatusMap: Map<String, WCOrderStatusModel> = emptyMap()
var allOrderIds: List<Long> = listOf()
var tracker: SelectionTracker<Long>? = null
var orderIdAndPosition = mutableMapOf<Long, Int>()

override fun getItemViewType(position: Int): Int {
return when (getItem(position)) {
Expand All @@ -61,10 +63,12 @@ class OrderListAdapter(
)
)
}

VIEW_TYPE_LOADING -> {
val view = inflater.inflate(R.layout.skeleton_order_list_item_auto, parent, false)
LoadingViewHolder(view)
}

VIEW_TYPE_SECTION_HEADER -> {
SectionHeaderViewHolder(
OrderListHeaderBinding.inflate(
Expand All @@ -74,6 +78,7 @@ class OrderListAdapter(
)
)
}

else -> {
// Fail fast if a new view type is added so we can handle it
throw IllegalStateException("The view type '$viewType' needs to be handled")
Expand All @@ -97,7 +102,9 @@ class OrderListAdapter(
allOrderIds,
isActivated = tracker?.isSelected(item.orderId) ?: false
)
orderIdAndPosition[item.orderId] = position
}

is SectionHeaderViewHolder -> {
if (BuildConfig.DEBUG && item !is SectionHeader) {
error(
Expand All @@ -107,6 +114,7 @@ class OrderListAdapter(
}
holder.onBind((item as SectionHeader))
}

else -> {}
}
}
Expand All @@ -126,7 +134,11 @@ class OrderListAdapter(
fun setOrderStatusOptions(orderStatusOptions: Map<String, WCOrderStatusModel>) {
if (orderStatusOptions.keys != activeOrderStatusMap.keys) {
this.activeOrderStatusMap = orderStatusOptions
notifyDataSetChanged()
for (position in 0 until itemCount) {
if (getItem(position) is OrderListItemUI) {
notifyItemChanged(position)
}
}
}
}

Expand Down Expand Up @@ -184,6 +196,7 @@ class OrderListAdapter(
viewBinding.root.context.getColor(R.color.color_item_selected)
)
}

else -> {
viewBinding.orderItemLayout.setBackgroundColor(Color.TRANSPARENT)
}
Expand All @@ -209,6 +222,7 @@ class OrderListAdapter(
extras[SwipeToComplete.OLD_STATUS] = orderItemUI.status

this.itemView.setOnClickListener {
if (shouldPreventDetailNavigation(orderId)) return@setOnClickListener
listener.openOrderDetail(
orderId = orderItemUI.orderId,
allOrderIds = allOrderIds,
Expand All @@ -218,6 +232,23 @@ class OrderListAdapter(
}
}

// Some edge cases in order selection mode, like tapping the screen with 4 fingers or using TalkBack,
// cause the order's onClick listener to gain focus over the selection tracker.
// This quick fix will prevent the app from entering an unexpected status when the app is in selection mode.
private fun shouldPreventDetailNavigation(orderId: Long): Boolean {
if (tracker?.selection?.size() != 0) {
tracker?.let { selectionTracker ->
if (selectionTracker.isSelected(orderId)) {
selectionTracker.deselect(orderId)
} else {
selectionTracker.select(orderId)
}
}
return true
}
return false
}

/**
* Converts the order status label into an [OrderStatusTag], creates the associated [TagView],
* and add it to the holder. No need to trim the label text since this is done in [OrderStatusTag]
Expand Down
Loading

0 comments on commit a7633b5

Please sign in to comment.