Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion RELEASE-NOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

23.8
-----

- [*] Optimized POS Local Catalog Settings screen [https://github.com/woocommerce/woocommerce-android/pull/14971]

23.7
-----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.unit.dp
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.constraintlayout.compose.Dimension
Expand Down Expand Up @@ -88,7 +90,8 @@ private fun WooPosSettingsLocalCatalogScreen(
allowCellularDataUpdate = state.allowCellularDataUpdate,
onToggleCellularData = onToggleCellularData,
isLoading = state.catalogStatus is WooPosSettingsLocalCatalogState.CatalogStatus.Loading ||
state.catalogStatus is WooPosSettingsLocalCatalogState.CatalogStatus.RefreshingCatalog
state.catalogStatus is WooPosSettingsLocalCatalogState.CatalogStatus.RefreshingCatalog,
hasCellularCapability = state.hasCellularCapability
)

ManualUpdateSection(
Expand Down Expand Up @@ -155,15 +158,19 @@ private fun CatalogStatusSection(
private fun CellularDataSection(
allowCellularDataUpdate: Boolean,
onToggleCellularData: (Boolean) -> Unit,
isLoading: Boolean
isLoading: Boolean,
hasCellularCapability: Boolean
) {
val isEnabled = hasCellularCapability && !isLoading
val contentAlpha = if (hasCellularCapability) 1f else 0.38f

WooPosCard(
modifier = Modifier.fillMaxWidth()
) {
ConstraintLayout(
modifier = Modifier
.fillMaxWidth()
.clickable(enabled = !isLoading) {
.clickable(enabled = isEnabled) {
onToggleCellularData(!allowCellularDataUpdate)
}
.padding(WooPosSpacing.Medium.value)
Expand All @@ -173,7 +180,7 @@ private fun CellularDataSection(
WooPosText(
text = stringResource(R.string.woopos_settings_local_catalog_cellular_data),
style = WooPosTypography.BodyLarge,
color = MaterialTheme.colorScheme.onSurface,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = contentAlpha),
fontWeight = FontWeight.Bold,
modifier = Modifier.constrainAs(title) {
top.linkTo(parent.top)
Expand All @@ -186,7 +193,7 @@ private fun CellularDataSection(
WooPosText(
text = stringResource(R.string.woopos_settings_local_catalog_cellular_data_subtitle),
style = WooPosTypography.BodyMedium,
color = MaterialTheme.colorScheme.onSurface,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = contentAlpha),
modifier = Modifier.constrainAs(subtitle) {
top.linkTo(title.bottom, margin = WooPosSpacing.Small.value)
start.linkTo(parent.start)
Expand All @@ -198,7 +205,7 @@ private fun CellularDataSection(
Switch(
checked = allowCellularDataUpdate,
onCheckedChange = null,
enabled = !isLoading,
enabled = isEnabled,
colors = SwitchDefaults.colors(
checkedThumbColor = Color(0xFFFFFFFF),
checkedTrackColor = MaterialTheme.colorScheme.primaryContainer
Expand Down Expand Up @@ -391,7 +398,29 @@ fun WooPosSettingsLocalCatalogScreenPreview() {
lastUpdate = "2 hours ago",
lastFullUpdate = "Yesterday at 3:45 PM"
),
allowCellularDataUpdate = true
allowCellularDataUpdate = true,
hasCellularCapability = true
),
onToggleCellularData = {},
onRefreshCatalog = {}
)
}
}

@WooPosPreview
@Composable
fun WooPosSettingsLocalCatalogScreenNoCellularPreview() {
WooPosTheme {
WooPosSettingsLocalCatalogScreen(
state = WooPosSettingsLocalCatalogState(
catalogStatus = WooPosSettingsLocalCatalogState.CatalogStatus.Available(
productCount = 1250,
variationCount = 3420,
lastUpdate = "2 hours ago",
lastFullUpdate = "Yesterday at 3:45 PM"
),
allowCellularDataUpdate = false,
hasCellularCapability = false
),
onToggleCellularData = {},
onRefreshCatalog = {}
Expand All @@ -406,22 +435,30 @@ fun WooPosSettingsLocalCatalogScreenLoadingPreview() {
WooPosSettingsLocalCatalogScreen(
state = WooPosSettingsLocalCatalogState(
catalogStatus = WooPosSettingsLocalCatalogState.CatalogStatus.Loading,
allowCellularDataUpdate = true
allowCellularDataUpdate = true,
hasCellularCapability = true
),
onToggleCellularData = {},
onRefreshCatalog = {}
)
}
}

class CellularCapabilityPreviewParameterProvider : PreviewParameterProvider<Boolean> {
override val values = sequenceOf(true, false)
}

@WooPosPreview
@Composable
fun WooPosSettingsLocalCatalogRefreshingPreview() {
fun WooPosSettingsLocalCatalogRefreshingPreview(
@PreviewParameter(CellularCapabilityPreviewParameterProvider::class) hasCellularCapability: Boolean
) {
WooPosTheme {
WooPosSettingsLocalCatalogScreen(
state = WooPosSettingsLocalCatalogState(
catalogStatus = WooPosSettingsLocalCatalogState.CatalogStatus.RefreshingCatalog,
allowCellularDataUpdate = true
allowCellularDataUpdate = true,
hasCellularCapability = hasCellularCapability
),
onToggleCellularData = {},
onRefreshCatalog = {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.woocommerce.android.ui.woopos.settings.details.localcatalog
data class WooPosSettingsLocalCatalogState(
val catalogStatus: CatalogStatus = CatalogStatus.Loading,
val allowCellularDataUpdate: Boolean = false,
val hasCellularCapability: Boolean = false,
) {
sealed class CatalogStatus {
data class Available(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.woocommerce.android.ui.woopos.home.WooPosParentToChildrenEventReceive
import com.woocommerce.android.ui.woopos.localcatalog.PosLocalCatalogSyncResult
import com.woocommerce.android.ui.woopos.localcatalog.WooPosLocalCatalogSyncRepository
import com.woocommerce.android.ui.woopos.localcatalog.WooPosLocalCatalogSyncScheduler
import com.woocommerce.android.ui.woopos.util.WooPosCellularCapabilityDetector
import com.woocommerce.android.ui.woopos.util.datastore.WooPosPreferencesRepository
import com.woocommerce.android.ui.woopos.util.datastore.WooPosSyncTimestampManager
import com.woocommerce.android.ui.woopos.util.format.WooPosDateFormatter
Expand All @@ -31,18 +32,32 @@ class WooPosSettingsLocalCatalogViewModel @Inject constructor(
private val syncScheduler: WooPosLocalCatalogSyncScheduler,
private val childToParentEventSender: WooPosChildrenToParentEventSender,
private val parentToChildEventReceiver: WooPosParentToChildrenEventReceiver,
private val cellularCapabilityDetector: WooPosCellularCapabilityDetector,
) : ViewModel() {
private val _state = MutableStateFlow(WooPosSettingsLocalCatalogState())
val state: StateFlow<WooPosSettingsLocalCatalogState> = _state.asStateFlow()

init {
checkCellularCapability()

loadCatalogStatus()

listenToCellularDataUpdateValue()

listenToParentEvents()
}

private fun checkCellularCapability() {
val hasCellular = cellularCapabilityDetector.hasCellularCapability()
_state.update { it.copy(hasCellularCapability = hasCellular) }

if (!hasCellular) {
viewModelScope.launch {
preferencesRepository.setAllowCellularDataUpdate(false)
}
}
}

private fun listenToParentEvents() {
viewModelScope.launch {
parentToChildEventReceiver.events.collect { event ->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.woocommerce.android.ui.woopos.util

import android.content.Context
import android.content.pm.PackageManager
import dagger.Reusable
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject

@Reusable
class WooPosCellularCapabilityDetector @Inject constructor(
@ApplicationContext private val context: Context
) {
fun hasCellularCapability(): Boolean {
return context.packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ class WooPosSettingsLocalCatalogViewModelTest {
private val syncScheduler: WooPosLocalCatalogSyncScheduler = mock()
private val childToParentEventSender: WooPosChildrenToParentEventSender = mock()
private val parentToChildEventReceiver: WooPosParentToChildrenEventReceiver = mock()
private val cellularCapabilityDetector: com.woocommerce.android.ui.woopos.util.WooPosCellularCapabilityDetector =
mock()

private val mockSite: SiteModel = mock()
private val allowCellularDataFlow = MutableStateFlow(false)
Expand All @@ -57,6 +59,7 @@ class WooPosSettingsLocalCatalogViewModelTest {
whenever(selectedSite.get()).thenReturn(mockSite)
whenever(preferencesRepository.allowCellularDataUpdate).thenReturn(allowCellularDataFlow)
whenever(parentToChildEventReceiver.events).thenReturn(parentEventsFlow)
whenever(cellularCapabilityDetector.hasCellularCapability()).thenReturn(true)
whenever(localCatalogSyncRepository.syncLocalCatalogFull(any()))
.thenReturn(
PosLocalCatalogSyncResult.Success(
Expand Down Expand Up @@ -295,6 +298,58 @@ class WooPosSettingsLocalCatalogViewModelTest {
.isInstanceOf(WooPosSettingsLocalCatalogState.CatalogStatus.Available::class.java)
}

@Test
fun `given device has cellular capability, when init, then hasCellularCapability is true`() = runTest {
// GIVEN
whenever(cellularCapabilityDetector.hasCellularCapability()).thenReturn(true)

// WHEN
sut = createViewModel()
advanceUntilIdle()

// THEN
assertThat(sut.state.value.hasCellularCapability).isTrue()
}

@Test
fun `given device has no cellular capability, when init, then hasCellularCapability is false`() = runTest {
// GIVEN
whenever(cellularCapabilityDetector.hasCellularCapability()).thenReturn(false)

// WHEN
sut = createViewModel()
advanceUntilIdle()

// THEN
assertThat(sut.state.value.hasCellularCapability).isFalse()
}

@Test
fun `given device has no cellular capability, when init, then allowCellularDataUpdate is set to false in preferences`() = runTest {
// GIVEN
whenever(cellularCapabilityDetector.hasCellularCapability()).thenReturn(false)

// WHEN
sut = createViewModel()
advanceUntilIdle()

// THEN
verify(preferencesRepository).setAllowCellularDataUpdate(false)
}

@Test
fun `given device has cellular capability, when init, then allowCellularDataUpdate preference is not modified`() = runTest {
// GIVEN
whenever(cellularCapabilityDetector.hasCellularCapability()).thenReturn(true)

// WHEN
sut = createViewModel()
advanceUntilIdle()

// THEN
verify(preferencesRepository, times(0)).setAllowCellularDataUpdate(false)
}

private fun createViewModel() = WooPosSettingsLocalCatalogViewModel(
syncTimestampManager = syncTimestampManager,
localCatalogSyncRepository = localCatalogSyncRepository,
Expand All @@ -304,5 +359,6 @@ class WooPosSettingsLocalCatalogViewModelTest {
syncScheduler = syncScheduler,
childToParentEventSender = childToParentEventSender,
parentToChildEventReceiver = parentToChildEventReceiver,
cellularCapabilityDetector = cellularCapabilityDetector,
)
}