Skip to content

Commit

Permalink
Merge branch 'trunk' into issue/12561-fix-renaming-attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
toupper authored Sep 16, 2024
2 parents 6ee2c13 + d1eb9ed commit baa7dea
Show file tree
Hide file tree
Showing 22 changed files with 431 additions and 35 deletions.
18 changes: 18 additions & 0 deletions .buildkite/commands/lint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash -u

echo "--- 🧹 Linting"
cp gradle.properties-example gradle.properties
./gradlew :WooCommerce:lintJalapenoDebug
app_lint_exit_code=$?

./gradlew :WooCommerce-Wear:lintJalapenoDebug
wear_lint_exit_code=$?

lint_exit_code=0
if [ $app_lint_exit_code -ne 0 ] || [ $wear_lint_exit_code -ne 0 ]; then
lint_exit_code=1
fi

upload_sarif_to_github 'WooCommerce/build/reports/lint-results-jalapenoDebug.sarif' 'woocommerce' 'woocommerce-android'

exit $lint_exit_code
5 changes: 1 addition & 4 deletions .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,7 @@ steps:
- "**/build/reports/detekt/detekt.html"

- label: "lint"
command: |
echo "--- 🧹 Linting"
cp gradle.properties-example gradle.properties
./gradlew lintJalapenoDebug
command: .buildkite/commands/lint.sh
plugins: [$CI_TOOLKIT]
artifact_paths:
- "**/build/reports/lint-results*.*"
Expand Down
9 changes: 5 additions & 4 deletions .buildkite/shared-pipeline-vars
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#!/bin/sh

# This file is `source`'d before calling `buildkite-agent pipeline upload`, and can be used
# to set up some variables that will be interpolated in the `.yml` pipeline before uploading it.
# This file is `source`'d before calling `buildkite-agent pipeline upload`, and can be used
# to set up some variables that will be interpolated in the `.yml` pipeline before uploading it.

export CI_TOOLKIT="automattic/a8c-ci-toolkit#3.6.2"
export TEST_COLLECTOR="test-collector#v1.10.1"

