diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/ad/BlazeCampaignCreationEditAdFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/ad/BlazeCampaignCreationEditAdFragment.kt index 220d85853f5..ce57ed1000a 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/ad/BlazeCampaignCreationEditAdFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/ad/BlazeCampaignCreationEditAdFragment.kt @@ -1,25 +1,61 @@ package com.woocommerce.android.ui.blaze.creation.ad +import android.net.Uri 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.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.ShowMediaLibrary import com.woocommerce.android.ui.compose.composeView import com.woocommerce.android.ui.main.AppBarStatus +import com.woocommerce.android.viewmodel.MultiLiveEvent.Event.Exit import dagger.hilt.android.AndroidEntryPoint +import javax.inject.Inject @AndroidEntryPoint -class BlazeCampaignCreationEditAdFragment : BaseFragment() { +class BlazeCampaignCreationEditAdFragment : BaseFragment(), MediaPickerResultHandler { override val activityAppBarStatus: AppBarStatus get() = AppBarStatus.Hidden val viewModel: BlazeCampaignCreationEditAdViewModel by viewModels() + @Inject + lateinit var mediaPickerHelper: MediaPickerHelper + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { return composeView { BlazeCampaignCreationPreviewScreen(viewModel = viewModel) } } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + viewModel.event.observe(viewLifecycleOwner) { event -> + when (event) { + is Exit -> findNavController().popBackStack() + is ShowMediaLibrary -> mediaPickerHelper.showMediaPicker(event.source) + } + } + } + + override fun onDeviceMediaSelected(imageUris: List, source: String) { + if (imageUris.isNotEmpty()) { + onImageSelected(imageUris.first().toString()) + } + } + + override fun onWPMediaSelected(images: List) { + if (images.isNotEmpty()) { + onImageSelected(images.first().source) + } + } + + private fun onImageSelected(mediaUri: String) { + viewModel.onImageChanged(mediaUri) + } } diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/ad/BlazeCampaignCreationEditAdScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/ad/BlazeCampaignCreationEditAdScreen.kt index 362ccc3f824..98e8518fafd 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/ad/BlazeCampaignCreationEditAdScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/ad/BlazeCampaignCreationEditAdScreen.kt @@ -43,11 +43,13 @@ import coil.compose.AsyncImage import coil.request.ImageRequest import com.woocommerce.android.R import com.woocommerce.android.R.string +import com.woocommerce.android.mediapicker.MediaPickerDialog import com.woocommerce.android.ui.compose.component.Toolbar import com.woocommerce.android.ui.compose.component.WCOutlinedTextField import com.woocommerce.android.ui.compose.component.WCTextButton import com.woocommerce.android.ui.compose.preview.LightDarkThemePreviews import com.woocommerce.android.ui.compose.theme.WooThemeWithBackground +import org.wordpress.android.mediapicker.api.MediaPickerSetup.DataSource @Composable fun BlazeCampaignCreationPreviewScreen(viewModel: BlazeCampaignCreationEditAdViewModel) { @@ -59,7 +61,9 @@ fun BlazeCampaignCreationPreviewScreen(viewModel: BlazeCampaignCreationEditAdVie onChangeImageTapped = viewModel::onChangeImageTapped, onPreviousSuggestionTapped = viewModel::onPreviousSuggestionTapped, onNextSuggestionTapped = viewModel::onNextSuggestionTapped, - onBackButtonTapped = viewModel::onBackButtonTapped + onBackButtonTapped = viewModel::onBackButtonTapped, + onMediaPickerDialogDismissed = viewModel::onMediaPickerDialogDismissed, + onMediaLibraryRequested = viewModel::onMediaLibraryRequested ) } } @@ -72,8 +76,16 @@ private fun BlazeCampaignCreationEditAdScreen( onChangeImageTapped: () -> Unit, onPreviousSuggestionTapped: () -> Unit, onNextSuggestionTapped: () -> Unit, - onBackButtonTapped: () -> Unit + onBackButtonTapped: () -> Unit, + onMediaPickerDialogDismissed: () -> Unit, + onMediaLibraryRequested: (DataSource) -> Unit, ) { + if (viewState.isMediaPickerDialogVisible) { + MediaPickerDialog( + onMediaPickerDialogDismissed, + onMediaLibraryRequested + ) + } Scaffold( topBar = { Toolbar( @@ -127,7 +139,7 @@ fun CampaignEditAdContent( ) { AsyncImage( model = ImageRequest.Builder(LocalContext.current) - .data(viewState.campaignImageUrl) + .data(viewState.adImageUrl) .crossfade(true) .fallback(R.drawable.blaze_campaign_product_placeholder) .placeholder(R.drawable.blaze_campaign_product_placeholder) @@ -278,7 +290,7 @@ fun PreviewCampaignEditAdContent() { viewState = BlazeCampaignCreationEditAdViewModel.ViewState( tagLine = "From 45.00 USD", description = "Get the latest white t-shirts", - campaignImageUrl = "https://rb.gy/gmjuwb" + adImageUrl = "https://rb.gy/gmjuwb" ), onTagLineChanged = { }, onDescriptionChanged = { }, diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/ad/BlazeCampaignCreationEditAdViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/ad/BlazeCampaignCreationEditAdViewModel.kt index 9aea231f2d7..ec63638e6e1 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/ad/BlazeCampaignCreationEditAdViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/blaze/creation/ad/BlazeCampaignCreationEditAdViewModel.kt @@ -2,10 +2,14 @@ package com.woocommerce.android.ui.blaze.creation.ad import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.asLiveData +import com.woocommerce.android.viewmodel.MultiLiveEvent.Event +import com.woocommerce.android.viewmodel.MultiLiveEvent.Event.Exit import com.woocommerce.android.viewmodel.ScopedViewModel import com.woocommerce.android.viewmodel.navArgs import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.update +import org.wordpress.android.mediapicker.api.MediaPickerSetup import javax.inject.Inject @HiltViewModel @@ -25,9 +29,10 @@ class BlazeCampaignCreationEditAdViewModel @Inject constructor( data class ViewState( val tagLine: String, val description: String, - val campaignImageUrl: String?, + val adImageUrl: String?, val isPreviousSuggestionButtonEnabled: Boolean = false, val isNextSuggestionButtonEnabled: Boolean = true, + val isMediaPickerDialogVisible: Boolean = false ) { val taglineCharactersRemaining: Int get() = TAGLINE_MAX_LENGTH - tagLine.length @@ -44,11 +49,20 @@ class BlazeCampaignCreationEditAdViewModel @Inject constructor( } fun onChangeImageTapped() { - /* TODO */ + setMediaPickerDialogVisibility(true) + } + + fun onMediaPickerDialogDismissed() { + setMediaPickerDialogVisibility(false) + } + + fun onMediaLibraryRequested(source: MediaPickerSetup.DataSource) { + triggerEvent(ShowMediaLibrary(source)) + setMediaPickerDialogVisibility(false) } fun onBackButtonTapped() { - /* TODO */ + triggerEvent(Exit) } fun onTagLineChanged(tagLine: String) { @@ -58,4 +72,18 @@ class BlazeCampaignCreationEditAdViewModel @Inject constructor( fun onDescriptionChanged(description: String) { _viewState.value = _viewState.value.copy(description = description.take(DESCRIPTION_MAX_LENGTH)) } + + fun onImageChanged(url: String) { + _viewState.update { + _viewState.value.copy(adImageUrl = url) + } + } + + private fun setMediaPickerDialogVisibility(isVisible: Boolean) { + _viewState.update { + _viewState.value.copy(isMediaPickerDialogVisible = isVisible) + } + } + + data class ShowMediaLibrary(val source: MediaPickerSetup.DataSource) : Event() } diff --git a/WooCommerce/src/main/res/values/dimens_base.xml b/WooCommerce/src/main/res/values/dimens_base.xml index 622f79945a8..7c42dc904b1 100644 --- a/WooCommerce/src/main/res/values/dimens_base.xml +++ b/WooCommerce/src/main/res/values/dimens_base.xml @@ -133,6 +133,7 @@ so that's the baseline as defined in `major_100`. 56dp 280dp 8dp + 32dp 56dp 91dp 64dp