Skip to content

Commit

Permalink
Merge pull request #12733 from woocommerce/issue/12706-fetch-and-save…
Browse files Browse the repository at this point in the history
…-selected-objective

Issue/12706 fetch and save selected objective
  • Loading branch information
JorgeMucientes authored Oct 1, 2024
2 parents 6e60afd + d43c454 commit 51c89cc
Show file tree
Hide file tree
Showing 14 changed files with 132 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ object AppPrefs {
TIMES_AI_PRODUCT_CREATION_SURVEY_DISPLAYED,
AI_PRODUCT_CREATION_SURVEY_DISMISSED,
CUSTOM_FIELDS_TOP_BANNER_DISMISSED,
BLAZE_CAMPAIGN_SELECTED_OBJECTIVE
}

/**
Expand Down Expand Up @@ -272,6 +273,10 @@ object AppPrefs {
get() = getBoolean(DeletablePrefKey.CUSTOM_FIELDS_TOP_BANNER_DISMISSED, false)
set(value) = setBoolean(DeletablePrefKey.CUSTOM_FIELDS_TOP_BANNER_DISMISSED, value)

var blazeCampaignSelectedObjective: String
get() = getString(DeletablePrefKey.BLAZE_CAMPAIGN_SELECTED_OBJECTIVE, "")
set(value) = setString(DeletablePrefKey.BLAZE_CAMPAIGN_SELECTED_OBJECTIVE, 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 @@ -36,6 +36,8 @@ class AppPrefsWrapper @Inject constructor() {

var isCustomFieldsTopBannerDismissed by AppPrefs::isCustomFieldsTopBannerDismissed

var blazeCampaignSelectedObjective by AppPrefs::blazeCampaignSelectedObjective

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
@@ -1,6 +1,7 @@
package com.woocommerce.android.ui.blaze

import android.os.Parcelable
import com.woocommerce.android.AppPrefsWrapper
import com.woocommerce.android.AppUrls.FETCH_PAYMENT_METHOD_URL_PATH
import com.woocommerce.android.AppUrls.WPCOM_ADD_PAYMENT_METHOD
import com.woocommerce.android.BuildConfig
Expand Down Expand Up @@ -36,7 +37,8 @@ class BlazeRepository @Inject constructor(
private val selectedSite: SelectedSite,
private val blazeCampaignsStore: BlazeCampaignsStore,
private val productDetailRepository: ProductDetailRepository,
private val mediaFilesRepository: MediaFilesRepository
private val mediaFilesRepository: MediaFilesRepository,
private val appPrefsWrapper: AppPrefsWrapper
) {
companion object {
private const val BLAZE_CAMPAIGN_CREATION_ORIGIN = "wc-android"
Expand Down Expand Up @@ -191,7 +193,8 @@ class BlazeRepository @Inject constructor(
destinationParameters = DestinationParameters(
targetUrl = product.permalink,
parameters = emptyMap()
)
),
objectiveId = appPrefsWrapper.blazeCampaignSelectedObjective
)
}

Expand Down Expand Up @@ -318,7 +321,8 @@ class BlazeRepository @Inject constructor(
topics = it.interests.map { interest -> interest.id }
)
},
isEndlessCampaign = campaignDetails.budget.isEndlessCampaign
isEndlessCampaign = campaignDetails.budget.isEndlessCampaign,
objectiveId = campaignDetails.objectiveId
)
)

Expand Down Expand Up @@ -384,6 +388,7 @@ class BlazeRepository @Inject constructor(
val budget: Budget,
val targetingParameters: TargetingParameters,
val destinationParameters: DestinationParameters,
val objectiveId: String
) : Parcelable

sealed interface BlazeCampaignImage : Parcelable {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.woocommerce.android.ui.blaze.creation.objective

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.compose.material.Text
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import com.woocommerce.android.ui.base.BaseFragment
import com.woocommerce.android.ui.compose.composeView
import com.woocommerce.android.ui.main.AppBarStatus
import com.woocommerce.android.viewmodel.MultiLiveEvent
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class BlazeCampaignObjectiveFragment : BaseFragment() {
override val activityAppBarStatus: AppBarStatus
get() = AppBarStatus.Hidden

val viewModel: BlazeCampaignObjectiveViewModel by viewModels()

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return composeView {
Text(text = "Select Campaign Objective")
}
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
handleEvents()
}

private fun handleEvents() {
viewModel.event.observe(viewLifecycleOwner) { event ->
when (event) {
is MultiLiveEvent.Event.Exit -> findNavController().navigateUp()
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.woocommerce.android.ui.blaze.creation.objective

import androidx.lifecycle.SavedStateHandle
import com.woocommerce.android.viewmodel.MultiLiveEvent.Event.Exit
import com.woocommerce.android.viewmodel.ScopedViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject

@HiltViewModel
class BlazeCampaignObjectiveViewModel @Inject constructor(
savedStateHandle: SavedStateHandle
) : ScopedViewModel(savedStateHandle) {
fun onDismissClick() {
triggerEvent(Exit)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import com.woocommerce.android.ui.blaze.creation.destination.BlazeCampaignCreati
import com.woocommerce.android.ui.blaze.creation.preview.BlazeCampaignCreationPreviewViewModel.NavigateToAdDestinationScreen
import com.woocommerce.android.ui.blaze.creation.preview.BlazeCampaignCreationPreviewViewModel.NavigateToBudgetScreen
import com.woocommerce.android.ui.blaze.creation.preview.BlazeCampaignCreationPreviewViewModel.NavigateToEditAdScreen
import com.woocommerce.android.ui.blaze.creation.preview.BlazeCampaignCreationPreviewViewModel.NavigateToObjectiveSelectionScreen
import com.woocommerce.android.ui.blaze.creation.preview.BlazeCampaignCreationPreviewViewModel.NavigateToPaymentSummary
import com.woocommerce.android.ui.blaze.creation.preview.BlazeCampaignCreationPreviewViewModel.NavigateToTargetLocationSelectionScreen
import com.woocommerce.android.ui.blaze.creation.preview.BlazeCampaignCreationPreviewViewModel.NavigateToTargetSelectionScreen
Expand Down Expand Up @@ -99,12 +100,18 @@ class BlazeCampaignCreationPreviewFragment : BaseFragment() {
event.destinationParameters
)
)

is NavigateToPaymentSummary -> findNavController().navigateSafely(
BlazeCampaignCreationPreviewFragmentDirections
.actionBlazeCampaignCreationPreviewFragmentToBlazeCampaignPaymentSummaryFragment(
event.campaignDetails
)
)

is NavigateToObjectiveSelectionScreen -> findNavController().navigateSafely(
BlazeCampaignCreationPreviewFragmentDirections
.actionBlazeCampaignCreationPreviewFragmentToBlazeCampaignObjectiveFragment()
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ fun CampaignDetails(
style = MaterialTheme.typography.body2
)
// Budget
CampaignPropertyGroupItem(items = listOf(campaignDetails.budget))
CampaignPropertyGroupItem(items = listOf(campaignDetails.selectedObjective, campaignDetails.budget))
Spacer(modifier = Modifier.height(16.dp))

// Ad Audience
Expand Down Expand Up @@ -449,7 +449,12 @@ fun CampaignScreenPreview() {
displayValue = "https://www.myer.com.au/p/white-t-shirt-797334760-797334760",
onItemSelected = {},
maxLinesValue = 1,
)
),
selectedObjective = CampaignDetailItemUi(
displayTitle = stringResource(R.string.blaze_campaign_preview_details_objective),
displayValue = "Sales",
onItemSelected = {},
),
)
),
onBackPressed = { },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.woocommerce.android.support.help.HelpOrigin
import com.woocommerce.android.ui.blaze.BlazeRepository
import com.woocommerce.android.ui.blaze.BlazeRepository.AiSuggestionForAd
import com.woocommerce.android.ui.blaze.BlazeRepository.CampaignDetails
import com.woocommerce.android.ui.blaze.BlazeRepository.Objective
import com.woocommerce.android.ui.blaze.Location
import com.woocommerce.android.ui.blaze.creation.targets.BlazeTargetType
import com.woocommerce.android.ui.blaze.creation.targets.BlazeTargetType.DEVICE
Expand Down Expand Up @@ -43,7 +44,7 @@ class BlazeCampaignCreationPreviewViewModel @Inject constructor(
private val blazeRepository: BlazeRepository,
private val resourceProvider: ResourceProvider,
private val currencyFormatter: CurrencyFormatter,
private val analyticsTrackerWrapper: AnalyticsTrackerWrapper,
private val analyticsTrackerWrapper: AnalyticsTrackerWrapper
) : ScopedViewModel(savedStateHandle) {
private val navArgs: BlazeCampaignCreationPreviewFragmentArgs by savedStateHandle.navArgs()
private val campaignDetails = savedStateHandle.getNullableStateFlow(
Expand All @@ -53,15 +54,18 @@ class BlazeCampaignCreationPreviewViewModel @Inject constructor(
clazz = CampaignDetails::class.java
)
private var aiSuggestions: List<AiSuggestionForAd> = emptyList()
private var campaignObjectives: List<Objective> = emptyList()

private val adDetailsState = savedStateHandle.getStateFlow(viewModelScope, AdDetailsUiState.LOADING)
private val dialogState = MutableStateFlow<DialogState?>(null)

val viewState = combine(
campaignDetails.filterNotNull(),
adDetailsState,
dialogState
) { campaignDetails, adDetailsState, dialogState ->
dialogState,
blazeRepository.observeObjectives()
) { campaignDetails, adDetailsState, dialogState, objectives ->
campaignObjectives = objectives
CampaignPreviewUiState(
adDetails = when (adDetailsState) {
AdDetailsUiState.LOADING -> AdDetailsUi.Loading
Expand Down Expand Up @@ -234,6 +238,7 @@ class BlazeCampaignCreationPreviewViewModel @Inject constructor(
)
}
}
blazeRepository.fetchObjectives()
}
}

Expand All @@ -245,9 +250,22 @@ class BlazeCampaignCreationPreviewViewModel @Inject constructor(
getTargetLocationsDetails(),
getTargetInterestsDetails(),
),
destinationUrl = getTargetDestinationDetails()
destinationUrl = getTargetDestinationDetails(),
selectedObjective = getSelectedObjective(campaignObjectives)
)

private fun getSelectedObjective(objectives: List<Objective>): CampaignDetailItemUi {
val selectedObjectiveDisplayValue = objectives
.find { it.id == campaignDetails.value?.objectiveId }
?.title
?: resourceProvider.getString(R.string.blaze_campaign_preview_details_choose_objective)
return CampaignDetailItemUi(
displayTitle = resourceProvider.getString(R.string.blaze_campaign_preview_details_objective),
displayValue = selectedObjectiveDisplayValue,
onItemSelected = { triggerEvent(NavigateToObjectiveSelectionScreen) }
)
}

private fun CampaignDetails.getBudgetDetails() =
CampaignDetailItemUi(
displayTitle = resourceProvider.getString(R.string.blaze_campaign_preview_details_budget),
Expand Down Expand Up @@ -365,6 +383,7 @@ class BlazeCampaignCreationPreviewViewModel @Inject constructor(
val budget: CampaignDetailItemUi,
val targetDetails: List<CampaignDetailItemUi>,
val destinationUrl: CampaignDetailItemUi,
val selectedObjective: CampaignDetailItemUi
)

data class CampaignDetailItemUi(
Expand Down Expand Up @@ -404,4 +423,6 @@ class BlazeCampaignCreationPreviewViewModel @Inject constructor(
data class NavigateToPaymentSummary(
val campaignDetails: CampaignDetails
) : MultiLiveEvent.Event()

data object NavigateToObjectiveSelectionScreen : MultiLiveEvent.Event()
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@
<action
android:id="@+id/action_blazeCampaignCreationPreviewFragment_to_blazeCampaignPaymentSummaryFragment"
app:destination="@id/blazeCampaignPaymentSummaryFragment" />
<action
android:id="@+id/action_blazeCampaignCreationPreviewFragment_to_blazeCampaignObjectiveFragment"
app:destination="@id/blazeCampaignObjectiveFragment" />
</fragment>
<fragment
android:id="@+id/blazeCampaignCreationEditAdFragment"
Expand Down Expand Up @@ -194,4 +197,8 @@
android:name="productId"
app:argType="long" />
</fragment>
<fragment
android:id="@+id/blazeCampaignObjectiveFragment"
android:name="com.woocommerce.android.ui.blaze.creation.objective.BlazeCampaignObjectiveFragment"
android:label="BlazeCampaignObjectiveFragment" />
</navigation>
2 changes: 2 additions & 0 deletions WooCommerce/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3899,6 +3899,8 @@
<string name="blaze_campaign_preview_details_section_title">Details</string>
<string name="blaze_campaign_preview_audience_section_title">Audience</string>
<string name="blaze_campaign_preview_details_budget">Budget</string>
<string name="blaze_campaign_preview_details_objective">Campaign objective</string>
<string name="blaze_campaign_preview_details_choose_objective">Choose campaign objective</string>
<string name="blaze_campaign_preview_details_language">Language</string>
<string name="blaze_campaign_preview_details_devices">Devices</string>
<string name="blaze_campaign_preview_details_location">Location</string>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.woocommerce.android.ui.blaze

import com.woocommerce.android.AppPrefsWrapper
import com.woocommerce.android.media.MediaFilesRepository
import com.woocommerce.android.tools.SelectedSite
import com.woocommerce.android.ui.blaze.BlazeRepository.BlazeCampaignImage.RemoteImage
Expand Down Expand Up @@ -47,14 +48,16 @@ class BlazeRepositoryTest : BaseUnitTest() {
onBlocking { fetchWordPressMedia(AD_IMAGE.mediaId) } doReturn
Result.success(mediaModel)
}
private val appPrefsWrapper: AppPrefsWrapper = mock()

private val createCampaignRequestCaptor = argumentCaptor<BlazeCampaignCreationRequest>()

private val repository = BlazeRepository(
selectedSite,
blazeCampaignsStore,
productDetailRepository,
mediaFilesRepository
mediaFilesRepository,
appPrefsWrapper
)

@Test
Expand Down Expand Up @@ -129,6 +132,7 @@ class BlazeRepositoryTest : BaseUnitTest() {
budget = DEFAULT_BUDGET,
targetingParameters = EMPTY_TARGETING_PARAMETERS,
destinationParameters = EMPTY_DESTINATION_PARAMETERS,
objectiveId = "sales",
)
private val ENDLESS_CAMPAIGN_DETAILS = DEFAULT_CAMPAIGN_DETAILS.copy(
budget = DEFAULT_BUDGET.copy(isEndlessCampaign = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ class BlazeCampaignPaymentSummaryViewModelTests : BaseUnitTest() {
destinationParameters = BlazeRepository.DestinationParameters(
targetUrl = "https://test.com",
parameters = emptyMap()
)
),
objectiveId = "sales"
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.woocommerce.android.extensions.formatToMMMdd
import com.woocommerce.android.model.UiString
import com.woocommerce.android.ui.blaze.BlazeRepository
import com.woocommerce.android.ui.blaze.BlazeRepository.BlazeCampaignImage
import com.woocommerce.android.ui.blaze.BlazeRepository.Objective
import com.woocommerce.android.ui.blaze.BlazeUrlsHelper.BlazeFlowSource
import com.woocommerce.android.ui.blaze.Device
import com.woocommerce.android.ui.blaze.Interest
Expand Down Expand Up @@ -57,12 +58,14 @@ class BlazeCampaignCreationPreviewViewModelTests : BaseUnitTest() {
targetUrl = "http://test_url",
parameters = emptyMap()
),
targetingParameters = BlazeRepository.TargetingParameters()
targetingParameters = BlazeRepository.TargetingParameters(),
objectiveId = "sales"
)
private val locations = listOf(Location(1, "Location 1"), Location(2, "Location 2"))
private val languages = listOf(Language("en", "English"), Language("es", "Spanish"))
private val interests = listOf(Interest("1", "Interest 1"), Interest("2", "Interest 2"))
private val devices = listOf(Device("1", "Device 1"), Device("2", "Device 2"))
private val objectives = listOf(Objective("sales", "Sales", "Get more sales", ""))
}

private val currencyFormatter: CurrencyFormatter = mock {
Expand All @@ -77,6 +80,7 @@ class BlazeCampaignCreationPreviewViewModelTests : BaseUnitTest() {
on { observeDevices() } doReturn flowOf(devices)
on { observeInterests() } doReturn flowOf(interests)
on { observeLanguages() } doReturn flowOf(languages)
on { observeObjectives() } doReturn flowOf(objectives)
}
private val analyticsTracker: AnalyticsTrackerWrapper = mock()
private lateinit var viewModel: BlazeCampaignCreationPreviewViewModel
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ tasks.register("installGitHooks", Copy) {
}

ext {
fluxCVersion = '2.98.0'
fluxCVersion = 'trunk-7e2a6b2524a39103ade0b034e40a9e1a013a6d2a'
glideVersion = '4.16.0'
coilVersion = '2.1.0'
constraintLayoutVersion = '1.2.0'
Expand Down

0 comments on commit 51c89cc

Please sign in to comment.