export CI_TOOLKIT="automattic/a8c-ci-toolkit#3.5.1"
export TEST_COLLECTOR="test-collector#v1.10.1"
2 changes: 1 addition & 1 deletion RELEASE-NOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
20.5
-----
- [*] Fixes a bug that prevented users to rename the Product Variation Attributes to because of case insensitive checks [https://github.com/woocommerce/woocommerce-android/pull/12608]

- [*] Users can directly pick product images when creating Blaze ads [https://github.com/woocommerce/woocommerce-android/pull/12610]

20.4
-----
Expand Down
2 changes: 2 additions & 0 deletions WooCommerce/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ android {
}

lintOptions {
sarifReport System.getenv('CI') ? true : false
checkDependencies true
disable 'InvalidPackage'
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ import org.wordpress.android.mediapicker.api.MediaPickerSetup.DataSource.WP_MEDI
@Composable
fun MediaPickerDialog(
onDismissRequest: () -> Unit,
onMediaLibraryRequested: (DataSource) -> Unit
onMediaLibraryRequested: (DataSource) -> Unit,
withProductImagePicker: Boolean = false,
onProductImagesRequested: () -> Unit = {}
) {
Dialog(onDismissRequest = onDismissRequest) {
Card(
Expand Down Expand Up @@ -74,6 +76,13 @@ fun MediaPickerDialog(
title = string.image_source_wp_media_library,
onClick = { onMediaLibraryRequested(WP_MEDIA_LIBRARY) }
)
if (withProductImagePicker) {
DialogButton(
image = drawable.ic_product,
title = string.image_source_product_images,
onClick = onProductImagesRequested
)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import com.woocommerce.android.extensions.handleResult
import com.woocommerce.android.extensions.navigateBackWithResult
import com.woocommerce.android.extensions.navigateSafely
import com.woocommerce.android.mediapicker.MediaPickerHelper
import com.woocommerce.android.mediapicker.MediaPickerHelper.MediaPickerResultHandler
import com.woocommerce.android.model.Product.Image
import com.woocommerce.android.ui.base.BaseFragment
import com.woocommerce.android.ui.blaze.creation.ad.BlazeCampaignCreationEditAdViewModel.EditAdResult
import com.woocommerce.android.ui.blaze.creation.ad.BlazeCampaignCreationEditAdViewModel.ShowMediaLibrary
import com.woocommerce.android.ui.blaze.creation.ad.BlazeCampaignCreationEditAdViewModel.ShowProductImagePicker
import com.woocommerce.android.ui.blaze.creation.ad.ProductImagePickerViewModel.ImageSelectedResult
import com.woocommerce.android.ui.compose.composeView
import com.woocommerce.android.ui.main.AppBarStatus
import com.woocommerce.android.viewmodel.MultiLiveEvent.Event.Exit
Expand Down Expand Up @@ -43,10 +47,12 @@ class BlazeCampaignCreationEditAdFragment : BaseFragment(), MediaPickerResultHan
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
handleResults()
viewModel.event.observe(viewLifecycleOwner) { event ->
when (event) {
is Exit -> findNavController().popBackStack()
is ShowMediaLibrary -> mediaPickerHelper.showMediaPicker(event.source)
is ShowProductImagePicker -> navigateToProductImagePicker(event.productId)
is ShowDialog -> event.showDialog()
is ExitWithResult<*> -> {
navigateBackWithResult(EDIT_AD_RESULT, event.data as EditAdResult)
Expand All @@ -55,6 +61,19 @@ class BlazeCampaignCreationEditAdFragment : BaseFragment(), MediaPickerResultHan
}
}

private fun navigateToProductImagePicker(productId: Long) {
findNavController().navigateSafely(
BlazeCampaignCreationEditAdFragmentDirections
.actionBlazeCampaignCreationEditAdFragmentToProductImagePickerFragment(productId)
)
}

private fun handleResults() {
handleResult<ImageSelectedResult>(ProductImagePickerFragment.ON_PRODUCT_IMAGE_SELECTED) {
viewModel.onWPMediaSelected(it.productImage)
}
}

override fun onDeviceMediaSelected(imageUris: List<Uri>, source: String) {
if (imageUris.isNotEmpty()) {
viewModel.onLocalImageSelected(imageUris.first().toString())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ fun BlazeCampaignCreationPreviewScreen(viewModel: BlazeCampaignCreationEditAdVie
onNextSuggestionTapped = viewModel::onNextSuggestionTapped,
onBackButtonTapped = viewModel::onBackButtonTapped,
onMediaPickerDialogDismissed = viewModel::onMediaPickerDialogDismissed,
onProductImagesRequested = viewModel::onProductImagesRequested,
onMediaLibraryRequested = viewModel::onMediaLibraryRequested,
onSaveTapped = viewModel::onSaveTapped
)
Expand All @@ -85,13 +86,16 @@ private fun BlazeCampaignCreationEditAdScreen(
onNextSuggestionTapped: () -> Unit,
onBackButtonTapped: () -> Unit,
onMediaPickerDialogDismissed: () -> Unit,
onProductImagesRequested: () -> Unit,
onMediaLibraryRequested: (DataSource) -> Unit,
onSaveTapped: () -> Unit
) {
if (viewState.isMediaPickerDialogVisible) {
MediaPickerDialog(
onMediaPickerDialogDismissed,
onMediaLibraryRequested
onDismissRequest = onMediaPickerDialogDismissed,
onMediaLibraryRequested = onMediaLibraryRequested,
withProductImagePicker = true,
onProductImagesRequested = onProductImagesRequested
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,13 @@ class BlazeCampaignCreationEditAdViewModel @Inject constructor(
}
}

fun onProductImagesRequested() {
triggerEvent(ShowProductImagePicker(navArgs.productId))
setMediaPickerDialogVisibility(false)
}

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

@Parcelize
data class ViewState(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.woocommerce.android.ui.blaze.creation.ad

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import com.woocommerce.android.extensions.navigateBackWithResult
import com.woocommerce.android.ui.base.BaseFragment
import com.woocommerce.android.ui.blaze.creation.ad.ProductImagePickerViewModel.ImageSelectedResult
import com.woocommerce.android.ui.compose.composeView
import com.woocommerce.android.ui.main.AppBarStatus
import com.woocommerce.android.viewmodel.MultiLiveEvent.Event.Exit
import com.woocommerce.android.viewmodel.MultiLiveEvent.Event.ExitWithResult
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class ProductImagePickerFragment : BaseFragment() {
companion object {
const val ON_PRODUCT_IMAGE_SELECTED = "on_product_image_selected"
}

override val activityAppBarStatus: AppBarStatus
get() = AppBarStatus.Hidden

val viewModel: ProductImagePickerViewModel by viewModels()

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return composeView {
ProductImagePickerScreen(viewModel = viewModel)
}
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
viewModel.event.observe(viewLifecycleOwner) { event ->
when (event) {
is Exit -> findNavController().popBackStack()
is ExitWithResult<*> -> {
navigateBackWithResult(ON_PRODUCT_IMAGE_SELECTED, event.data as ImageSelectedResult)
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.woocommerce.android.ui.blaze.creation.ad

import android.os.Parcelable
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import com.woocommerce.android.model.Product
import com.woocommerce.android.ui.products.details.ProductDetailRepository
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.getStateFlow
import com.woocommerce.android.viewmodel.navArgs
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.parcelize.Parcelize
import javax.inject.Inject

@HiltViewModel
class ProductImagePickerViewModel @Inject constructor(
savedStateHandle: SavedStateHandle,
private val productRepository: ProductDetailRepository,
) : ScopedViewModel(savedStateHandle) {
private val navArgs: ProductImagePickerFragmentArgs by savedStateHandle.navArgs()

private val _viewState = savedStateHandle.getStateFlow(
scope = viewModelScope,
initialValue = ViewState(emptyList())
)
val viewState = _viewState.asLiveData()

init {
launch {
val product = productRepository.getProduct(navArgs.productId)
product?.let {
_viewState.update { it.copy(productImages = product.images) }
}
}
}

fun onImageSelected(productImage: Product.Image) {
triggerEvent(
ExitWithResult(
ImageSelectedResult(productImage = productImage)
)
)
}

fun onBackButtonTapped() {
triggerEvent(Exit)
}

@Parcelize
data class ViewState(
val productImages: List<Product.Image>
) : Parcelable

@Parcelize
data class ImageSelectedResult(val productImage: Product.Image) : Parcelable
}
Loading

0 comments on commit baa7dea

Please sign in to comment.