Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
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 @@ -149,7 +149,7 @@ class BlazeRepository @Inject constructor(

suspend fun fetchAdSuggestions(productId: Long): Result<List<AiSuggestionForAd>> {
fun List<BlazeAdSuggestion>.mapToUiModel(): List<AiSuggestionForAd> {
return map { AiSuggestionForAd(it.tagLine, it.description) }
return map { AiSuggestionForAd(it.tagLine, it.description, it.ctaText) }
}

val result = blazeCampaignsStore.fetchBlazeAdSuggestions(selectedSite.get(), productId)
Expand Down Expand Up @@ -194,7 +194,8 @@ class BlazeRepository @Inject constructor(
targetUrl = product.permalink,
parameters = emptyMap()
),
objectiveId = appPrefsWrapper.blazeCampaignSelectedObjective
objectiveId = appPrefsWrapper.blazeCampaignSelectedObjective,
ctaText = ""
)
}

Expand Down Expand Up @@ -273,6 +274,7 @@ class BlazeRepository @Inject constructor(
)
}

@Suppress("LongMethod")
suspend fun createCampaign(
campaignDetails: CampaignDetails,
paymentMethodId: String
Expand All @@ -297,6 +299,7 @@ class BlazeRepository @Inject constructor(
targetResourceId = campaignDetails.productId,
tagLine = campaignDetails.tagLine,
description = campaignDetails.description,
ctaText = campaignDetails.ctaText,
startDate = campaignDetails.budget.startDate,
endDate = campaignDetails.budget.endDate,
budget = BlazeCampaignCreationRequestBudget(
Expand Down Expand Up @@ -394,6 +397,7 @@ class BlazeRepository @Inject constructor(
val productId: Long,
val tagLine: String,
val description: String,
val ctaText: String,
val campaignImage: BlazeCampaignImage,
val budget: Budget,
val targetingParameters: TargetingParameters,
Expand Down Expand Up @@ -446,6 +450,7 @@ class BlazeRepository @Inject constructor(
data class AiSuggestionForAd(
val tagLine: String,
val description: String,
val ctaText: String
) : Parcelable

@Parcelize
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ fun BlazeCampaignCreationPreviewScreen(viewModel: BlazeCampaignCreationEditAdVie
onMediaPickerDialogDismissed = viewModel::onMediaPickerDialogDismissed,
onProductImagesRequested = viewModel::onProductImagesRequested,
onMediaLibraryRequested = viewModel::onMediaLibraryRequested,
onSaveTapped = viewModel::onSaveTapped
onSaveTapped = viewModel::onSaveTapped,
onCtaTextChanged = viewModel::onCtaTextChanged
)
}
}
Expand All @@ -88,7 +89,8 @@ private fun BlazeCampaignCreationEditAdScreen(
onMediaPickerDialogDismissed: () -> Unit,
onProductImagesRequested: () -> Unit,
onMediaLibraryRequested: (DataSource) -> Unit,
onSaveTapped: () -> Unit
onSaveTapped: () -> Unit,
onCtaTextChanged: (String) -> Unit
) {
if (viewState.isMediaPickerDialogVisible) {
MediaPickerDialog(
Expand Down Expand Up @@ -123,7 +125,8 @@ private fun BlazeCampaignCreationEditAdScreen(
onDescriptionChanged,
onChangeImageTapped,
onPreviousSuggestionTapped,
onNextSuggestionTapped
onNextSuggestionTapped,
onCtaTextChanged
)
}
}
Expand All @@ -137,6 +140,7 @@ fun CampaignEditAdContent(
onChangeImageTapped: () -> Unit,
onPreviousSuggestionTapped: () -> Unit,
onNextSuggestionTapped: () -> Unit,
onCtaTextChanged: (String) -> Unit
) {
Column(
modifier = Modifier
Expand All @@ -156,7 +160,8 @@ fun CampaignEditAdContent(
onTagLineChanged = onTagLineChanged,
onDescriptionChanged = onDescriptionChanged,
onPreviousSuggestionTapped = onPreviousSuggestionTapped,
onNextSuggestionTapped = onNextSuggestionTapped
onNextSuggestionTapped = onNextSuggestionTapped,
onCtaTextChanged = onCtaTextChanged
)
}
}
Expand All @@ -167,70 +172,25 @@ private fun AdDataSection(
onTagLineChanged: (String) -> Unit,
onDescriptionChanged: (String) -> Unit,
onPreviousSuggestionTapped: () -> Unit,
onNextSuggestionTapped: () -> Unit
onNextSuggestionTapped: () -> Unit,
onCtaTextChanged: (String) -> Unit
) {
Column(
modifier = Modifier
.padding(dimensionResource(id = dimen.major_100))
.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Box {
WCOutlinedTextField(
value = viewState.tagLine,
onValueChange = onTagLineChanged,
label = stringResource(id = string.blaze_campaign_edit_ad_change_tagline_title),
singleLine = true,
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next)
)

CornerCharacterWarning(
charsLeft = viewState.taglineCharactersRemaining,
modifier = Modifier.align(Alignment.TopEnd)
)
}

Text(
text = stringResource(
id = string.blaze_campaign_edit_ad_characters_remaining,
viewState.taglineCharactersRemaining
),
style = MaterialTheme.typography.caption,
color = colorResource(id = color.color_on_surface_disabled),
modifier = Modifier
.padding(top = dimensionResource(id = dimen.minor_100))
.fillMaxWidth()
TaglineInputText(viewState, onTagLineChanged)
DescriptionInputText(
viewState,
onDescriptionChanged,
modifier = Modifier.padding(top = dimensionResource(id = dimen.major_150))
)

Box(
modifier = Modifier
.padding(top = dimensionResource(id = dimen.major_150))
) {
WCOutlinedTextField(
value = viewState.description,
onValueChange = onDescriptionChanged,
label = stringResource(id = string.blaze_campaign_edit_ad_change_description_title),
maxLines = 3,
minLines = 3,
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next)
)

CornerCharacterWarning(
charsLeft = viewState.descriptionCharactersRemaining,
modifier = Modifier.align(Alignment.TopEnd)
)
}

Text(
text = stringResource(
id = string.blaze_campaign_edit_ad_characters_remaining,
viewState.descriptionCharactersRemaining
),
style = MaterialTheme.typography.caption,
color = colorResource(id = color.color_on_surface_disabled),
modifier = Modifier
.padding(top = dimensionResource(id = dimen.minor_100))
.fillMaxWidth()
CallToActionInputText(
viewState,
onCtaTextChanged,
modifier = Modifier.padding(top = dimensionResource(id = dimen.major_150))
)

if (viewState.suggestions.size > 1) {
Expand Down Expand Up @@ -271,6 +231,97 @@ private fun AdDataSection(
}
}

@Composable
private fun DescriptionInputText(
viewState: ViewState,
onDescriptionChanged: (String) -> Unit,
modifier: Modifier = Modifier
) {
val isError = viewState.description.isEmpty()
Box(modifier = modifier) {
WCOutlinedTextField(
value = viewState.description,
onValueChange = onDescriptionChanged,
label = stringResource(id = string.blaze_campaign_edit_ad_change_description_title),
maxLines = 3,
minLines = 3,
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
helperText = when {
isError -> stringResource(id = string.blaze_campaign_edit_ad_change_description_empty_error)
else ->
stringResource(
id = string.blaze_campaign_edit_ad_characters_remaining,
viewState.descriptionCharactersRemaining
)
},
isError = isError
)

CornerCharacterWarning(
charsLeft = viewState.descriptionCharactersRemaining,
modifier = Modifier.align(Alignment.TopEnd)
)
}
}

@Composable
private fun TaglineInputText(
viewState: ViewState,
onTagLineChanged: (String) -> Unit,
modifier: Modifier = Modifier
) {
val isError = viewState.tagLine.isEmpty()
Box(modifier = modifier) {
WCOutlinedTextField(
value = viewState.tagLine,
onValueChange = onTagLineChanged,
label = stringResource(id = string.blaze_campaign_edit_ad_change_tagline_title),
singleLine = true,
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
helperText = when {
isError -> stringResource(id = string.blaze_campaign_edit_ad_change_tagline_empty_error)
else ->
stringResource(
id = string.blaze_campaign_edit_ad_characters_remaining,
viewState.taglineCharactersRemaining
)
},
isError = isError
)

CornerCharacterWarning(
charsLeft = viewState.taglineCharactersRemaining,
modifier = Modifier.align(Alignment.TopEnd)
)
}
}

@Composable
private fun CallToActionInputText(
viewState: ViewState,
onCtaTextChanged: (String) -> Unit,
modifier: Modifier = Modifier
) {
Box(modifier = modifier) {
WCOutlinedTextField(
value = viewState.ctaText,
onValueChange = onCtaTextChanged,
label = stringResource(id = string.blaze_campaign_edit_ad_change_cta_text_title),
singleLine = true,
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
helperText = stringResource(
id = string.blaze_campaign_edit_ad_characters_remaining,
viewState.ctaTextCharactersRemaining
),
)

CornerCharacterWarning(
charsLeft = viewState.ctaTextCharactersRemaining,
modifier = Modifier.align(Alignment.TopEnd)
)
}
}

@Composable
private fun CornerCharacterWarning(charsLeft: Int, modifier: Modifier = Modifier) {
if (charsLeft < 10) {
Expand Down Expand Up @@ -380,7 +431,8 @@ fun PreviewCampaignEditAdContent() {
onDescriptionChanged = { },
onChangeImageTapped = { },
onPreviousSuggestionTapped = { },
onNextSuggestionTapped = { }
onNextSuggestionTapped = { },
onCtaTextChanged = { },
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class BlazeCampaignCreationEditAdViewModel @Inject constructor(
companion object {
private const val TAGLINE_MAX_LENGTH = 32
private const val DESCRIPTION_MAX_LENGTH = 140
private const val CTA_TEST_MAX_LENGTH = 26
}

private val navArgs: BlazeCampaignCreationEditAdFragmentArgs by savedStateHandle.navArgs()
Expand All @@ -49,7 +50,7 @@ class BlazeCampaignCreationEditAdViewModel @Inject constructor(

private fun loadSuggestions() {
viewModelScope.launch {
val passedDetails = AiSuggestionForAd(navArgs.tagline, navArgs.description)
val passedDetails = AiSuggestionForAd(navArgs.tagline, navArgs.description, navArgs.ctaText)
val suggestions = navArgs.aiSuggestionsForAd.toList()
_viewState.update {
it.copy(
Expand Down Expand Up @@ -83,7 +84,8 @@ class BlazeCampaignCreationEditAdViewModel @Inject constructor(
EditAdResult(
tagline = _viewState.value.tagLine,
description = _viewState.value.description,
campaignImage = _viewState.value.adImage
campaignImage = _viewState.value.adImage,
ctaText = _viewState.value.ctaText
)
)
)
Expand All @@ -107,11 +109,23 @@ class BlazeCampaignCreationEditAdViewModel @Inject constructor(
}

fun onTagLineChanged(tagLine: String) {
updateSuggestion(AiSuggestionForAd(tagLine.take(TAGLINE_MAX_LENGTH), _viewState.value.description))
updateSuggestion(
AiSuggestionForAd(
tagLine.take(TAGLINE_MAX_LENGTH),
_viewState.value.description,
_viewState.value.ctaText
)
)
}

fun onDescriptionChanged(description: String) {
updateSuggestion(AiSuggestionForAd(_viewState.value.tagLine, description.take(DESCRIPTION_MAX_LENGTH)))
updateSuggestion(
AiSuggestionForAd(
_viewState.value.tagLine,
description.take(DESCRIPTION_MAX_LENGTH),
_viewState.value.ctaText
)
)
}

fun onLocalImageSelected(uri: String) {
Expand Down Expand Up @@ -175,6 +189,16 @@ class BlazeCampaignCreationEditAdViewModel @Inject constructor(
setMediaPickerDialogVisibility(false)
}

fun onCtaTextChanged(ctaText: String) {
updateSuggestion(
AiSuggestionForAd(
_viewState.value.tagLine,
_viewState.value.description,
ctaText.take(CTA_TEST_MAX_LENGTH)
)
)
}

data class ShowMediaLibrary(val source: MediaPickerSetup.DataSource) : Event()
data class ShowProductImagePicker(val productId: Long) : Event()

Expand All @@ -189,10 +213,14 @@ class BlazeCampaignCreationEditAdViewModel @Inject constructor(
get() = suggestions.getOrNull(suggestionIndex)?.tagLine ?: ""
val description: String
get() = suggestions.getOrNull(suggestionIndex)?.description ?: ""
val ctaText: String
get() = suggestions.getOrNull(suggestionIndex)?.ctaText ?: ""
val taglineCharactersRemaining: Int
get() = TAGLINE_MAX_LENGTH - (suggestions.getOrNull(suggestionIndex)?.tagLine?.length ?: 0)
val descriptionCharactersRemaining: Int
get() = DESCRIPTION_MAX_LENGTH - (suggestions.getOrNull(suggestionIndex)?.description?.length ?: 0)
val ctaTextCharactersRemaining: Int
get() = CTA_TEST_MAX_LENGTH - (suggestions.getOrNull(suggestionIndex)?.ctaText?.length ?: 0)
val isPreviousSuggestionButtonEnabled: Boolean
get() = suggestionIndex > 0
val isNextSuggestionButtonEnabled: Boolean
Expand All @@ -203,6 +231,7 @@ class BlazeCampaignCreationEditAdViewModel @Inject constructor(
data class EditAdResult(
val tagline: String,
val description: String,
val campaignImage: BlazeRepository.BlazeCampaignImage
val campaignImage: BlazeRepository.BlazeCampaignImage,
val ctaText: String
) : Parcelable
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class BlazeCampaignCreationPreviewFragment : BaseFragment() {
productId = event.productId,
tagline = event.tagLine,
description = event.description,
ctaText = event.ctaText,
adImage = event.campaignImage,
aiSuggestionsForAd = event.aiSuggestions.toTypedArray()
)
Expand Down Expand Up @@ -120,7 +121,7 @@ class BlazeCampaignCreationPreviewFragment : BaseFragment() {

private fun handleResults() {
handleResult<EditAdResult>(BlazeCampaignCreationEditAdFragment.EDIT_AD_RESULT) {
viewModel.onAdUpdated(it.tagline, it.description, it.campaignImage)
viewModel.onAdUpdated(it)
}
handleResult<ObjectiveResult>(BlazeCampaignObjectiveFragment.BLAZE_OBJECTIVE_SELECTION_RESULT) {
viewModel.onObjectiveUpdated(it.objectiveId)
Expand Down
Loading
Loading