From 2748aa0f76e72a3c4d17e7a0b088c8e288518139 Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Wed, 23 Mar 2022 19:16:59 -0300 Subject: [PATCH 01/29] Create generic FeatureIntroduction dialog --- ...BloggingPromptsOnboardingDialogFragment.kt | 26 +++------ .../FeatureIntroductionDialogFragment.kt | 53 +++++++++++++++++++ ... feature_introduction_dialog_fragment.xml} | 53 ++++++++++++++++--- WordPress/src/main/res/values/styles.xml | 6 +-- 4 files changed, 110 insertions(+), 28 deletions(-) create mode 100644 WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt rename WordPress/src/main/res/layout/{blogging_prompts_onboarding_dialog_fragment.xml => feature_introduction_dialog_fragment.xml} (55%) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt index 636262bd2504..838c5125e59b 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt @@ -1,24 +1,20 @@ package org.wordpress.android.ui.bloggingprompts.onboarding -import android.app.Dialog import android.content.Context import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.fragment.app.DialogFragment import androidx.lifecycle.ViewModelProvider import com.google.android.material.button.MaterialButton -import org.wordpress.android.R import org.wordpress.android.WordPress -import org.wordpress.android.databinding.BloggingPromptsOnboardingDialogFragmentBinding import org.wordpress.android.ui.ActivityLauncher import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenEditor +import org.wordpress.android.ui.featureintroduction.FeatureIntroductionDialogFragment import org.wordpress.android.util.extensions.exhaustive -import org.wordpress.android.util.extensions.setStatusBarAsSurfaceColor import javax.inject.Inject -class BloggingPromptsOnboardingDialogFragment : DialogFragment() { +class BloggingPromptsOnboardingDialogFragment : FeatureIntroductionDialogFragment() { @Inject lateinit var viewModelFactory: ViewModelProvider.Factory private lateinit var viewModel: BloggingPromptsOnboardingViewModel @@ -29,18 +25,6 @@ class BloggingPromptsOnboardingDialogFragment : DialogFragment() { fun newInstance(): BloggingPromptsOnboardingDialogFragment = BloggingPromptsOnboardingDialogFragment() } - override fun getTheme(): Int { - return R.style.BloggingPromptsOnboardingDialogFragment - } - - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val dialog = super.onCreateDialog(savedInstanceState) - viewModel = ViewModelProvider(this, viewModelFactory) - .get(BloggingPromptsOnboardingViewModel::class.java) - dialog.setStatusBarAsSurfaceColor() - return dialog - } - override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -60,6 +44,12 @@ class BloggingPromptsOnboardingDialogFragment : DialogFragment() { (requireActivity().applicationContext as WordPress).component().inject(this) } + override fun onPrimaryButtonClick() = viewModel.onTryNow() + + override fun onSecondaryButtonClick() { + + } + private fun setupTryNow(tryNow: MaterialButton) { tryNow.setOnClickListener { viewModel.onTryNow() } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt new file mode 100644 index 000000000000..d14a46a258d3 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt @@ -0,0 +1,53 @@ +package org.wordpress.android.ui.featureintroduction + +import android.app.Dialog +import android.graphics.drawable.Drawable +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.DialogFragment +import com.google.android.material.button.MaterialButton +import org.wordpress.android.R +import org.wordpress.android.databinding.FeatureIntroductionDialogFragmentBinding +import org.wordpress.android.util.extensions.setStatusBarAsSurfaceColor + +abstract class FeatureIntroductionDialogFragment : DialogFragment() { + abstract fun onPrimaryButtonClick() + abstract fun onSecondaryButtonClick() + abstract val headerTitle: String + abstract val headerIcon: Drawable + + override fun getTheme(): Int { + return R.style.FeatureIntroductionDialogFragment + } + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val dialog = super.onCreateDialog(savedInstanceState) + dialog.setStatusBarAsSurfaceColor() + return dialog + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View = FeatureIntroductionDialogFragmentBinding.inflate(inflater).root + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + val binding = FeatureIntroductionDialogFragmentBinding.bind(view) + setupPrimaryButton(binding.primaryButton) + setupSecondaryButton(binding.secondaryButton) + setupHeaderTitle(binding.headerTitle) + setupHeaderIcon(binding.headerIcon) + } + + private fun setupPrimaryButton(primaryButton: MaterialButton) { + primaryButton.setOnClickListener { onPrimaryButtonClick() } + } + + private fun setupSecondaryButton(secondaryButton: MaterialButton) { + secondaryButton.setOnClickListener { onSecondaryButtonClick() } + } +} diff --git a/WordPress/src/main/res/layout/blogging_prompts_onboarding_dialog_fragment.xml b/WordPress/src/main/res/layout/feature_introduction_dialog_fragment.xml similarity index 55% rename from WordPress/src/main/res/layout/blogging_prompts_onboarding_dialog_fragment.xml rename to WordPress/src/main/res/layout/feature_introduction_dialog_fragment.xml index 6112b16c97fb..d909cc295541 100644 --- a/WordPress/src/main/res/layout/blogging_prompts_onboarding_dialog_fragment.xml +++ b/WordPress/src/main/res/layout/feature_introduction_dialog_fragment.xml @@ -1,6 +1,7 @@ @@ -18,6 +19,44 @@ android:layout_width="match_parent" android:layout_height="match_parent"> + + + + + + + + + + + @@ -34,7 +73,7 @@ android:layout_height="wrap_content"> + app:layout_constraintTop_toTopOf="parent" + tools:text="Primary button" /> + app:layout_constraintTop_toBottomOf="@+id/primary_button" + tools:text="Secondary button" /> diff --git a/WordPress/src/main/res/values/styles.xml b/WordPress/src/main/res/values/styles.xml index 0dd80fb5a977..5fecfdfc91ae 100644 --- a/WordPress/src/main/res/values/styles.xml +++ b/WordPress/src/main/res/values/styles.xml @@ -1398,16 +1398,16 @@ @style/FullScreenDialogFragmentAnimation - - From f71a1ee8a8259077e1af802b7428a9ae8e6e6a30 Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Thu, 24 Mar 2022 16:23:52 -0300 Subject: [PATCH 02/29] Add compose dependencies and config --- WordPress/build.gradle | 9 +++++++++ build.gradle | 2 ++ 2 files changed, 11 insertions(+) diff --git a/WordPress/build.gradle b/WordPress/build.gradle index 5cc6b06ece06..1cd72df5b43e 100644 --- a/WordPress/build.gradle +++ b/WordPress/build.gradle @@ -279,6 +279,11 @@ android { buildFeatures { viewBinding true + compose true + + composeOptions { + kotlinCompilerExtensionVersion = composeVersion + } } } @@ -382,6 +387,10 @@ dependencies { kapt 'com.github.bumptech.glide:compiler:4.10.0' implementation 'com.github.bumptech.glide:volley-integration:4.6.1@aar' + // Compose + implementation "androidx.compose.ui:ui:$composeVersion" + implementation "androidx.compose.foundation:foundation:$composeVersion" + testImplementation "junit:junit:$jUnitVersion" testImplementation 'org.robolectric:robolectric:4.4' diff --git a/build.gradle b/build.gradle index f0be1d9fcc1b..797839e63c86 100644 --- a/build.gradle +++ b/build.gradle @@ -31,6 +31,8 @@ ext { exoPlayerVersion = '2.9.3' + composeVersion = '1.1.1' + // testing jUnitVersion = '4.13' androidxTestVersion = '1.1.0' From fca69c2f683f64a4a68e159f3ff9fd5ddead486e Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Thu, 24 Mar 2022 16:24:27 -0300 Subject: [PATCH 03/29] Implement Blogging Prompts introduction dialog using FeatureIntroductionDialogFragment --- .../BloggingPromptsOnboardingAction.kt | 4 ++ ...BloggingPromptsOnboardingDialogFragment.kt | 46 +++++++++++++------ .../BloggingPromptsOnboardingViewModel.kt | 16 ++++++- .../FeatureIntroductionDialogFragment.kt | 46 +++++++++++++------ .../feature_introduction_dialog_fragment.xml | 25 ++++++++-- WordPress/src/main/res/values/strings.xml | 1 + .../BloggingPromptsOnboardingViewModelTest.kt | 2 +- 7 files changed, 103 insertions(+), 37 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingAction.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingAction.kt index e18295e073fc..77627437d2c0 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingAction.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingAction.kt @@ -4,4 +4,8 @@ import org.wordpress.android.models.bloggingprompts.BloggingPrompt sealed class BloggingPromptsOnboardingAction { data class OpenEditor(val bloggingPrompt: BloggingPrompt) : BloggingPromptsOnboardingAction() + + object OpenSitePicker : BloggingPromptsOnboardingAction() + + object OpenRemindersIntro : BloggingPromptsOnboardingAction() } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt index 838c5125e59b..8fa93df1e244 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt @@ -2,14 +2,14 @@ package org.wordpress.android.ui.bloggingprompts.onboarding import android.content.Context import android.os.Bundle -import android.view.LayoutInflater import android.view.View -import android.view.ViewGroup import androidx.lifecycle.ViewModelProvider -import com.google.android.material.button.MaterialButton +import org.wordpress.android.R import org.wordpress.android.WordPress import org.wordpress.android.ui.ActivityLauncher import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenEditor +import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenRemindersIntro +import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenSitePicker import org.wordpress.android.ui.featureintroduction.FeatureIntroductionDialogFragment import org.wordpress.android.util.extensions.exhaustive import javax.inject.Inject @@ -25,16 +25,13 @@ class BloggingPromptsOnboardingDialogFragment : FeatureIntroductionDialogFragmen fun newInstance(): BloggingPromptsOnboardingDialogFragment = BloggingPromptsOnboardingDialogFragment() } - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View = BloggingPromptsOnboardingDialogFragmentBinding.inflate(inflater).root - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - val binding = BloggingPromptsOnboardingDialogFragmentBinding.bind(view) - setupTryNow(binding.tryNow) + setupTryNowButton() + setupRemindMeButton() + setupHeaderTitle() + setupHeaderIcon() + setupContent() setupActionObserver() viewModel.start() } @@ -44,20 +41,39 @@ class BloggingPromptsOnboardingDialogFragment : FeatureIntroductionDialogFragmen (requireActivity().applicationContext as WordPress).component().inject(this) } - override fun onPrimaryButtonClick() = viewModel.onTryNow() + private fun setupTryNowButton() { + setPrimaryButtonListener { viewModel.onTryNowClick() } + setPrimaryButtonText(R.string.blogging_prompts_onboarding_try_it_now) + + } + + private fun setupRemindMeButton() { + setPrimaryButtonListener { viewModel.onRemindMeClick() } + setPrimaryButtonText(R.string.blogging_prompts_onboarding_remind_me) + } - override fun onSecondaryButtonClick() { + private fun setupHeaderTitle() { + setHeaderTitle(R.string.blogging_prompts_onboarding_header_title) + } + private fun setupHeaderIcon() { + setHeaderIcon(R.drawable.ic_story_icon_24dp) } - private fun setupTryNow(tryNow: MaterialButton) { - tryNow.setOnClickListener { viewModel.onTryNow() } + private fun setupContent() { + setContent { + + } } private fun setupActionObserver() { viewModel.action.observe(this, { action -> when (action) { is OpenEditor -> ActivityLauncher.openEditorInNewStack(activity) + is OpenSitePicker -> { /*TODO*/ + } + is OpenRemindersIntro -> { /*TODO*/ + } }.exhaustive }) } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModel.kt index 5e306c83631f..dee5622ab1fd 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModel.kt @@ -6,13 +6,17 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import kotlinx.coroutines.flow.single import kotlinx.coroutines.launch +import org.wordpress.android.fluxc.store.SiteStore import org.wordpress.android.models.bloggingprompts.BloggingPrompt import org.wordpress.android.models.usecases.GetBloggingPromptUseCase import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenEditor +import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenRemindersIntro +import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenSitePicker import javax.inject.Inject class BloggingPromptsOnboardingViewModel @Inject constructor( - private val getBloggingPromptUseCase: GetBloggingPromptUseCase + private val getBloggingPromptUseCase: GetBloggingPromptUseCase, + private val siteStore: SiteStore ) : ViewModel() { private lateinit var bloggingPrompt: BloggingPrompt @@ -28,7 +32,15 @@ class BloggingPromptsOnboardingViewModel @Inject constructor( } } - fun onTryNow() { + fun onTryNowClick() { _action.value = OpenEditor(bloggingPrompt) } + + fun onRemindMeClick() { + if (siteStore.sitesCount > 1) { + _action.value = OpenSitePicker + } else { + _action.value = OpenRemindersIntro + } + } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt index d14a46a258d3..886e912a8dd1 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt @@ -1,22 +1,22 @@ package org.wordpress.android.ui.featureintroduction import android.app.Dialog -import android.graphics.drawable.Drawable import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.annotation.DrawableRes +import androidx.annotation.StringRes +import androidx.compose.runtime.Composable +import androidx.core.content.res.ResourcesCompat import androidx.fragment.app.DialogFragment -import com.google.android.material.button.MaterialButton import org.wordpress.android.R import org.wordpress.android.databinding.FeatureIntroductionDialogFragmentBinding import org.wordpress.android.util.extensions.setStatusBarAsSurfaceColor abstract class FeatureIntroductionDialogFragment : DialogFragment() { - abstract fun onPrimaryButtonClick() - abstract fun onSecondaryButtonClick() - abstract val headerTitle: String - abstract val headerIcon: Drawable + + private lateinit var binding: FeatureIntroductionDialogFragmentBinding override fun getTheme(): Int { return R.style.FeatureIntroductionDialogFragment @@ -36,18 +36,34 @@ abstract class FeatureIntroductionDialogFragment : DialogFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - val binding = FeatureIntroductionDialogFragmentBinding.bind(view) - setupPrimaryButton(binding.primaryButton) - setupSecondaryButton(binding.secondaryButton) - setupHeaderTitle(binding.headerTitle) - setupHeaderIcon(binding.headerIcon) + binding = FeatureIntroductionDialogFragmentBinding.bind(view) + } + + fun setPrimaryButtonListener(listener: () -> Unit) { + binding.primaryButton.setOnClickListener { listener() } + } + + fun setPrimaryButtonText(@StringRes textRes: Int) { + binding.primaryButton.text = getString(textRes) + } + + fun setSecondaryButtonListener(listener: () -> Unit) { + binding.secondaryButton.setOnClickListener { listener() } + } + + fun setSecondaryButtonText(@StringRes textRes: Int) { + binding.secondaryButton.text = getString(textRes) + } + + fun setHeaderTitle(@StringRes headerTitleRes: Int) { + binding.headerTitle.text = getString(headerTitleRes) } - private fun setupPrimaryButton(primaryButton: MaterialButton) { - primaryButton.setOnClickListener { onPrimaryButtonClick() } + fun setHeaderIcon(@DrawableRes headerIconRes: Int) { + binding.headerIcon.setImageDrawable(ResourcesCompat.getDrawable(resources, headerIconRes, context?.theme)) } - private fun setupSecondaryButton(secondaryButton: MaterialButton) { - secondaryButton.setOnClickListener { onSecondaryButtonClick() } + fun setContent(content: @Composable () -> Unit) { + binding.content.setContent(content) } } diff --git a/WordPress/src/main/res/layout/feature_introduction_dialog_fragment.xml b/WordPress/src/main/res/layout/feature_introduction_dialog_fragment.xml index d909cc295541..bc60300d8723 100644 --- a/WordPress/src/main/res/layout/feature_introduction_dialog_fragment.xml +++ b/WordPress/src/main/res/layout/feature_introduction_dialog_fragment.xml @@ -9,8 +9,8 @@ android:layout_width="match_parent" android:layout_height="0dp" android:fillViewport="true" - android:paddingEnd="@dimen/dialog_fragment_content_margin" - android:paddingStart="@dimen/dialog_fragment_content_margin" + android:paddingEnd="@dimen/margin_extra_large" + android:paddingStart="@dimen/margin_extra_large" app:layout_behavior="@string/appbar_scrolling_view_behavior" app:layout_constraintBottom_toTopOf="@+id/blogging_prompts_onboading_button_container" app:layout_constraintTop_toTopOf="parent"> @@ -23,6 +23,8 @@ android:id="@+id/header_container" android:layout_width="0dp" android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/margin_extra_large" + android:layout_marginTop="@dimen/margin_extra_large" app:layout_constraintBottom_toTopOf="@+id/content_container" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -32,7 +34,7 @@ android:id="@+id/header_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginEnd="@dimen/margin_medium" + android:layout_marginBottom="@dimen/margin_medium" android:alpha="@dimen/material_emphasis_medium" android:contentDescription="@null" app:layout_constraintEnd_toEndOf="parent" @@ -40,6 +42,17 @@ app:layout_constraintTop_toTopOf="parent" tools:src="@drawable/ic_add_outline_grey_dark_24dp" /> + + + android:layout_height="0dp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> diff --git a/WordPress/src/main/res/values/strings.xml b/WordPress/src/main/res/values/strings.xml index f2a0ac6c85d4..0c815cc16390 100644 --- a/WordPress/src/main/res/values/strings.xml +++ b/WordPress/src/main/res/values/strings.xml @@ -3960,6 +3960,7 @@ translators: %s: Select control option value e.g: "Auto, 25%". --> App icon + Introducing Prompts Try it now Remind me diff --git a/WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModelTest.kt index d8bbaae02380..67050400041e 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModelTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModelTest.kt @@ -34,7 +34,7 @@ class BloggingPromptsOnboardingViewModelTest : BaseUnitTest() { val bloggingPrompt: BloggingPrompt = mock() whenever(getBloggingPromptUseCase.execute()).thenReturn(flow { emit(bloggingPrompt) }) bloggingPromptsOnboardingViewModel.start() - bloggingPromptsOnboardingViewModel.onTryNow() + bloggingPromptsOnboardingViewModel.onTryNowClick() verify(actionObserver).onChanged(OpenEditor(bloggingPrompt)) } } From 9ae1e7da2d4aff89f5e4cbbbc2b9d667d5c488d1 Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Tue, 29 Mar 2022 03:17:10 -0300 Subject: [PATCH 04/29] Add compose material dependency --- WordPress/build.gradle | 1 + .../BloggingPromptsOnboardingUiStateMapper.kt | 16 ++ .../card/BloggingPromptsOnboardingCardView.kt | 39 +++++ .../util/extensions/UiStringExtensions.kt | 14 ++ .../layout/my_site_blogging_prompt_card.xml | 142 ++++++++++++++++++ 5 files changed, 212 insertions(+) create mode 100644 WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapper.kt create mode 100644 WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/card/BloggingPromptsOnboardingCardView.kt create mode 100644 WordPress/src/main/java/org/wordpress/android/util/extensions/UiStringExtensions.kt create mode 100644 WordPress/src/main/res/layout/my_site_blogging_prompt_card.xml diff --git a/WordPress/build.gradle b/WordPress/build.gradle index 722a9d715d74..d9a9302319b4 100644 --- a/WordPress/build.gradle +++ b/WordPress/build.gradle @@ -390,6 +390,7 @@ dependencies { // Compose implementation "androidx.compose.ui:ui:$composeVersion" implementation "androidx.compose.foundation:foundation:$composeVersion" + implementation "androidx.compose.material:material:$composeVersion" testImplementation "junit:junit:$jUnitVersion" diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapper.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapper.kt new file mode 100644 index 000000000000..1c57054c90b5 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapper.kt @@ -0,0 +1,16 @@ +package org.wordpress.android.ui.bloggingprompts.onboarding + +import org.wordpress.android.R +import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingUiState.Ready +import org.wordpress.android.ui.utils.UiString.UiStringRes +import javax.inject.Inject + +class BloggingPromptsOnboardingUiStateMapper @Inject constructor() { + + fun mapReady(): Ready = Ready( + prompt = UiStringRes(R.string.blogging_prompts_onboarding_card_prompt), + answeredUsers = emptyList(), + numberOfAnswers = 19, + isAnswered = false + ) +} diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/card/BloggingPromptsOnboardingCardView.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/card/BloggingPromptsOnboardingCardView.kt new file mode 100644 index 000000000000..eba2bac30e79 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/card/BloggingPromptsOnboardingCardView.kt @@ -0,0 +1,39 @@ +package org.wordpress.android.ui.bloggingprompts.onboarding.card + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.view.View +import org.wordpress.android.R +import org.wordpress.android.databinding.MySiteBloggingPromptCardBinding +import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.DashboardCards.DashboardCard.BloggingPromptCard.BloggingPromptCardWithData +import org.wordpress.android.ui.utils.UiString +import org.wordpress.android.util.extensions.getText +import org.wordpress.android.util.extensions.orEmpty + +class BloggingPromptsOnboardingCardView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : View(context, attrs, defStyleAttr) { + + private var binding: MySiteBloggingPromptCardBinding = MySiteBloggingPromptCardBinding.inflate( + LayoutInflater.from(context) + ) + + fun bind(card: BloggingPromptCardWithData) { + setupPromptContent(card.prompt) + setupNumberOfAnswers(card.numberOfAnswers) + } + + private fun setupPromptContent(prompt: UiString) { + binding.promptContent.text = prompt.getText(context).orEmpty() + } + + private fun setupNumberOfAnswers(numberOfAnswers: Int) { + val numberOfAnswersLabel = context.getString( + R.string.my_site_blogging_prompt_card_number_of_answers, numberOfAnswers + ) + binding.numberOfAnswers.text = numberOfAnswersLabel + } +} diff --git a/WordPress/src/main/java/org/wordpress/android/util/extensions/UiStringExtensions.kt b/WordPress/src/main/java/org/wordpress/android/util/extensions/UiStringExtensions.kt new file mode 100644 index 000000000000..2b526511ebf5 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/util/extensions/UiStringExtensions.kt @@ -0,0 +1,14 @@ +package org.wordpress.android.util.extensions + +import android.content.Context +import org.wordpress.android.ui.utils.UiString +import org.wordpress.android.ui.utils.UiString.UiStringRes +import org.wordpress.android.ui.utils.UiString.UiStringResWithParams +import org.wordpress.android.ui.utils.UiString.UiStringText + +fun UiString.getText(context: Context): String = when (this) { + is UiStringText -> text.toString().orEmpty() + is UiStringRes -> context.getString(stringRes).orEmpty() + is UiStringResWithParams -> context.getString(stringRes, params.map { it.getText(context) }.toTypedArray()) + .orEmpty() +} diff --git a/WordPress/src/main/res/layout/my_site_blogging_prompt_card.xml b/WordPress/src/main/res/layout/my_site_blogging_prompt_card.xml new file mode 100644 index 000000000000..10dc71cba8ee --- /dev/null +++ b/WordPress/src/main/res/layout/my_site_blogging_prompt_card.xml @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From d3399bd721316b53d10085f2806998ce777ab7ff Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Tue, 29 Mar 2022 03:18:12 -0300 Subject: [PATCH 05/29] Suppress Kotlin version check when using Compose --- WordPress/build.gradle | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/WordPress/build.gradle b/WordPress/build.gradle index d9a9302319b4..19f887ecc287 100644 --- a/WordPress/build.gradle +++ b/WordPress/build.gradle @@ -612,6 +612,17 @@ tasks.register("printAllVersions") { } } } +// TODO remove after merging PR that bumps Kotlin version +tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { + kotlinOptions { + jvmTarget = "1.8" + freeCompilerArgs += [ + "-Xallow-jvm-ir-dependencies", + "-P", + "plugin:androidx.compose.compiler.plugins.kotlin:suppressKotlinVersionCompatibilityCheck=true" + ] + } +} def checkGradlePropertiesFile() { def inputFile = file("${rootDir}/gradle.properties") From 8f6da04598c3fb7eb1ae64c3c63e0baebd24ff6b Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Tue, 29 Mar 2022 03:18:48 -0300 Subject: [PATCH 06/29] Remove unused GetBloggingPromptUseCase --- .../usecases/GetBloggingPromptUseCase.kt | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 WordPress/src/main/java/org/wordpress/android/models/usecases/GetBloggingPromptUseCase.kt diff --git a/WordPress/src/main/java/org/wordpress/android/models/usecases/GetBloggingPromptUseCase.kt b/WordPress/src/main/java/org/wordpress/android/models/usecases/GetBloggingPromptUseCase.kt deleted file mode 100644 index cc894bedb246..000000000000 --- a/WordPress/src/main/java/org/wordpress/android/models/usecases/GetBloggingPromptUseCase.kt +++ /dev/null @@ -1,19 +0,0 @@ -package org.wordpress.android.models.usecases - -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flow -import org.wordpress.android.models.bloggingprompts.BloggingPrompt -import javax.inject.Inject - -class GetBloggingPromptUseCase @Inject constructor() { - // TODO fetch from Store when implementation is ready - fun execute(): Flow = flow { - emit( - BloggingPrompt( - text = "This is a blogging prompt!", - numberOfAnswers = 7, - template = "" - ) - ) - } -} From 1c579649875f836e4c50b4b8848e674df4d21931 Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Tue, 29 Mar 2022 03:23:03 -0300 Subject: [PATCH 07/29] Update BloggingPromptsOnboarding with Ready state --- ...BloggingPromptsOnboardingDialogFragment.kt | 72 +++++++++++++++++-- .../BloggingPromptsOnboardingUiState.kt | 12 +++- .../BloggingPromptsOnboardingViewModel.kt | 12 +--- 3 files changed, 80 insertions(+), 16 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt index 8fa93df1e244..f0ba2417b909 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt @@ -3,6 +3,20 @@ package org.wordpress.android.ui.bloggingprompts.onboarding import android.content.Context import android.os.Bundle import android.view.View +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.material.Text +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.colorResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.compose.ui.viewinterop.AndroidView import androidx.lifecycle.ViewModelProvider import org.wordpress.android.R import org.wordpress.android.WordPress @@ -10,7 +24,10 @@ import org.wordpress.android.ui.ActivityLauncher import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenEditor import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenRemindersIntro import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenSitePicker +import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingUiState.Ready +import org.wordpress.android.ui.bloggingprompts.onboarding.card.BloggingPromptsOnboardingCardView import org.wordpress.android.ui.featureintroduction.FeatureIntroductionDialogFragment +import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.DashboardCards.DashboardCard.BloggingPromptCard.BloggingPromptCardWithData import org.wordpress.android.util.extensions.exhaustive import javax.inject.Inject @@ -27,11 +44,12 @@ class BloggingPromptsOnboardingDialogFragment : FeatureIntroductionDialogFragmen override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + viewModel = ViewModelProvider(this, viewModelFactory).get(BloggingPromptsOnboardingViewModel::class.java) setupTryNowButton() setupRemindMeButton() setupHeaderTitle() setupHeaderIcon() - setupContent() + setupUiStateObserver() setupActionObserver() viewModel.start() } @@ -44,7 +62,6 @@ class BloggingPromptsOnboardingDialogFragment : FeatureIntroductionDialogFragmen private fun setupTryNowButton() { setPrimaryButtonListener { viewModel.onTryNowClick() } setPrimaryButtonText(R.string.blogging_prompts_onboarding_try_it_now) - } private fun setupRemindMeButton() { @@ -60,14 +77,57 @@ class BloggingPromptsOnboardingDialogFragment : FeatureIntroductionDialogFragmen setHeaderIcon(R.drawable.ic_story_icon_24dp) } - private fun setupContent() { + private fun setupContent(readyState: Ready) { setContent { - + Column(modifier = Modifier + .fillMaxWidth() + .wrapContentHeight()) { + Text( + text = stringResource(R.string.blogging_prompts_onboarding_body_top), + fontFamily = FontFamily.Serif, + fontSize = 16.sp, + color = colorResource(R.color.black) + ) + AndroidView( + modifier = Modifier + .height(200.dp) + .fillMaxWidth() + .background(Color.Blue), + factory = { context -> + val cardView = BloggingPromptsOnboardingCardView(context) + cardView.bind( + BloggingPromptCardWithData( + prompt = readyState.prompt, + answeredUsers = readyState.answeredUsers, + numberOfAnswers = readyState.numberOfAnswers, + isAnswered = readyState.isAnswered + ) + ) + cardView + } + ) + Text( + text = getString(R.string.blogging_prompts_onboarding_body_bottom), + fontFamily = FontFamily.Serif, + fontSize = 16.sp, + color = colorResource(R.color.black) + ) + } + } + } + + private fun setupUiStateObserver() { + viewModel.uiState.observe(this) { uiState -> + when (uiState) { + is Ready -> { + setupContent(uiState) + } + }.exhaustive } } private fun setupActionObserver() { - viewModel.action.observe(this, { action -> + viewModel.action.observe(this) { action -> when (action) { is OpenEditor -> ActivityLauncher.openEditorInNewStack(activity) is OpenSitePicker -> { /*TODO*/ @@ -75,6 +135,6 @@ class BloggingPromptsOnboardingDialogFragment : FeatureIntroductionDialogFragmen is OpenRemindersIntro -> { /*TODO*/ } }.exhaustive - }) + } } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiState.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiState.kt index ac86c23e9b81..e6e587cb6c6c 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiState.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiState.kt @@ -1,3 +1,13 @@ package org.wordpress.android.ui.bloggingprompts.onboarding -sealed class BloggingPromptsOnboardingUiState +import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.DashboardCards.DashboardCard.BloggingPromptCard.BloggingPromptCardWithData.AnsweredUser +import org.wordpress.android.ui.utils.UiString + +sealed class BloggingPromptsOnboardingUiState { + data class Ready( + val prompt: UiString, + val answeredUsers: List, + val numberOfAnswers: Int, + val isAnswered: Boolean + ) : BloggingPromptsOnboardingUiState() +} diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModel.kt index dee5622ab1fd..817c5912dcf3 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModel.kt @@ -3,20 +3,16 @@ package org.wordpress.android.ui.bloggingprompts.onboarding import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import kotlinx.coroutines.flow.single -import kotlinx.coroutines.launch import org.wordpress.android.fluxc.store.SiteStore import org.wordpress.android.models.bloggingprompts.BloggingPrompt -import org.wordpress.android.models.usecases.GetBloggingPromptUseCase import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenEditor import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenRemindersIntro import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenSitePicker import javax.inject.Inject class BloggingPromptsOnboardingViewModel @Inject constructor( - private val getBloggingPromptUseCase: GetBloggingPromptUseCase, - private val siteStore: SiteStore + private val siteStore: SiteStore, + private val uiStateMapper: BloggingPromptsOnboardingUiStateMapper ) : ViewModel() { private lateinit var bloggingPrompt: BloggingPrompt @@ -27,9 +23,7 @@ class BloggingPromptsOnboardingViewModel @Inject constructor( val action: LiveData = _action fun start() { - viewModelScope.launch { - bloggingPrompt = getBloggingPromptUseCase.execute().single() - } + _uiState.value = uiStateMapper.mapReady() } fun onTryNowClick() { From d5b9739a3b50da14c74da8b41775782732a89488 Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Tue, 29 Mar 2022 03:23:30 -0300 Subject: [PATCH 08/29] Update View and String extensions --- .../wordpress/android/util/extensions/StringExtensions.kt | 6 ++++++ .../org/wordpress/android/util/extensions/ViewExtensions.kt | 3 +++ 2 files changed, 9 insertions(+) diff --git a/WordPress/src/main/java/org/wordpress/android/util/extensions/StringExtensions.kt b/WordPress/src/main/java/org/wordpress/android/util/extensions/StringExtensions.kt index e231f0897c41..0694db3602f7 100644 --- a/WordPress/src/main/java/org/wordpress/android/util/extensions/StringExtensions.kt +++ b/WordPress/src/main/java/org/wordpress/android/util/extensions/StringExtensions.kt @@ -1,6 +1,10 @@ package org.wordpress.android.util.extensions import android.annotation.SuppressLint +import android.content.res.Resources +import org.wordpress.android.ui.utils.UiString +import org.wordpress.android.ui.utils.UiString.UiStringRes +import org.wordpress.android.ui.utils.UiString.UiStringText import java.util.Locale /** @@ -18,3 +22,5 @@ import java.util.Locale fun String.capitalizeWithLocaleWithoutLint(locale: Locale): String { return this.capitalize(locale) } + +fun String?.orEmpty(): String = this?.run { this } ?: "" diff --git a/WordPress/src/main/java/org/wordpress/android/util/extensions/ViewExtensions.kt b/WordPress/src/main/java/org/wordpress/android/util/extensions/ViewExtensions.kt index 2f4b8d64b1bc..108ba0dcbed1 100644 --- a/WordPress/src/main/java/org/wordpress/android/util/extensions/ViewExtensions.kt +++ b/WordPress/src/main/java/org/wordpress/android/util/extensions/ViewExtensions.kt @@ -7,6 +7,7 @@ import android.view.View import android.view.ViewTreeObserver import android.view.inputmethod.InputMethodManager import androidx.annotation.DimenRes +import androidx.annotation.StringRes import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.SimpleItemAnimator @@ -80,3 +81,5 @@ fun View.focusAndShowKeyboard() { fun RecyclerView.disableAnimation() { (itemAnimator as? SimpleItemAnimator)?.supportsChangeAnimations = false } + +fun View.getString(@StringRes stringRes: Int) = context.getString(stringRes) From dd836f20137ecf83652de16cd88d575674c426f0 Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Tue, 29 Mar 2022 03:23:53 -0300 Subject: [PATCH 09/29] Fix feature introduction dialog header text size --- .../src/main/res/layout/feature_introduction_dialog_fragment.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/WordPress/src/main/res/layout/feature_introduction_dialog_fragment.xml b/WordPress/src/main/res/layout/feature_introduction_dialog_fragment.xml index bc60300d8723..b2e0379f42fb 100644 --- a/WordPress/src/main/res/layout/feature_introduction_dialog_fragment.xml +++ b/WordPress/src/main/res/layout/feature_introduction_dialog_fragment.xml @@ -47,6 +47,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:gravity="center" + android:textSize="@dimen/text_sz_double_extra_large" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" From 0754042d9b82d4a5cd66ec8891596279bf183345 Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Tue, 29 Mar 2022 03:24:33 -0300 Subject: [PATCH 10/29] Add blogging prompts feature introduction top, bottom and sample prompt strings --- WordPress/src/main/res/values/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/WordPress/src/main/res/values/strings.xml b/WordPress/src/main/res/values/strings.xml index 6b91a427da07..1e86ab57c021 100644 --- a/WordPress/src/main/res/values/strings.xml +++ b/WordPress/src/main/res/values/strings.xml @@ -3991,6 +3991,9 @@ translators: %s: Select control option value e.g: "Auto, 25%". --> Introducing Prompts + The best way to become a better writer is to build a writing habit and share with others — that’s where Prompts come in! + We’ll show you a new prompt each day on your dashboard to help get those creative juices flowing! Try it now Remind me + Cast the movie of your life. From 5de5988701ae2b10c006a6d78ce0d5d0b13f3632 Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Tue, 29 Mar 2022 03:24:57 -0300 Subject: [PATCH 11/29] Update BloggingPromptsOnboardingViewModel tests --- .../BloggingPromptsOnboardingViewModelTest.kt | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModelTest.kt index 67050400041e..4e0b264ca6e4 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModelTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModelTest.kt @@ -3,19 +3,18 @@ package org.wordpress.android.ui.bloggingprompts.onboarding import androidx.lifecycle.Observer import com.nhaarman.mockitokotlin2.mock import com.nhaarman.mockitokotlin2.verify -import com.nhaarman.mockitokotlin2.whenever -import kotlinx.coroutines.flow.flow import org.junit.Before import org.junit.Test import org.wordpress.android.BaseUnitTest +import org.wordpress.android.fluxc.store.SiteStore import org.wordpress.android.models.bloggingprompts.BloggingPrompt -import org.wordpress.android.models.usecases.GetBloggingPromptUseCase import org.wordpress.android.test import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenEditor class BloggingPromptsOnboardingViewModelTest : BaseUnitTest() { - private val getBloggingPromptUseCase: GetBloggingPromptUseCase = mock() - private val bloggingPromptsOnboardingViewModel = BloggingPromptsOnboardingViewModel(getBloggingPromptUseCase) + private val uiStateMapper: BloggingPromptsOnboardingUiStateMapper = mock() + private val siteStore: SiteStore = mock() + private val bloggingPromptsOnboardingViewModel = BloggingPromptsOnboardingViewModel(siteStore, uiStateMapper) private val actionObserver: Observer = mock() @Before @@ -26,13 +25,12 @@ class BloggingPromptsOnboardingViewModelTest : BaseUnitTest() { @Test fun `Should execute GetBloggingPromptUseCase when start is called`() = test { bloggingPromptsOnboardingViewModel.start() - verify(getBloggingPromptUseCase).execute() + verify(uiStateMapper).mapReady() } @Test fun `Should trigger OpenEditor action when onTryNow is called`() = test { val bloggingPrompt: BloggingPrompt = mock() - whenever(getBloggingPromptUseCase.execute()).thenReturn(flow { emit(bloggingPrompt) }) bloggingPromptsOnboardingViewModel.start() bloggingPromptsOnboardingViewModel.onTryNowClick() verify(actionObserver).onChanged(OpenEditor(bloggingPrompt)) From f4533a78f0b59a243f3d23d680941be5b7050a50 Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Tue, 29 Mar 2022 03:25:12 -0300 Subject: [PATCH 12/29] Update compose version based on Kotlin version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 4066db7814e8..163fa1e9a613 100644 --- a/build.gradle +++ b/build.gradle @@ -31,7 +31,7 @@ ext { exoPlayerVersion = '2.9.3' - composeVersion = '1.1.1' + composeVersion = '1.0.5' // testing jUnitVersion = '4.13' From b8ee2be6ec925737ca65fe6509370c73c5bb629a Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Tue, 29 Mar 2022 14:00:07 -0300 Subject: [PATCH 13/29] Fix Remind Me button setup in BloggingPromptsOnboardingDialog --- .../onboarding/BloggingPromptsOnboardingDialogFragment.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt index f0ba2417b909..1b8ec4a7ca34 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt @@ -65,8 +65,8 @@ class BloggingPromptsOnboardingDialogFragment : FeatureIntroductionDialogFragmen } private fun setupRemindMeButton() { - setPrimaryButtonListener { viewModel.onRemindMeClick() } - setPrimaryButtonText(R.string.blogging_prompts_onboarding_remind_me) + setSecondaryButtonListener { viewModel.onRemindMeClick() } + setSecondaryButtonText(R.string.blogging_prompts_onboarding_remind_me) } private fun setupHeaderTitle() { From eacdf41a8056a1a6104394587afb5c97e2c3ac01 Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Tue, 29 Mar 2022 14:00:37 -0300 Subject: [PATCH 14/29] Set binding field to null onDestroyView in FeatureIntroductionDialogFragment --- .../FeatureIntroductionDialogFragment.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt index 886e912a8dd1..2853ca712dfb 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt @@ -16,7 +16,8 @@ import org.wordpress.android.util.extensions.setStatusBarAsSurfaceColor abstract class FeatureIntroductionDialogFragment : DialogFragment() { - private lateinit var binding: FeatureIntroductionDialogFragmentBinding + private var _binding: FeatureIntroductionDialogFragmentBinding? = null + private val binding get() = _binding ?: throw NullPointerException("_binding cannot be null") override fun getTheme(): Int { return R.style.FeatureIntroductionDialogFragment @@ -36,7 +37,12 @@ abstract class FeatureIntroductionDialogFragment : DialogFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - binding = FeatureIntroductionDialogFragmentBinding.bind(view) + _binding = FeatureIntroductionDialogFragmentBinding.bind(view) + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null } fun setPrimaryButtonListener(listener: () -> Unit) { From c9cf9b49a03fc4030a95bda64a9ad4b71a9fda0f Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Tue, 29 Mar 2022 19:29:42 -0300 Subject: [PATCH 15/29] Add blogging prompts introduction content padding --- .../BloggingPromptsOnboardingDialogFragment.kt | 7 +++++-- .../src/main/res/color/lightbulb_orange_background.xml | 6 ++++++ .../ic_outline_lightbulb_orange_gradient_40dp.xml | 9 +++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 WordPress/src/main/res/color/lightbulb_orange_background.xml create mode 100644 WordPress/src/main/res/drawable/ic_outline_lightbulb_orange_gradient_40dp.xml diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt index 1b8ec4a7ca34..6d6be1036ca0 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt @@ -7,6 +7,7 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.material.Text import androidx.compose.ui.Modifier @@ -74,7 +75,7 @@ class BloggingPromptsOnboardingDialogFragment : FeatureIntroductionDialogFragmen } private fun setupHeaderIcon() { - setHeaderIcon(R.drawable.ic_story_icon_24dp) + setHeaderIcon(R.drawable.ic_outline_lightbulb_orange_gradient_40dp) } private fun setupContent(readyState: Ready) { @@ -83,10 +84,11 @@ class BloggingPromptsOnboardingDialogFragment : FeatureIntroductionDialogFragmen .fillMaxWidth() .wrapContentHeight()) { Text( + modifier = Modifier.padding(bottom = 24.dp), text = stringResource(R.string.blogging_prompts_onboarding_body_top), fontFamily = FontFamily.Serif, fontSize = 16.sp, - color = colorResource(R.color.black) + color = colorResource(R.color.black), ) AndroidView( modifier = Modifier @@ -107,6 +109,7 @@ class BloggingPromptsOnboardingDialogFragment : FeatureIntroductionDialogFragmen } ) Text( + modifier = Modifier.padding(top = 24.dp), text = getString(R.string.blogging_prompts_onboarding_body_bottom), fontFamily = FontFamily.Serif, fontSize = 16.sp, diff --git a/WordPress/src/main/res/color/lightbulb_orange_background.xml b/WordPress/src/main/res/color/lightbulb_orange_background.xml new file mode 100644 index 000000000000..199d7cd18d60 --- /dev/null +++ b/WordPress/src/main/res/color/lightbulb_orange_background.xml @@ -0,0 +1,6 @@ + + diff --git a/WordPress/src/main/res/drawable/ic_outline_lightbulb_orange_gradient_40dp.xml b/WordPress/src/main/res/drawable/ic_outline_lightbulb_orange_gradient_40dp.xml new file mode 100644 index 000000000000..0b2d8f44668d --- /dev/null +++ b/WordPress/src/main/res/drawable/ic_outline_lightbulb_orange_gradient_40dp.xml @@ -0,0 +1,9 @@ + + + From 3b3966f89116006c1a2dbede29d73683165afa24 Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Tue, 29 Mar 2022 19:30:02 -0300 Subject: [PATCH 16/29] Add close button to feature introduction --- .../FeatureIntroductionDialogFragment.kt | 5 +++ .../feature_introduction_dialog_fragment.xml | 34 +++++++++++++++---- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt index 2853ca712dfb..79132d1866cd 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt @@ -38,6 +38,7 @@ abstract class FeatureIntroductionDialogFragment : DialogFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) _binding = FeatureIntroductionDialogFragmentBinding.bind(view) + setupCloseButton() } override fun onDestroyView() { @@ -72,4 +73,8 @@ abstract class FeatureIntroductionDialogFragment : DialogFragment() { fun setContent(content: @Composable () -> Unit) { binding.content.setContent(content) } + + private fun setupCloseButton() { + binding.closeButton.setOnClickListener { dismiss() } + } } diff --git a/WordPress/src/main/res/layout/feature_introduction_dialog_fragment.xml b/WordPress/src/main/res/layout/feature_introduction_dialog_fragment.xml index b2e0379f42fb..8f4b23dcff84 100644 --- a/WordPress/src/main/res/layout/feature_introduction_dialog_fragment.xml +++ b/WordPress/src/main/res/layout/feature_introduction_dialog_fragment.xml @@ -20,7 +20,31 @@ android:layout_height="match_parent"> + + + + + + + app:layout_constraintTop_toBottomOf="@+id/toolbar_container"> + app:layout_constraintTop_toBottomOf="@+id/top_bar_container"> From 2db6425c90f9887bb4db326c3d16d5ba81291394 Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Tue, 29 Mar 2022 20:15:25 -0300 Subject: [PATCH 17/29] Fix Compose Text style in BloggingPromptsOnboardingDialogFragment --- ...BloggingPromptsOnboardingDialogFragment.kt | 15 +- .../card/BloggingPromptsOnboardingCardView.kt | 4 +- .../layout/my_site_blogging_prompt_card.xml | 142 ------------------ 3 files changed, 11 insertions(+), 150 deletions(-) delete mode 100644 WordPress/src/main/res/layout/my_site_blogging_prompt_card.xml diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt index 6d6be1036ca0..76dcbaf992f8 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt @@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -16,10 +17,10 @@ import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.compose.ui.viewinterop.AndroidView import androidx.lifecycle.ViewModelProvider import org.wordpress.android.R +import org.wordpress.android.R.attr import org.wordpress.android.WordPress import org.wordpress.android.ui.ActivityLauncher import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenEditor @@ -87,8 +88,8 @@ class BloggingPromptsOnboardingDialogFragment : FeatureIntroductionDialogFragmen modifier = Modifier.padding(bottom = 24.dp), text = stringResource(R.string.blogging_prompts_onboarding_body_top), fontFamily = FontFamily.Serif, - fontSize = 16.sp, - color = colorResource(R.color.black), + style = MaterialTheme.typography.subtitle1, + color = colorResource(id = attr.wpColorOnSurfaceMedium) ) AndroidView( modifier = Modifier @@ -102,7 +103,10 @@ class BloggingPromptsOnboardingDialogFragment : FeatureIntroductionDialogFragmen prompt = readyState.prompt, answeredUsers = readyState.answeredUsers, numberOfAnswers = readyState.numberOfAnswers, - isAnswered = readyState.isAnswered + isAnswered = readyState.isAnswered, + onShareClick = { + // no op + } ) ) cardView @@ -112,8 +116,7 @@ class BloggingPromptsOnboardingDialogFragment : FeatureIntroductionDialogFragmen modifier = Modifier.padding(top = 24.dp), text = getString(R.string.blogging_prompts_onboarding_body_bottom), fontFamily = FontFamily.Serif, - fontSize = 16.sp, - color = colorResource(R.color.black) + style = MaterialTheme.typography.subtitle1 ) } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/card/BloggingPromptsOnboardingCardView.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/card/BloggingPromptsOnboardingCardView.kt index eba2bac30e79..0d481336a8c9 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/card/BloggingPromptsOnboardingCardView.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/card/BloggingPromptsOnboardingCardView.kt @@ -5,7 +5,7 @@ import android.util.AttributeSet import android.view.LayoutInflater import android.view.View import org.wordpress.android.R -import org.wordpress.android.databinding.MySiteBloggingPromptCardBinding +import org.wordpress.android.databinding.MySiteBloggingPrompCardBinding import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.DashboardCards.DashboardCard.BloggingPromptCard.BloggingPromptCardWithData import org.wordpress.android.ui.utils.UiString import org.wordpress.android.util.extensions.getText @@ -17,7 +17,7 @@ class BloggingPromptsOnboardingCardView @JvmOverloads constructor( defStyleAttr: Int = 0 ) : View(context, attrs, defStyleAttr) { - private var binding: MySiteBloggingPromptCardBinding = MySiteBloggingPromptCardBinding.inflate( + private var binding: MySiteBloggingPrompCardBinding = MySiteBloggingPrompCardBinding.inflate( LayoutInflater.from(context) ) diff --git a/WordPress/src/main/res/layout/my_site_blogging_prompt_card.xml b/WordPress/src/main/res/layout/my_site_blogging_prompt_card.xml deleted file mode 100644 index 10dc71cba8ee..000000000000 --- a/WordPress/src/main/res/layout/my_site_blogging_prompt_card.xml +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 346f1ba2a7536b66ad9f3d4abe2b848c32a83bca Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Wed, 30 Mar 2022 23:15:03 -0300 Subject: [PATCH 18/29] Remove Compose dependencies --- WordPress/build.gradle | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/WordPress/build.gradle b/WordPress/build.gradle index ac448c305ffc..24dd46baa293 100644 --- a/WordPress/build.gradle +++ b/WordPress/build.gradle @@ -280,11 +280,6 @@ android { buildFeatures { viewBinding true - compose true - - composeOptions { - kotlinCompilerExtensionVersion = composeVersion - } } } @@ -388,11 +383,6 @@ dependencies { kapt 'com.github.bumptech.glide:compiler:4.10.0' implementation 'com.github.bumptech.glide:volley-integration:4.6.1@aar' - // Compose - implementation "androidx.compose.ui:ui:$composeVersion" - implementation "androidx.compose.foundation:foundation:$composeVersion" - implementation "androidx.compose.material:material:$composeVersion" - testImplementation "junit:junit:$jUnitVersion" testImplementation 'org.robolectric:robolectric:4.4' From 304ebc1966a451b833e69bbe59977878dd1f93b8 Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Wed, 30 Mar 2022 23:16:22 -0300 Subject: [PATCH 19/29] Update blogging prompts onboarding dialog layout without Compose --- ...BloggingPromptsOnboardingDialogFragment.kt | 72 ++++------------ .../BloggingPromptsOnboardingUiState.kt | 14 ++-- .../BloggingPromptsOnboardingUiStateMapper.kt | 15 ++-- .../card/BloggingPromptsOnboardingCardView.kt | 39 --------- .../FeatureIntroductionDialogFragment.kt | 5 +- .../res/color/lightbulb_orange_background.xml | 2 +- .../bg_rectangle_black_60_radius_2dp.xml | 8 ++ ...outline_lightbulb_orange_gradient_40dp.xml | 5 +- ...prompts_omboarding_dialog_content_view.xml | 84 +++++++++++++++++++ .../feature_introduction_dialog_fragment.xml | 12 +-- WordPress/src/main/res/values/strings.xml | 6 +- WordPress/src/main/res/values/styles.xml | 11 +++ build.gradle | 2 - 13 files changed, 149 insertions(+), 126 deletions(-) delete mode 100644 WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/card/BloggingPromptsOnboardingCardView.kt create mode 100644 WordPress/src/main/res/drawable/bg_rectangle_black_60_radius_2dp.xml create mode 100644 WordPress/src/main/res/layout/blogging_prompts_omboarding_dialog_content_view.xml diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt index 76dcbaf992f8..cdc3ca096a09 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt @@ -3,33 +3,18 @@ package org.wordpress.android.ui.bloggingprompts.onboarding import android.content.Context import android.os.Bundle import android.view.View -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.wrapContentHeight -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.colorResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.unit.dp -import androidx.compose.ui.viewinterop.AndroidView +import androidx.core.text.bold +import androidx.core.text.buildSpannedString import androidx.lifecycle.ViewModelProvider import org.wordpress.android.R -import org.wordpress.android.R.attr import org.wordpress.android.WordPress +import org.wordpress.android.databinding.BloggingPromptsOmboardingDialogContentViewBinding import org.wordpress.android.ui.ActivityLauncher import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenEditor import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenRemindersIntro import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenSitePicker import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingUiState.Ready -import org.wordpress.android.ui.bloggingprompts.onboarding.card.BloggingPromptsOnboardingCardView import org.wordpress.android.ui.featureintroduction.FeatureIntroductionDialogFragment -import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.DashboardCards.DashboardCard.BloggingPromptCard.BloggingPromptCardWithData import org.wordpress.android.util.extensions.exhaustive import javax.inject.Inject @@ -80,44 +65,19 @@ class BloggingPromptsOnboardingDialogFragment : FeatureIntroductionDialogFragmen } private fun setupContent(readyState: Ready) { - setContent { - Column(modifier = Modifier - .fillMaxWidth() - .wrapContentHeight()) { - Text( - modifier = Modifier.padding(bottom = 24.dp), - text = stringResource(R.string.blogging_prompts_onboarding_body_top), - fontFamily = FontFamily.Serif, - style = MaterialTheme.typography.subtitle1, - color = colorResource(id = attr.wpColorOnSurfaceMedium) - ) - AndroidView( - modifier = Modifier - .height(200.dp) - .fillMaxWidth() - .background(Color.Blue), - factory = { context -> - val cardView = BloggingPromptsOnboardingCardView(context) - cardView.bind( - BloggingPromptCardWithData( - prompt = readyState.prompt, - answeredUsers = readyState.answeredUsers, - numberOfAnswers = readyState.numberOfAnswers, - isAnswered = readyState.isAnswered, - onShareClick = { - // no op - } - ) - ) - cardView - } - ) - Text( - modifier = Modifier.padding(top = 24.dp), - text = getString(R.string.blogging_prompts_onboarding_body_bottom), - fontFamily = FontFamily.Serif, - style = MaterialTheme.typography.subtitle1 - ) + val contentBinding = BloggingPromptsOmboardingDialogContentViewBinding.inflate(layoutInflater) + setContent(contentBinding.root) + with(contentBinding) { + contentTop.text = getString(readyState.contentTopRes) + cardCoverView.setOnClickListener { /*do nothing*/ } + promptCard.promptContent.text = getString(readyState.promptRes) + promptCard.numberOfAnswers.text = getString(readyState.answersRes, readyState.answersCount) + contentBottom.text = getString(readyState.contentBottomRes) + contentNote.text = getString(readyState.contentNoteTitle) + + contentNote.text = buildSpannedString { + bold { append(getString(readyState.contentNoteTitle)) } + append(getString(readyState.contentNoteContent)) } } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiState.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiState.kt index e6e587cb6c6c..e8c2a0b36aa0 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiState.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiState.kt @@ -1,13 +1,15 @@ package org.wordpress.android.ui.bloggingprompts.onboarding -import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.DashboardCards.DashboardCard.BloggingPromptCard.BloggingPromptCardWithData.AnsweredUser -import org.wordpress.android.ui.utils.UiString +import androidx.annotation.StringRes sealed class BloggingPromptsOnboardingUiState { data class Ready( - val prompt: UiString, - val answeredUsers: List, - val numberOfAnswers: Int, - val isAnswered: Boolean + @StringRes val promptRes: Int, + @StringRes val answersRes: Int, + val answersCount: Int, + @StringRes val contentTopRes: Int, + @StringRes val contentBottomRes: Int, + @StringRes val contentNoteTitle: Int, + @StringRes val contentNoteContent: Int ) : BloggingPromptsOnboardingUiState() } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapper.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapper.kt index 1c57054c90b5..c15816b6fd78 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapper.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapper.kt @@ -2,15 +2,20 @@ package org.wordpress.android.ui.bloggingprompts.onboarding import org.wordpress.android.R import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingUiState.Ready -import org.wordpress.android.ui.utils.UiString.UiStringRes import javax.inject.Inject class BloggingPromptsOnboardingUiStateMapper @Inject constructor() { fun mapReady(): Ready = Ready( - prompt = UiStringRes(R.string.blogging_prompts_onboarding_card_prompt), - answeredUsers = emptyList(), - numberOfAnswers = 19, - isAnswered = false + promptRes = R.string.blogging_prompts_onboarding_card_prompt, + answersRes = R.string.my_site_blogging_prompt_card_number_of_answers, + answersCount = ANSWER_COUNT, + contentTopRes = R.string.blogging_prompts_onboarding_content_top, + contentBottomRes = R.string.blogging_prompts_onboarding_content_bottom, + contentNoteTitle = R.string.blogging_prompts_onboarding_content_note_title, + contentNoteContent = R.string.blogging_prompts_onboarding_content_note_content ) } + +private const val ANSWER_COUNT = 19 + diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/card/BloggingPromptsOnboardingCardView.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/card/BloggingPromptsOnboardingCardView.kt deleted file mode 100644 index 0d481336a8c9..000000000000 --- a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/card/BloggingPromptsOnboardingCardView.kt +++ /dev/null @@ -1,39 +0,0 @@ -package org.wordpress.android.ui.bloggingprompts.onboarding.card - -import android.content.Context -import android.util.AttributeSet -import android.view.LayoutInflater -import android.view.View -import org.wordpress.android.R -import org.wordpress.android.databinding.MySiteBloggingPrompCardBinding -import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.DashboardCards.DashboardCard.BloggingPromptCard.BloggingPromptCardWithData -import org.wordpress.android.ui.utils.UiString -import org.wordpress.android.util.extensions.getText -import org.wordpress.android.util.extensions.orEmpty - -class BloggingPromptsOnboardingCardView @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null, - defStyleAttr: Int = 0 -) : View(context, attrs, defStyleAttr) { - - private var binding: MySiteBloggingPrompCardBinding = MySiteBloggingPrompCardBinding.inflate( - LayoutInflater.from(context) - ) - - fun bind(card: BloggingPromptCardWithData) { - setupPromptContent(card.prompt) - setupNumberOfAnswers(card.numberOfAnswers) - } - - private fun setupPromptContent(prompt: UiString) { - binding.promptContent.text = prompt.getText(context).orEmpty() - } - - private fun setupNumberOfAnswers(numberOfAnswers: Int) { - val numberOfAnswersLabel = context.getString( - R.string.my_site_blogging_prompt_card_number_of_answers, numberOfAnswers - ) - binding.numberOfAnswers.text = numberOfAnswersLabel - } -} diff --git a/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt index 79132d1866cd..b4f214c76bec 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt @@ -7,7 +7,6 @@ import android.view.View import android.view.ViewGroup import androidx.annotation.DrawableRes import androidx.annotation.StringRes -import androidx.compose.runtime.Composable import androidx.core.content.res.ResourcesCompat import androidx.fragment.app.DialogFragment import org.wordpress.android.R @@ -70,8 +69,8 @@ abstract class FeatureIntroductionDialogFragment : DialogFragment() { binding.headerIcon.setImageDrawable(ResourcesCompat.getDrawable(resources, headerIconRes, context?.theme)) } - fun setContent(content: @Composable () -> Unit) { - binding.content.setContent(content) + fun setContent(view: View) { + binding.contentContainer.addView(view) } private fun setupCloseButton() { diff --git a/WordPress/src/main/res/color/lightbulb_orange_background.xml b/WordPress/src/main/res/color/lightbulb_orange_background.xml index 199d7cd18d60..34dcac8c7a12 100644 --- a/WordPress/src/main/res/color/lightbulb_orange_background.xml +++ b/WordPress/src/main/res/color/lightbulb_orange_background.xml @@ -1,6 +1,6 @@ diff --git a/WordPress/src/main/res/drawable/bg_rectangle_black_60_radius_2dp.xml b/WordPress/src/main/res/drawable/bg_rectangle_black_60_radius_2dp.xml new file mode 100644 index 000000000000..9458d24b8ceb --- /dev/null +++ b/WordPress/src/main/res/drawable/bg_rectangle_black_60_radius_2dp.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/WordPress/src/main/res/drawable/ic_outline_lightbulb_orange_gradient_40dp.xml b/WordPress/src/main/res/drawable/ic_outline_lightbulb_orange_gradient_40dp.xml index 0b2d8f44668d..b419eccfb2a4 100644 --- a/WordPress/src/main/res/drawable/ic_outline_lightbulb_orange_gradient_40dp.xml +++ b/WordPress/src/main/res/drawable/ic_outline_lightbulb_orange_gradient_40dp.xml @@ -1,8 +1,9 @@ + android:viewportHeight="24" + android:viewportWidth="24"> + diff --git a/WordPress/src/main/res/layout/blogging_prompts_omboarding_dialog_content_view.xml b/WordPress/src/main/res/layout/blogging_prompts_omboarding_dialog_content_view.xml new file mode 100644 index 000000000000..6731a8abe0f2 --- /dev/null +++ b/WordPress/src/main/res/layout/blogging_prompts_omboarding_dialog_content_view.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + diff --git a/WordPress/src/main/res/layout/feature_introduction_dialog_fragment.xml b/WordPress/src/main/res/layout/feature_introduction_dialog_fragment.xml index 8f4b23dcff84..545148a006e2 100644 --- a/WordPress/src/main/res/layout/feature_introduction_dialog_fragment.xml +++ b/WordPress/src/main/res/layout/feature_introduction_dialog_fragment.xml @@ -48,7 +48,6 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginBottom="@dimen/margin_extra_large" - android:layout_marginTop="@dimen/margin_extra_large" app:layout_constraintBottom_toTopOf="@+id/content_container" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -63,10 +62,11 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" - tools:src="@drawable/ic_add_outline_grey_dark_24dp" /> + tools:src="@drawable/ic_outline_lightbulb_orange_gradient_40dp" /> - - diff --git a/WordPress/src/main/res/values/strings.xml b/WordPress/src/main/res/values/strings.xml index 17e0a0346925..915d1c45490b 100644 --- a/WordPress/src/main/res/values/strings.xml +++ b/WordPress/src/main/res/values/strings.xml @@ -3998,8 +3998,10 @@ translators: %s: Select control option value e.g: "Auto, 25%". --> Introducing Prompts - The best way to become a better writer is to build a writing habit and share with others — that’s where Prompts come in! - We’ll show you a new prompt each day on your dashboard to help get those creative juices flowing! + The best way to become a better writer is to build a writing habit and share with others — that’s where Prompts come in! + We’ll show you a new prompt each day on your dashboard to help get those creative juices flowing! + Note: + You can learn more and set up reminders at any time in My Site > Settings > Blogging Reminders Try it now Remind me Cast the movie of your life. diff --git a/WordPress/src/main/res/values/styles.xml b/WordPress/src/main/res/values/styles.xml index 161eb705ef38..96f5378d722b 100644 --- a/WordPress/src/main/res/values/styles.xml +++ b/WordPress/src/main/res/values/styles.xml @@ -1728,4 +1728,15 @@ 0dp viewStart + + + diff --git a/build.gradle b/build.gradle index 163fa1e9a613..290e905dc3cb 100644 --- a/build.gradle +++ b/build.gradle @@ -31,8 +31,6 @@ ext { exoPlayerVersion = '2.9.3' - composeVersion = '1.0.5' - // testing jUnitVersion = '4.13' androidxTestVersion = '1.1.0' From 3820c966bfc4f3010593f26d946fdcad8e99a0fa Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Wed, 30 Mar 2022 23:31:19 -0300 Subject: [PATCH 20/29] Blogging prompts onboarding dialog: add space after note title --- .../onboarding/BloggingPromptsOnboardingDialogFragment.kt | 2 +- WordPress/src/main/res/values/strings.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt index cdc3ca096a09..f43b3abebc76 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt @@ -76,7 +76,7 @@ class BloggingPromptsOnboardingDialogFragment : FeatureIntroductionDialogFragmen contentNote.text = getString(readyState.contentNoteTitle) contentNote.text = buildSpannedString { - bold { append(getString(readyState.contentNoteTitle)) } + bold { append("${getString(readyState.contentNoteTitle)} ") } append(getString(readyState.contentNoteContent)) } } diff --git a/WordPress/src/main/res/values/strings.xml b/WordPress/src/main/res/values/strings.xml index 915d1c45490b..c873eaca7013 100644 --- a/WordPress/src/main/res/values/strings.xml +++ b/WordPress/src/main/res/values/strings.xml @@ -4000,7 +4000,7 @@ translators: %s: Select control option value e.g: "Auto, 25%". --> Introducing Prompts The best way to become a better writer is to build a writing habit and share with others — that’s where Prompts come in! We’ll show you a new prompt each day on your dashboard to help get those creative juices flowing! - Note: + Note: You can learn more and set up reminders at any time in My Site > Settings > Blogging Reminders Try it now Remind me From eee5ead52e4b3c5ba9e0910fb2123a01206c09c2 Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Wed, 30 Mar 2022 23:44:34 -0300 Subject: [PATCH 21/29] Remove extra call to contentNote.text in BloggingPromptsOnboardingDialogFragment --- .../onboarding/BloggingPromptsOnboardingDialogFragment.kt | 2 -- .../onboarding/BloggingPromptsOnboardingUiStateMapper.kt | 1 - 2 files changed, 3 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt index f43b3abebc76..878705f59c33 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingDialogFragment.kt @@ -73,8 +73,6 @@ class BloggingPromptsOnboardingDialogFragment : FeatureIntroductionDialogFragmen promptCard.promptContent.text = getString(readyState.promptRes) promptCard.numberOfAnswers.text = getString(readyState.answersRes, readyState.answersCount) contentBottom.text = getString(readyState.contentBottomRes) - contentNote.text = getString(readyState.contentNoteTitle) - contentNote.text = buildSpannedString { bold { append("${getString(readyState.contentNoteTitle)} ") } append(getString(readyState.contentNoteContent)) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapper.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapper.kt index c15816b6fd78..a267796b2e41 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapper.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapper.kt @@ -18,4 +18,3 @@ class BloggingPromptsOnboardingUiStateMapper @Inject constructor() { } private const val ANSWER_COUNT = 19 - From f2e5cb0132fe345ccb3595126e1430bdb1ae0039 Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Wed, 30 Mar 2022 23:44:55 -0300 Subject: [PATCH 22/29] Add unit tests for BloggingPromptsOnboardingUiStateMapper --- ...ggingPromptsOnboardingUiStateMapperTest.kt | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapperTest.kt diff --git a/WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapperTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapperTest.kt new file mode 100644 index 000000000000..a1316dbc7df8 --- /dev/null +++ b/WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapperTest.kt @@ -0,0 +1,59 @@ +package org.wordpress.android.ui.bloggingprompts.onboarding + +import org.assertj.core.api.Assertions.assertThat +import org.junit.Test +import org.wordpress.android.R + +class BloggingPromptsOnboardingUiStateMapperTest { + + private val classToTest = BloggingPromptsOnboardingUiStateMapper() + + @Test + fun `Should return correct Ready state string resource for promptRes`() { + val actual = classToTest.mapReady().promptRes + val expected = R.string.blogging_prompts_onboarding_card_prompt + assertThat(actual).isEqualTo(expected) + } + + @Test + fun `Should return correct Ready state string resource for answersRes`() { + val actual = classToTest.mapReady().answersRes + val expected = R.string.my_site_blogging_prompt_card_number_of_answers + assertThat(actual).isEqualTo(expected) + } + + @Test + fun `Should return correct Ready state answers count`() { + val actual = classToTest.mapReady().answersCount + val expected = 19 + assertThat(actual).isEqualTo(expected) + } + + @Test + fun `Should return correct Ready state string resource for contentTopRes`() { + val actual = classToTest.mapReady().contentTopRes + val expected = R.string.blogging_prompts_onboarding_content_top + assertThat(actual).isEqualTo(expected) + } + + @Test + fun `Should return correct Ready state string resource for contentBottomRes`() { + val actual = classToTest.mapReady().contentBottomRes + val expected = R.string.blogging_prompts_onboarding_content_bottom + assertThat(actual).isEqualTo(expected) + } + + @Test + fun `Should return correct Ready state string resource for contentNoteTitle`() { + val actual = classToTest.mapReady().contentNoteTitle + val expected = R.string.blogging_prompts_onboarding_content_note_title + assertThat(actual).isEqualTo(expected) + } + + @Test + fun `Should return correct Ready state string resource for contentNoteContent`() { + val actual = classToTest.mapReady().contentNoteContent + val expected = R.string.blogging_prompts_onboarding_content_note_content + assertThat(actual).isEqualTo(expected) + } +} From 97c6f29fb6e416c429291622d7a86e5149da6db4 Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Wed, 30 Mar 2022 23:58:46 -0300 Subject: [PATCH 23/29] Update BloggingPromptsOnboardingViewModel unit tests --- .../BloggingPromptsOnboardingAction.kt | 4 +-- .../BloggingPromptsOnboardingViewModel.kt | 5 ++- .../BloggingPromptsOnboardingViewModelTest.kt | 35 +++++++++++++------ 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingAction.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingAction.kt index 77627437d2c0..402bce02e4f4 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingAction.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingAction.kt @@ -1,9 +1,7 @@ package org.wordpress.android.ui.bloggingprompts.onboarding -import org.wordpress.android.models.bloggingprompts.BloggingPrompt - sealed class BloggingPromptsOnboardingAction { - data class OpenEditor(val bloggingPrompt: BloggingPrompt) : BloggingPromptsOnboardingAction() + object OpenEditor : BloggingPromptsOnboardingAction() object OpenSitePicker : BloggingPromptsOnboardingAction() diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModel.kt index 817c5912dcf3..469fdbb97fe9 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModel.kt @@ -4,7 +4,6 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import org.wordpress.android.fluxc.store.SiteStore -import org.wordpress.android.models.bloggingprompts.BloggingPrompt import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenEditor import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenRemindersIntro import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenSitePicker @@ -14,7 +13,6 @@ class BloggingPromptsOnboardingViewModel @Inject constructor( private val siteStore: SiteStore, private val uiStateMapper: BloggingPromptsOnboardingUiStateMapper ) : ViewModel() { - private lateinit var bloggingPrompt: BloggingPrompt private val _uiState = MutableLiveData() val uiState: LiveData = _uiState @@ -27,7 +25,8 @@ class BloggingPromptsOnboardingViewModel @Inject constructor( } fun onTryNowClick() { - _action.value = OpenEditor(bloggingPrompt) + // TODO send BloggingPrompt with OpenEditor action when prompt store is ready + _action.value = OpenEditor } fun onRemindMeClick() { diff --git a/WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModelTest.kt index 4e0b264ca6e4..5cd8c8e3bd98 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModelTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModelTest.kt @@ -3,36 +3,51 @@ package org.wordpress.android.ui.bloggingprompts.onboarding import androidx.lifecycle.Observer import com.nhaarman.mockitokotlin2.mock import com.nhaarman.mockitokotlin2.verify +import com.nhaarman.mockitokotlin2.whenever import org.junit.Before import org.junit.Test import org.wordpress.android.BaseUnitTest import org.wordpress.android.fluxc.store.SiteStore -import org.wordpress.android.models.bloggingprompts.BloggingPrompt import org.wordpress.android.test import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenEditor +import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenRemindersIntro +import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboardingAction.OpenSitePicker class BloggingPromptsOnboardingViewModelTest : BaseUnitTest() { private val uiStateMapper: BloggingPromptsOnboardingUiStateMapper = mock() private val siteStore: SiteStore = mock() - private val bloggingPromptsOnboardingViewModel = BloggingPromptsOnboardingViewModel(siteStore, uiStateMapper) + private val classToTest = BloggingPromptsOnboardingViewModel(siteStore, uiStateMapper) private val actionObserver: Observer = mock() @Before fun setup() { - bloggingPromptsOnboardingViewModel.action.observeForever(actionObserver) + classToTest.action.observeForever(actionObserver) } @Test - fun `Should execute GetBloggingPromptUseCase when start is called`() = test { - bloggingPromptsOnboardingViewModel.start() + fun `Should trigger Ready state when start is called`() { + classToTest.start() verify(uiStateMapper).mapReady() } @Test - fun `Should trigger OpenEditor action when onTryNow is called`() = test { - val bloggingPrompt: BloggingPrompt = mock() - bloggingPromptsOnboardingViewModel.start() - bloggingPromptsOnboardingViewModel.onTryNowClick() - verify(actionObserver).onChanged(OpenEditor(bloggingPrompt)) + fun `Should trigger OpenEditor action when onTryNow is called`() { + classToTest.start() + classToTest.onTryNowClick() + verify(actionObserver).onChanged(OpenEditor) + } + + @Test + fun `Should trigger OpenSitePicker if Remind Me is clicked and user has more than 1 site`() = test { + whenever(siteStore.sitesCount).thenReturn(2) + classToTest.onRemindMeClick() + verify(actionObserver).onChanged(OpenSitePicker) + } + + @Test + fun `Should trigger OpenRemindersIntro if Remind Me is clicked and user has only 1 site`() = test { + whenever(siteStore.sitesCount).thenReturn(1) + classToTest.onRemindMeClick() + verify(actionObserver).onChanged(OpenRemindersIntro) } } From 6fbd73e642767b16cadcf865cdd0d74ebb974249 Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Thu, 31 Mar 2022 00:03:07 -0300 Subject: [PATCH 24/29] Fix detekt: suppress too many functions for FeatureIntroductionDialogFragment --- .../ui/featureintroduction/FeatureIntroductionDialogFragment.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt index b4f214c76bec..9eff48e33297 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt @@ -13,6 +13,7 @@ import org.wordpress.android.R import org.wordpress.android.databinding.FeatureIntroductionDialogFragmentBinding import org.wordpress.android.util.extensions.setStatusBarAsSurfaceColor +@Suppress("TooManyFunctions") abstract class FeatureIntroductionDialogFragment : DialogFragment() { private var _binding: FeatureIntroductionDialogFragmentBinding? = null From a6d0d8084211aaddc778879f99c5767a5e751d6f Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Thu, 31 Mar 2022 00:03:37 -0300 Subject: [PATCH 25/29] Remove unused extension functions from StringExtensions and UiStringExtensions --- .../android/util/extensions/StringExtensions.kt | 6 ------ .../android/util/extensions/UiStringExtensions.kt | 14 -------------- 2 files changed, 20 deletions(-) delete mode 100644 WordPress/src/main/java/org/wordpress/android/util/extensions/UiStringExtensions.kt diff --git a/WordPress/src/main/java/org/wordpress/android/util/extensions/StringExtensions.kt b/WordPress/src/main/java/org/wordpress/android/util/extensions/StringExtensions.kt index 0694db3602f7..e231f0897c41 100644 --- a/WordPress/src/main/java/org/wordpress/android/util/extensions/StringExtensions.kt +++ b/WordPress/src/main/java/org/wordpress/android/util/extensions/StringExtensions.kt @@ -1,10 +1,6 @@ package org.wordpress.android.util.extensions import android.annotation.SuppressLint -import android.content.res.Resources -import org.wordpress.android.ui.utils.UiString -import org.wordpress.android.ui.utils.UiString.UiStringRes -import org.wordpress.android.ui.utils.UiString.UiStringText import java.util.Locale /** @@ -22,5 +18,3 @@ import java.util.Locale fun String.capitalizeWithLocaleWithoutLint(locale: Locale): String { return this.capitalize(locale) } - -fun String?.orEmpty(): String = this?.run { this } ?: "" diff --git a/WordPress/src/main/java/org/wordpress/android/util/extensions/UiStringExtensions.kt b/WordPress/src/main/java/org/wordpress/android/util/extensions/UiStringExtensions.kt deleted file mode 100644 index 2b526511ebf5..000000000000 --- a/WordPress/src/main/java/org/wordpress/android/util/extensions/UiStringExtensions.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.wordpress.android.util.extensions - -import android.content.Context -import org.wordpress.android.ui.utils.UiString -import org.wordpress.android.ui.utils.UiString.UiStringRes -import org.wordpress.android.ui.utils.UiString.UiStringResWithParams -import org.wordpress.android.ui.utils.UiString.UiStringText - -fun UiString.getText(context: Context): String = when (this) { - is UiStringText -> text.toString().orEmpty() - is UiStringRes -> context.getString(stringRes).orEmpty() - is UiStringResWithParams -> context.getString(stringRes, params.map { it.getText(context) }.toTypedArray()) - .orEmpty() -} From ab6b46037e0c8af697efeb585f4c71887bf25b78 Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Thu, 31 Mar 2022 00:06:22 -0300 Subject: [PATCH 26/29] Fix checkstyle: Empty line not allowed after brace --- .../onboarding/BloggingPromptsOnboardingUiStateMapper.kt | 1 - .../onboarding/BloggingPromptsOnboardingViewModel.kt | 1 - .../ui/featureintroduction/FeatureIntroductionDialogFragment.kt | 1 - .../onboarding/BloggingPromptsOnboardingUiStateMapperTest.kt | 1 - 4 files changed, 4 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapper.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapper.kt index a267796b2e41..c19b409f443d 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapper.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapper.kt @@ -5,7 +5,6 @@ import org.wordpress.android.ui.bloggingprompts.onboarding.BloggingPromptsOnboar import javax.inject.Inject class BloggingPromptsOnboardingUiStateMapper @Inject constructor() { - fun mapReady(): Ready = Ready( promptRes = R.string.blogging_prompts_onboarding_card_prompt, answersRes = R.string.my_site_blogging_prompt_card_number_of_answers, diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModel.kt index 469fdbb97fe9..8ecae9f3d595 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingViewModel.kt @@ -13,7 +13,6 @@ class BloggingPromptsOnboardingViewModel @Inject constructor( private val siteStore: SiteStore, private val uiStateMapper: BloggingPromptsOnboardingUiStateMapper ) : ViewModel() { - private val _uiState = MutableLiveData() val uiState: LiveData = _uiState diff --git a/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt index 9eff48e33297..c76ac38f2e19 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/featureintroduction/FeatureIntroductionDialogFragment.kt @@ -15,7 +15,6 @@ import org.wordpress.android.util.extensions.setStatusBarAsSurfaceColor @Suppress("TooManyFunctions") abstract class FeatureIntroductionDialogFragment : DialogFragment() { - private var _binding: FeatureIntroductionDialogFragmentBinding? = null private val binding get() = _binding ?: throw NullPointerException("_binding cannot be null") diff --git a/WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapperTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapperTest.kt index a1316dbc7df8..84b484346a6b 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapperTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/onboarding/BloggingPromptsOnboardingUiStateMapperTest.kt @@ -5,7 +5,6 @@ import org.junit.Test import org.wordpress.android.R class BloggingPromptsOnboardingUiStateMapperTest { - private val classToTest = BloggingPromptsOnboardingUiStateMapper() @Test From 6c89138d79fd26e958834d77e7ca0ca970eb9ba7 Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Thu, 31 Mar 2022 00:14:41 -0300 Subject: [PATCH 27/29] Remove Kotlin version compatibility check for Compose --- WordPress/build.gradle | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/WordPress/build.gradle b/WordPress/build.gradle index 24dd46baa293..5b308a149559 100644 --- a/WordPress/build.gradle +++ b/WordPress/build.gradle @@ -603,17 +603,6 @@ tasks.register("printAllVersions") { } } } -// TODO remove after merging PR that bumps Kotlin version -tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { - kotlinOptions { - jvmTarget = "1.8" - freeCompilerArgs += [ - "-Xallow-jvm-ir-dependencies", - "-P", - "plugin:androidx.compose.compiler.plugins.kotlin:suppressKotlinVersionCompatibilityCheck=true" - ] - } -} def checkGradlePropertiesFile() { def inputFile = file("${rootDir}/gradle.properties") From dceba76f9b4e6e438d89c706f15c71889a12104e Mon Sep 17 00:00:00 2001 From: Renan Lukas <14964993+RenanLukas@users.noreply.github.com> Date: Thu, 31 Mar 2022 19:42:19 -0300 Subject: [PATCH 28/29] Fix PR comments: blogging prompts introduction dialog card actions should be disabled, content area should be scrollable --- ...prompts_omboarding_dialog_content_view.xml | 14 +- .../feature_introduction_dialog_fragment.xml | 143 ++++++++---------- 2 files changed, 74 insertions(+), 83 deletions(-) diff --git a/WordPress/src/main/res/layout/blogging_prompts_omboarding_dialog_content_view.xml b/WordPress/src/main/res/layout/blogging_prompts_omboarding_dialog_content_view.xml index 6731a8abe0f2..f41847788ebf 100644 --- a/WordPress/src/main/res/layout/blogging_prompts_omboarding_dialog_content_view.xml +++ b/WordPress/src/main/res/layout/blogging_prompts_omboarding_dialog_content_view.xml @@ -17,20 +17,20 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/content_top"> - - + + + + + + + + + + + + + + + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/top_bar_container"> - - - - - - - - - - - - - - - - - + android:layout_height="match_parent" /> - - - Date: Fri, 1 Apr 2022 10:54:44 -0300 Subject: [PATCH 29/29] Fix introduction dialog content note width --- .../layout/blogging_prompts_omboarding_dialog_content_view.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/src/main/res/layout/blogging_prompts_omboarding_dialog_content_view.xml b/WordPress/src/main/res/layout/blogging_prompts_omboarding_dialog_content_view.xml index f41847788ebf..6bac234dec46 100644 --- a/WordPress/src/main/res/layout/blogging_prompts_omboarding_dialog_content_view.xml +++ b/WordPress/src/main/res/layout/blogging_prompts_omboarding_dialog_content_view.xml @@ -66,7 +66,7 @@