Skip to content

Commit

Permalink
Merge pull request #10644 from woocommerce/issue/10629-device-selection
Browse files Browse the repository at this point in the history
Blaze: Target device selection
  • Loading branch information
0nko authored Jan 30, 2024
2 parents 91fce81 + 68863ac commit 35e962c
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ class BlazeRepository @Inject constructor(

suspend fun fetchLanguages() = blazeCampaignsStore.fetchBlazeTargetingLanguages()

fun observeDevices() = blazeCampaignsStore.observeBlazeTargetingDevices()
.map { it.map { device -> Device(device.id, device.name) } }

suspend fun fetchDevices() = blazeCampaignsStore.fetchBlazeTargetingDevices()

suspend fun getMostRecentCampaign() = blazeCampaignsStore.getMostRecentBlazeCampaign(selectedSite.get())

suspend fun getAdSuggestions(productId: Long): List<AiSuggestionForAd>? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import com.woocommerce.android.R.string
import com.woocommerce.android.extensions.combine
import com.woocommerce.android.extensions.formatToMMMdd
import com.woocommerce.android.ui.blaze.BlazeRepository
import com.woocommerce.android.ui.blaze.BlazeRepository.Budget
Expand All @@ -16,6 +17,7 @@ import com.woocommerce.android.ui.blaze.BlazeRepository.Location
import com.woocommerce.android.ui.blaze.creation.preview.BlazeCampaignCreationPreviewViewModel.AdDetailsUi.AdDetails
import com.woocommerce.android.ui.blaze.creation.preview.BlazeCampaignCreationPreviewViewModel.AdDetailsUi.Loading
import com.woocommerce.android.ui.blaze.creation.targets.BlazeTargetType
import com.woocommerce.android.ui.blaze.creation.targets.BlazeTargetType.DEVICE
import com.woocommerce.android.ui.blaze.creation.targets.BlazeTargetType.LANGUAGE
import com.woocommerce.android.util.CurrencyFormatter
import com.woocommerce.android.viewmodel.MultiLiveEvent
Expand All @@ -24,7 +26,6 @@ import com.woocommerce.android.viewmodel.ScopedViewModel
import com.woocommerce.android.viewmodel.getStateFlow
import com.woocommerce.android.viewmodel.navArgs
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.parcelize.Parcelize
Expand All @@ -43,21 +44,34 @@ class BlazeCampaignCreationPreviewViewModel @Inject constructor(

private val adDetails = savedStateHandle.getStateFlow<AdDetailsUi>(viewModelScope, Loading)
private val budget = savedStateHandle.getStateFlow(viewModelScope, getDefaultBudget())

private val languages = blazeRepository.observeLanguages()
private val selectedLanguages = savedStateHandle.getStateFlow<List<String>>(viewModelScope, emptyList())
private val devices = blazeRepository.observeDevices()
private val selectedLanguages = savedStateHandle.getStateFlow<List<String>>(
scope = viewModelScope,
initialValue = emptyList(),
key = "selectedLanguages"
)
private val selectedDevices = savedStateHandle.getStateFlow<List<String>>(
scope = viewModelScope,
initialValue = emptyList(),
key = "selectedDevices"
)

val viewState = combine(
adDetails,
budget,
languages,
selectedLanguages
) { adDetails, budget, languages, selectedLanguages ->
devices,
selectedLanguages,
selectedDevices
) { adDetails, budget, languages, devices, selectedLanguages, selectedDevices ->
CampaignPreviewUiState(
adDetails = adDetails,
campaignDetails = campaign.toCampaignDetailsUi(
budget,
languages.filter { it.code in selectedLanguages },
emptyList(),
devices.filter { it.id in selectedDevices },
emptyList(),
emptyList()
)
Expand Down Expand Up @@ -100,6 +114,7 @@ class BlazeCampaignCreationPreviewViewModel @Inject constructor(
launch {
when (targetType) {
LANGUAGE -> selectedLanguages.update { selectedIds }
DEVICE -> selectedDevices.update { selectedIds }
else -> Unit
}
}
Expand All @@ -108,6 +123,7 @@ class BlazeCampaignCreationPreviewViewModel @Inject constructor(
private fun loadData() {
launch {
blazeRepository.fetchLanguages()
blazeRepository.fetchDevices()
blazeRepository.getAdSuggestions(navArgs.productId).let { suggestions ->
adDetails.update {
AdDetails(
Expand Down Expand Up @@ -146,7 +162,9 @@ class BlazeCampaignCreationPreviewViewModel @Inject constructor(
displayTitle = resourceProvider.getString(string.blaze_campaign_preview_details_devices),
displayValue = devices.joinToString { it.name }
.ifEmpty { resourceProvider.getString(string.blaze_campaign_preview_target_default_value) },
onItemSelected = { /* TODO Add device selection */ },
onItemSelected = {
triggerEvent(NavigateToTargetSelectionScreen(DEVICE, devices.map { it.id }))
},
),
CampaignDetailItemUi(
displayTitle = resourceProvider.getString(string.blaze_campaign_preview_details_location),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.padding
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.material.icons.Icons.Filled
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.runtime.Composable
Expand Down Expand Up @@ -45,8 +47,11 @@ private fun TargetSelectionScreen(
title = state.title,
onNavigationButtonClick = onBackPressed,
navigationIcon = Filled.ArrowBack,
actionButtonText = stringResource(id = string.save).uppercase(),
onActionButtonClick = onSaveTapped
actions = {
TextButton(onClick = onSaveTapped, enabled = state.selectedItems.isNotEmpty()) {
Text(stringResource(id = string.save).uppercase())
}
}
)
},
modifier = Modifier.background(MaterialTheme.colors.surface)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import com.woocommerce.android.viewmodel.navArgs
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.update
import kotlinx.parcelize.Parcelize
Expand All @@ -38,7 +37,14 @@ class BlazeCampaignTargetSelectionViewModel @Inject constructor(
)
}
}
else -> flowOf(emptyList())
else -> blazeRepository.observeDevices().map { devices ->
devices.map { device ->
TargetItem(
id = device.id,
value = device.name
)
}
}
}

private val selectedIds = savedStateHandle.getStateFlow(viewModelScope, navArgs.selectedIds.toSet())
Expand All @@ -49,7 +55,7 @@ class BlazeCampaignTargetSelectionViewModel @Inject constructor(
selectedItems = selectedIds.map { id -> items.first { it.id == id } },
title = when (navArgs.targetType) {
BlazeTargetType.LANGUAGE -> resourceProvider.getString(R.string.blaze_campaign_preview_details_language)
else -> ""
else -> resourceProvider.getString(R.string.blaze_campaign_preview_details_devices)
}
)
}.asLiveData()
Expand All @@ -65,7 +71,13 @@ class BlazeCampaignTargetSelectionViewModel @Inject constructor(
}

fun onAllButtonTapped() {
selectedIds.update { emptySet() }
selectedIds.update {
if (it.size == viewState.value?.items?.size) {
emptySet()
} else {
viewState.value?.items?.map { item -> item.id }?.toSet() ?: emptySet()
}
}
}

fun onBackPressed() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ fun <T> MultiSelectList(
allItemsButton?.let {
MultiSelectItem(
item = it.text,
isSelected = selectedItems.isEmpty(),
isSelected = selectedItems.size == items.size,
onItemToggled = it.onClicked,
modifier = Modifier.fillMaxWidth()
)
Expand Down

0 comments on commit 35e962c

Please sign in to comment.