Skip to content

Commit

Permalink
Merge pull request #12795 from woocommerce/issue/12469-blaze-objectiv…
Browse files Browse the repository at this point in the history
…e-store-switch

[Blaze i4] Add switch to the objective screen
  • Loading branch information
JorgeMucientes authored Oct 17, 2024
2 parents d2f7e2d + 185a0fe commit 82164a1
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ object AppPrefs {
TIMES_AI_PRODUCT_CREATION_SURVEY_DISPLAYED,
AI_PRODUCT_CREATION_SURVEY_DISMISSED,
CUSTOM_FIELDS_TOP_BANNER_DISMISSED,
BLAZE_CAMPAIGN_SELECTED_OBJECTIVE
BLAZE_CAMPAIGN_SELECTED_OBJECTIVE,
BLAZE_CAMPAIGN_OBJECTIVE_SWITCH_CHECKED
}

/**
Expand Down Expand Up @@ -277,6 +278,10 @@ object AppPrefs {
get() = getString(DeletablePrefKey.BLAZE_CAMPAIGN_SELECTED_OBJECTIVE, "")
set(value) = setString(DeletablePrefKey.BLAZE_CAMPAIGN_SELECTED_OBJECTIVE, value)

var blazeCampaignObjectiveSwitchChecked: Boolean
get() = getBoolean(DeletablePrefKey.BLAZE_CAMPAIGN_OBJECTIVE_SWITCH_CHECKED, true)
set(value) = setBoolean(DeletablePrefKey.BLAZE_CAMPAIGN_OBJECTIVE_SWITCH_CHECKED, value)

fun getProductSortingChoice(currentSiteId: Int) = getString(getProductSortingKey(currentSiteId)).orNullIfEmpty()

fun setProductSortingChoice(currentSiteId: Int, value: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ class AppPrefsWrapper @Inject constructor() {

var blazeCampaignSelectedObjective by AppPrefs::blazeCampaignSelectedObjective

var blazeCampaignObjectiveSwitchChecked by AppPrefs::blazeCampaignObjectiveSwitchChecked

fun getAppInstallationDate() = AppPrefs.installationDate

fun getReceiptUrl(localSiteId: Int, remoteSiteId: Long, selfHostedSiteId: Long, orderId: Long) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,7 @@ enum class AnalyticsEvent(override val siteless: Boolean = false) : IAnalyticsEv
BLAZE_CREATION_EDIT_LOCATION_SAVE_TAPPED,
BLAZE_CREATION_EDIT_DESTINATION_SAVE_TAPPED,
BLAZE_CAMPAIGN_CREATION_FEEDBACK,
BLAZE_CAMPAIGN_OBJECTIVE_SAVED,

// Hazmat Shipping Declaration
CONTAINS_HAZMAT_CHECKED,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,7 @@ class AnalyticsTracker private constructor(
const val KEY_BLAZE_IS_AI_CONTENT = "is_ai_suggested_ad_content"
const val KEY_BLAZE_ERROR = "blaze_creation_error"
const val KEY_BLAZE_CAMPAIGN_TYPE = "campaign_type"
const val KEY_BLAZE_OBJECTIVE = "objective"

const val PRODUCT_TYPES = "product_types"
const val HAS_ADDONS = "has_addons"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,16 @@ class BlazeRepository @Inject constructor(
}
}

fun isCampaignObjectiveSwitchChecked() = appPrefsWrapper.blazeCampaignObjectiveSwitchChecked

fun setCampaignObjectiveSwitchChecked(enabled: Boolean) {
appPrefsWrapper.blazeCampaignObjectiveSwitchChecked = enabled
}

fun storeSelectedObjective(objectiveId: String) {
appPrefsWrapper.blazeCampaignSelectedObjective = objectiveId
}

@Parcelize
data class CampaignDetails(
val productId: Long,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Divider
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
Expand All @@ -34,7 +35,9 @@ import com.woocommerce.android.R
import com.woocommerce.android.ui.blaze.creation.objective.BlazeCampaignObjectiveViewModel.ObjectiveItem
import com.woocommerce.android.ui.blaze.creation.objective.BlazeCampaignObjectiveViewModel.ObjectiveViewState
import com.woocommerce.android.ui.compose.annotatedStringRes
import com.woocommerce.android.ui.compose.component.BottomSheetSwitchColors
import com.woocommerce.android.ui.compose.component.Toolbar
import com.woocommerce.android.ui.compose.component.WCSwitch
import com.woocommerce.android.ui.compose.component.WCTextButton
import com.woocommerce.android.ui.compose.preview.LightDarkThemePreviews

Expand All @@ -45,7 +48,8 @@ fun BlazeCampaignObjectiveScreen(viewModel: BlazeCampaignObjectiveViewModel) {
state = state,
onBackPressed = viewModel::onBackPressed,
onSaveTapped = viewModel::onSaveTapped,
onObjectiveTapped = viewModel::onItemToggled
onObjectiveTapped = viewModel::onItemToggled,
onStoreObjectiveSwitchChanged = viewModel::onStoreObjectiveSwitchChanged
)
}
}
Expand All @@ -56,6 +60,7 @@ private fun ObjectiveScreen(
onBackPressed: () -> Unit,
onSaveTapped: () -> Unit,
onObjectiveTapped: (ObjectiveItem) -> Unit,
onStoreObjectiveSwitchChanged: (Boolean) -> Unit
) {
Scaffold(
topBar = {
Expand All @@ -81,7 +86,9 @@ private fun ObjectiveScreen(
.fillMaxSize()
) {
LazyColumn(
modifier = Modifier.padding(vertical = 4.dp)
modifier = Modifier
.padding(vertical = 4.dp)
.weight(1f)
) {
items(state.items) {
ObjectiveListItem(
Expand All @@ -99,6 +106,16 @@ private fun ObjectiveScreen(
)
}
}
Divider()
WCSwitch(
text = stringResource(id = R.string.blaze_campaign_objective_save_selection_switch_label),
checked = state.isStoreSelectionButtonToggled,
onCheckedChange = { onStoreObjectiveSwitchChanged(it) },
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
colors = BottomSheetSwitchColors()
)
}
}
}
Expand Down Expand Up @@ -216,5 +233,6 @@ fun PreviewObjectiveScreen() {
onBackPressed = { },
onSaveTapped = { },
onObjectiveTapped = { },
onStoreObjectiveSwitchChanged = { }
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ import android.os.Parcelable
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import com.woocommerce.android.analytics.AnalyticsEvent.BLAZE_CAMPAIGN_OBJECTIVE_SAVED
import com.woocommerce.android.analytics.AnalyticsTracker
import com.woocommerce.android.analytics.AnalyticsTrackerWrapper
import com.woocommerce.android.ui.blaze.BlazeRepository
import com.woocommerce.android.viewmodel.MultiLiveEvent.Event.Exit
import com.woocommerce.android.viewmodel.MultiLiveEvent.Event.ExitWithResult
import com.woocommerce.android.viewmodel.ScopedViewModel
import com.woocommerce.android.viewmodel.getNullableStateFlow
import com.woocommerce.android.viewmodel.getStateFlow
import com.woocommerce.android.viewmodel.navArgs
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.Flow
Expand All @@ -20,15 +24,22 @@ import javax.inject.Inject

@HiltViewModel
class BlazeCampaignObjectiveViewModel @Inject constructor(
blazeRepository: BlazeRepository,
savedStateHandle: SavedStateHandle
private val blazeRepository: BlazeRepository,
savedStateHandle: SavedStateHandle,
private val analyticsTrackerWrapper: AnalyticsTrackerWrapper
) : ScopedViewModel(savedStateHandle) {
private val navArgs: BlazeCampaignObjectiveFragmentArgs by savedStateHandle.navArgs()

private val selectedId = savedStateHandle.getNullableStateFlow(
scope = viewModelScope,
initialValue = navArgs.selectedObjectiveId,
clazz = String::class.java
clazz = String::class.java,
key = "selectedId"
)
private val storeObjectiveSwitchState = savedState.getStateFlow(
scope = this,
initialValue = blazeRepository.isCampaignObjectiveSwitchChecked(),
key = "storeObjectiveSwitchState"
)

private val items: Flow<List<ObjectiveItem>> =
Expand All @@ -38,8 +49,12 @@ class BlazeCampaignObjectiveViewModel @Inject constructor(
}
}

val viewState = combine(items, selectedId) { items, selectedId ->
ObjectiveViewState(items = items, selectedItemId = selectedId)
val viewState = combine(
items,
selectedId,
storeObjectiveSwitchState
) { items, selectedId, storeObjectiveSwitchState ->
ObjectiveViewState(items, selectedId, storeObjectiveSwitchState)
}.asLiveData()

fun onItemToggled(item: ObjectiveItem) {
Expand All @@ -50,15 +65,30 @@ class BlazeCampaignObjectiveViewModel @Inject constructor(
triggerEvent(Exit)
}

fun onStoreObjectiveSwitchChanged(checked: Boolean) {
storeObjectiveSwitchState.update { checked }
}

fun onSaveTapped() {
selectedId.value?.let { triggerEvent(ExitWithResult(ObjectiveResult(it))) }
// TODO analyticsTrackerWrapper.track(BLAZE_...)
viewState.value?.isStoreSelectionButtonToggled?.let {
blazeRepository.setCampaignObjectiveSwitchChecked(it)
if (it) {
blazeRepository.storeSelectedObjective(selectedId.value.orEmpty())
}
}
selectedId.value?.let {
triggerEvent(ExitWithResult(ObjectiveResult(it)))
analyticsTrackerWrapper.track(
stat = BLAZE_CAMPAIGN_OBJECTIVE_SAVED,
properties = mapOf(AnalyticsTracker.KEY_BLAZE_OBJECTIVE to it)
)
}
}

data class ObjectiveViewState(
val items: List<ObjectiveItem>,
val selectedItemId: String? = null,
val isStoreSelectionButtonToggled: Boolean = false,
val isStoreSelectionButtonToggled: Boolean = true,
) {
val isSaveButtonEnabled: Boolean
get() = !selectedItemId.isNullOrEmpty()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ class BlazeCampaignCreationPreviewViewModel @Inject constructor(
AnalyticsTracker.VALUE_EVERGREEN_CAMPAIGN

else -> AnalyticsTracker.VALUE_START_END_CAMPAIGN
}
},
AnalyticsTracker.KEY_BLAZE_OBJECTIVE to campaignDetails.value?.objectiveId,
)
)
campaignDetails.value?.let {
Expand Down
10 changes: 8 additions & 2 deletions WooCommerce/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3917,6 +3917,14 @@
<string name="blaze_campaign_preview_missing_content_dialog_positive_button">Add</string>
<string name="blaze_campaign_preview_missing_objective_dialog_text">Please select an objective for the Blaze campaign</string>
<string name="blaze_campaign_preview_missing_objective_dialog_positive_button">Select objective</string>

<!--
Blaze campaign objective screen
-->
<string name="blaze_campaign_objective_select_objective_label">Select objective %s</string>
<string name="blaze_campaign_objective_good_for"><![CDATA[<b>Good for:</b> %s]]></string>
<string name="blaze_campaign_objective_save_selection_switch_label">Save my selection for future campaigns</string>

<!--
Blaze campaign budget screen
-->
Expand Down Expand Up @@ -3992,8 +4000,6 @@
<string name="blaze_campaign_creation_location_search_message">Start typing country, state or city to see available options</string>
<string name="blaze_campaign_creation_location_search_no_results_message">No location found.\nPlease try again.</string>
<string name="blaze_campaign_creation_location_search_failed_message">Searching failed.\nPlease try again</string>
<string name="blaze_campaign_objective_select_objective_label">Select objective %s</string>
<string name="blaze_campaign_objective_good_for"><![CDATA[<b>Good for:</b> %s]]></string>

<!--
Blaze edit ad destination
Expand Down

0 comments on commit 82164a1

Please sign in to comment.