Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ fun WooPosItemsScreen(
WooPosItemsScreen(
modifier = modifier,
itemsStateFlow = productsViewModel.viewState,
catalogSyncBannerStateFlow = productsViewModel.catalogSyncBannerState,
productsViewState = productsViewState,
couponsListState = couponsListState,
catalogSyncState = catalogSyncState,
Expand All @@ -78,17 +79,20 @@ fun WooPosItemsScreen(
private fun WooPosItemsScreen(
modifier: Modifier = Modifier,
itemsStateFlow: StateFlow<WooPosItemsToolbarViewState>,
catalogSyncBannerStateFlow: StateFlow<WooPosItemsViewModel.CatalogSyncBannerState>,
productsViewState: LazyListState,
couponsListState: LazyListState,
catalogSyncState: CatalogSyncState,
onRetryCatalogSync: () -> Unit,
onUIEvent: (WooPosItemsUIEvent) -> Unit,
) {
val state = itemsStateFlow.collectAsState()
val bannerState = catalogSyncBannerStateFlow.collectAsState()

MainItemsList(
modifier = modifier,
state = state,
bannerState = bannerState,
productsViewState = productsViewState,
couponsListState = couponsListState,
catalogSyncState = catalogSyncState,
Expand All @@ -112,6 +116,7 @@ private fun WooPosItemsScreen(
},
onTabClicked = { onUIEvent(WooPosItemsUIEvent.OnTabClicked(it)) },
onBackClicked = { onUIEvent(WooPosItemsUIEvent.BackFromVariationsClicked) },
onSyncWarningBannerDismissed = { onUIEvent(WooPosItemsUIEvent.SyncOverdueBannerDismissed) },
)
}

Expand All @@ -120,22 +125,19 @@ private fun WooPosItemsScreen(
private fun MainItemsList(
modifier: Modifier,
state: State<WooPosItemsToolbarViewState>,
bannerState: State<WooPosItemsViewModel.CatalogSyncBannerState>,
productsViewState: LazyListState,
couponsListState: LazyListState,
catalogSyncState: CatalogSyncState,
onSearchEvent: (WooPosSearchUIEvent) -> Unit,
onTabClicked: (WooPosItemsToolbarViewState.Tab) -> Unit,
onAddCouponEvent: () -> Unit,
onBackClicked: () -> Unit,
onSyncWarningBannerDismissed: () -> Unit,
onRetryCatalogSync: () -> Unit = {},
) {
Box(
modifier = modifier
.fillMaxSize()
) {
Column(
modifier.fillMaxHeight()
) {
Box(modifier = modifier.fillMaxSize()) {
Column(modifier.fillMaxHeight()) {
WooPosItemsToolbar(
modifier = Modifier
.statusBarsPadding()
Expand All @@ -149,6 +151,21 @@ private fun MainItemsList(
onAddCouponEvent = onAddCouponEvent,
)

Spacer(
modifier =
Modifier
.height(WooPosSpacing.Small.value)
.padding(horizontal = WooPosSpacing.Medium.value.toAdaptivePadding())
)

WooPosRefreshCatalogBanner(
bannerState = bannerState.value,
modifier = Modifier,
onDismiss = onSyncWarningBannerDismissed
)

Spacer(modifier = Modifier.height(WooPosSpacing.Small.value))

val currentState = state.value

Crossfade(
Expand Down Expand Up @@ -308,10 +325,12 @@ fun WooPosItemsScreenSearchVisiblePreview(modifier: Modifier = Modifier) {
tabs = tabs()
)
)
val bannerState = MutableStateFlow(WooPosItemsViewModel.CatalogSyncBannerState.OverdueSyncWarning)
WooPosTheme {
WooPosItemsScreen(
modifier = modifier,
itemsStateFlow = productState,
catalogSyncBannerStateFlow = bannerState,
productsViewState = rememberLazyListState(),
couponsListState = rememberLazyListState(),
catalogSyncState = CatalogSyncState.Idle,
Expand All @@ -336,10 +355,12 @@ fun WooPosItemsScreenSearchHiddenPreview(modifier: Modifier = Modifier) {
tabs = tabs()
)
)
val bannerState = MutableStateFlow(WooPosItemsViewModel.CatalogSyncBannerState.OverdueSyncWarning)
WooPosTheme {
WooPosItemsScreen(
modifier = modifier,
itemsStateFlow = productState,
catalogSyncBannerStateFlow = bannerState,
productsViewState = rememberLazyListState(),
couponsListState = rememberLazyListState(),
catalogSyncState = CatalogSyncState.Idle,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ sealed class WooPosItemsUIEvent {
data object CloseSearchClicked : WooPosItemsUIEvent()
data object SearchIconClicked : WooPosItemsUIEvent()
data object AddCouponIconClicked : WooPosItemsUIEvent()
data object SyncOverdueBannerDismissed : WooPosItemsUIEvent()
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import com.woocommerce.android.ui.woopos.home.items.WooPosItemsToolbarViewState.
import com.woocommerce.android.ui.woopos.home.items.WooPosItemsToolbarViewState.Tab
import com.woocommerce.android.ui.woopos.home.items.coupons.creation.WooPosCouponCreationFacade
import com.woocommerce.android.ui.woopos.home.items.variations.WooPosVariationsNavigationData
import com.woocommerce.android.ui.woopos.localcatalog.WooPosFullSyncRequirement
import com.woocommerce.android.ui.woopos.localcatalog.WooPosFullSyncStatusChecker
import com.woocommerce.android.ui.woopos.util.analytics.WooPosAnalyticsEvent
import com.woocommerce.android.ui.woopos.util.analytics.WooPosAnalyticsEvent.Event.SearchButtonTapped
import com.woocommerce.android.ui.woopos.util.analytics.WooPosAnalyticsEventConstant
Expand All @@ -35,6 +37,7 @@ class WooPosItemsViewModel @Inject constructor(
private val parentToChildrenEventReceiver: WooPosParentToChildrenEventReceiver,
private val preferencesRepository: WooPosPreferencesRepository,
private val analyticsTracker: WooPosAnalyticsTracker,
private val syncStatusChecker: WooPosFullSyncStatusChecker,
) : ViewModel() {
private var preservedStateBeforeOpeningVariations: WooPosItemsToolbarViewState? = null
private val _viewState = MutableStateFlow<WooPosItemsToolbarViewState>(initialState())
Expand All @@ -45,6 +48,9 @@ class WooPosItemsViewModel @Inject constructor(
initialValue = _viewState.value,
)

private val _catalogSyncBannerState = MutableStateFlow<CatalogSyncBannerState>(CatalogSyncBannerState.Hidden)
val catalogSyncBannerState: StateFlow<CatalogSyncBannerState> = _catalogSyncBannerState

init {
listenUpEvents()
searchHelper.initialize(
Expand All @@ -55,6 +61,18 @@ class WooPosItemsViewModel @Inject constructor(
viewModelScope.launch {
preferencesRepository.setWasOpenedOnce(true)
}

checkSyncStatusAndUpdateBanner()
}

private fun checkSyncStatusAndUpdateBanner() {
viewModelScope.launch {
val requirement = syncStatusChecker.checkSyncRequirement()
_catalogSyncBannerState.value = when (requirement) {
is WooPosFullSyncRequirement.Overdue -> CatalogSyncBannerState.OverdueSyncWarning
else -> CatalogSyncBannerState.Hidden
}
}
}

fun onUIEvent(event: WooPosItemsUIEvent) {
Expand All @@ -77,6 +95,9 @@ class WooPosItemsViewModel @Inject constructor(
}

is WooPosItemsUIEvent.AddCouponIconClicked -> createAndAddCoupon()
WooPosItemsUIEvent.SyncOverdueBannerDismissed -> {
_catalogSyncBannerState.value = CatalogSyncBannerState.Hidden
}
}
}

Expand Down Expand Up @@ -241,4 +262,9 @@ class WooPosItemsViewModel @Inject constructor(
@Parcelize
data class Coupon(override val id: Long, val couponCode: String) : ItemClickedData(id), Parcelable
}

sealed class CatalogSyncBannerState {
data object Hidden : CatalogSyncBannerState()
data object OverdueSyncWarning : CatalogSyncBannerState()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package com.woocommerce.android.ui.woopos.home.items

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.scaleIn
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.woocommerce.android.R
import com.woocommerce.android.ui.woopos.common.composeui.WooPosPreview
import com.woocommerce.android.ui.woopos.common.composeui.component.ShadowType
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosCard
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosText
import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosCornerRadius
import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosElevation
import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosSpacing
import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosTheme
import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosTypography

@Composable
fun WooPosRefreshCatalogBanner(
bannerState: WooPosItemsViewModel.CatalogSyncBannerState,
modifier: Modifier = Modifier,
onDismiss: () -> Unit
) {
AnimatedVisibility(
visible = bannerState is WooPosItemsViewModel.CatalogSyncBannerState.OverdueSyncWarning,
enter = fadeIn(
animationSpec = tween(durationMillis = 180)
) + scaleIn(
animationSpec = tween(durationMillis = 180)
),
modifier = modifier.padding(horizontal = WooPosSpacing.Medium.value)
) {
WooPosCard(
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(WooPosCornerRadius.Medium.value),
backgroundColor = MaterialTheme.colorScheme.surfaceContainerLow,
elevation = WooPosElevation.Medium,
shadowType = ShadowType.Soft,
) {
Row(
horizontalArrangement = Arrangement.spacedBy(WooPosSpacing.Medium.value),
modifier = Modifier
.fillMaxWidth()
.padding(WooPosSpacing.Medium.value),
) {
Icon(
painter = painterResource(id = R.drawable.ic_woo_pos_info_banner),
tint = MaterialTheme.colorScheme.onSurface,
contentDescription = null,
modifier = Modifier.size(48.dp).align(Alignment.CenterVertically)
)
Column(
verticalArrangement = Arrangement.spacedBy(WooPosSpacing.Small.value),
horizontalAlignment = Alignment.Start,
modifier = Modifier.weight(1f)
) {
WooPosText(
text = stringResource(R.string.woopos_refresh_catalog_banner_title),
style = WooPosTypography.BodyLarge,
color = MaterialTheme.colorScheme.onSurface,
)
WooPosText(
text = stringResource(R.string.woopos_refresh_catalog_banner_message),
style = WooPosTypography.BodySmall,
color = MaterialTheme.colorScheme.onSurface,
)
}
IconButton(
onClick = onDismiss,
modifier = Modifier.size(32.dp)
) {
Icon(
imageVector = Icons.Filled.Close,
contentDescription = stringResource(R.string.woopos_refresh_catalog_banner_dismiss),
tint = MaterialTheme.colorScheme.onSurface,
modifier = Modifier.size(24.dp)
)
}
}
}
}
}

@Composable
@WooPosPreview
fun WooPosRefreshCatalogBannerPreview() {
WooPosTheme {
WooPosRefreshCatalogBanner(
bannerState = WooPosItemsViewModel.CatalogSyncBannerState.OverdueSyncWarning,
onDismiss = {}
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.woocommerce.android.ui.woopos.home.items.coupons

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.ExperimentalMaterialApi
Expand All @@ -21,7 +20,6 @@ import com.woocommerce.android.ui.woopos.common.composeui.WooPosPreview
import com.woocommerce.android.ui.woopos.common.composeui.component.Button
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosErrorScreen
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosPaginationErrorIndicator
import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosSpacing
import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosTheme
import com.woocommerce.android.ui.woopos.home.items.WooPosCouponsViewState
import com.woocommerce.android.ui.woopos.home.items.WooPosItemList
Expand Down Expand Up @@ -74,7 +72,7 @@ private fun WooPosCouponsScreen(
when (val itemsState = state.value) {
is WooPosCouponsViewState.Content -> {
WooPosItemList(
modifier = Modifier.padding(top = WooPosSpacing.Large.value),
modifier = Modifier,
state = itemsState,
listState = listState,
onItemClicked = { item -> onUIEvent(WooPosCouponsUIEvent.CouponClicked(item.id, item.name)) },
Expand All @@ -89,7 +87,7 @@ private fun WooPosCouponsScreen(
}

is WooPosCouponsViewState.Loading -> WooPosItemsLoadingIndicator(
modifier = Modifier.padding(top = WooPosSpacing.Large.value)
modifier = Modifier
)

is WooPosCouponsViewState.Empty -> WooPosItemsEmptyList(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ private fun Content(
onEndOfItemListReached: () -> Unit
) {
WooPosItemList(
modifier = Modifier.padding(top = WooPosSpacing.Large.value),
state = itemsState,
listState = listState,
onItemClicked = onItemClicked,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.ExperimentalMaterialApi
Expand All @@ -24,7 +23,6 @@ import com.woocommerce.android.ui.woopos.common.composeui.WooPosPreview
import com.woocommerce.android.ui.woopos.common.composeui.component.Button
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosErrorScreen
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosPaginationErrorIndicator
import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosSpacing
import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosTheme
import com.woocommerce.android.ui.woopos.home.items.WooPosItemList
import com.woocommerce.android.ui.woopos.home.items.WooPosItemSelectionViewState
Expand Down Expand Up @@ -103,7 +101,6 @@ private fun WooPosVariationsScreens(
when (val itemsState = itemState.value) {
is WooPosVariationsViewState.Content -> {
WooPosItemList(
modifier = Modifier.padding(top = WooPosSpacing.Large.value),
state = itemsState,
listState = listState,
onItemClicked = {
Expand All @@ -122,25 +119,20 @@ private fun WooPosVariationsScreens(
}

is WooPosVariationsViewState.Loading -> {
WooPosItemsLoadingIndicator(
modifier = Modifier.padding(top = WooPosSpacing.Large.value),
)
WooPosItemsLoadingIndicator()
}

is WooPosVariationsViewState.Error -> {
VariationsError(
modifier = Modifier
.width(640.dp)
.padding(top = WooPosSpacing.Large.value)
modifier = Modifier.width(640.dp)
) {
onRetryClicked()
}
}

is WooPosVariationsViewState.Empty -> {
WooPosItemsEmptyList(
modifier = Modifier.fillMaxSize()
.padding(top = WooPosSpacing.Large.value),
modifier = Modifier.fillMaxSize(),
title = stringResource(id = R.string.woopos_variations_empty_list_title),
message = stringResource(id = R.string.woopos_variations_empty_list_message),
contentDescription = stringResource(
Expand Down
Loading