From e2dd724f154ad3ad832a801ececd79659761e556 Mon Sep 17 00:00:00 2001 From: Noelia Alcala Date: Thu, 29 Dec 2022 18:46:44 +0100 Subject: [PATCH] ADS: Share Feedback section (#2670) Task/Issue URL: https://app.asana.com/0/0/1203467500325943/f **Description** Migration of share feedback screens to new components **_Design Review_** in https://app.asana.com/0/1195897901771673/1203575646431883 --- ...report_breakage_category_single_choice.xml | 6 +- .../BrokenSiteNegativeFeedbackFragment.kt | 8 +- .../negative/mainreason/MainReasonAdapter.kt | 12 +-- .../MainReasonNegativeFeedbackFragment.kt | 3 - .../ShareOpenEndedFeedbackFragment.kt | 6 +- .../ui/negative/subreason/SubReasonAdapter.kt | 12 +-- .../SubReasonNegativeFeedbackFragment.kt | 3 - .../res/drawable/feedback_list_divider.xml | 27 ------ app/src/main/res/layout/content_feedback.xml | 52 +++++++----- ...feedback_negative_broken_site_feedback.xml | 82 +++++++++---------- ...ck_negative_disambiguation_main_reason.xml | 46 +++++++---- ...ack_negative_disambiguation_sub_reason.xml | 47 +++++++---- .../content_feedback_open_ended_feedback.xml | 65 ++++++++------- .../content_feedback_positive_landing.xml | 76 ++++++++--------- .../main/res/layout/item_feedback_reason.xml | 42 ---------- .../ui/view/listitem/OneLineListItem.kt | 3 + .../android/ui/view/text/DaxTextInput.kt | 7 ++ common-ui/src/main/res/values/styles.xml | 48 +---------- 18 files changed, 235 insertions(+), 310 deletions(-) delete mode 100644 app/src/main/res/drawable/feedback_list_divider.xml delete mode 100644 app/src/main/res/layout/item_feedback_reason.xml diff --git a/app-tracking-protection/vpn-impl/src/main/res/layout/activity_report_breakage_category_single_choice.xml b/app-tracking-protection/vpn-impl/src/main/res/layout/activity_report_breakage_category_single_choice.xml index fbaa11d72ccf..0ddf557a0cc5 100644 --- a/app-tracking-protection/vpn-impl/src/main/res/layout/activity_report_breakage_category_single_choice.xml +++ b/app-tracking-protection/vpn-impl/src/main/res/layout/activity_report_breakage_category_single_choice.xml @@ -41,7 +41,7 @@ diff --git a/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/brokensite/BrokenSiteNegativeFeedbackFragment.kt b/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/brokensite/BrokenSiteNegativeFeedbackFragment.kt index 11ccc19c4bbb..325df4a4091f 100644 --- a/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/brokensite/BrokenSiteNegativeFeedbackFragment.kt +++ b/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/brokensite/BrokenSiteNegativeFeedbackFragment.kt @@ -60,13 +60,13 @@ class BrokenSiteNegativeFeedbackFragment : FeedbackFragment(R.layout.content_fee override fun configureListeners() { with(binding) { submitFeedbackButton.doOnNextLayout { - brokenSiteInput.setOnTouchListener(LayoutScrollingTouchListener(rootScrollView, brokenSiteInputContainer.y.toInt())) - openEndedFeedback.setOnTouchListener(LayoutScrollingTouchListener(rootScrollView, openEndedFeedbackContainer.y.toInt())) + brokenSiteInput.setOnTouchListener(LayoutScrollingTouchListener(rootScrollView, brokenSiteInput.y.toInt())) + openEndedFeedback.setOnTouchListener(LayoutScrollingTouchListener(rootScrollView, openEndedFeedback.y.toInt())) } submitFeedbackButton.setOnClickListener { - val feedback = openEndedFeedback.text.toString() - val brokenSite = brokenSiteInput.text.toString() + val feedback = openEndedFeedback.text + val brokenSite = brokenSiteInput.text viewModel.userSubmittingFeedback(feedback, brokenSite) } diff --git a/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/mainreason/MainReasonAdapter.kt b/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/mainreason/MainReasonAdapter.kt index 195ec7c91ed3..a3196f38c9fb 100644 --- a/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/mainreason/MainReasonAdapter.kt +++ b/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/mainreason/MainReasonAdapter.kt @@ -21,8 +21,8 @@ import android.view.ViewGroup import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView -import com.duckduckgo.app.browser.databinding.ItemFeedbackReasonBinding import com.duckduckgo.app.feedback.ui.negative.FeedbackTypeDisplay.FeedbackTypeMainReasonDisplay +import com.duckduckgo.mobile.android.databinding.RowOneLineListItemBinding class MainReasonAdapter(private val itemClickListener: (FeedbackTypeMainReasonDisplay) -> Unit) : ListAdapter(DiffCallback()) { @@ -48,7 +48,7 @@ class MainReasonAdapter(private val itemClickListener: (FeedbackTypeMainReasonDi viewType: Int, ): ViewHolder { val inflater = LayoutInflater.from(parent.context) - val binding = ItemFeedbackReasonBinding.inflate(inflater, parent, false) + val binding = RowOneLineListItemBinding.inflate(inflater, parent, false) return ViewHolder(binding) } @@ -59,14 +59,16 @@ class MainReasonAdapter(private val itemClickListener: (FeedbackTypeMainReasonDi holder.bind(getItem(position), itemClickListener) } - data class ViewHolder(val binding: ItemFeedbackReasonBinding) : RecyclerView.ViewHolder(binding.root) { + data class ViewHolder(val binding: RowOneLineListItemBinding) : RecyclerView.ViewHolder(binding.root) { fun bind( reason: FeedbackTypeMainReasonDisplay, clickListener: (FeedbackTypeMainReasonDisplay) -> Unit, ) { - binding.reason.text = binding.root.context.getString(reason.listDisplayResId) - binding.root.setOnClickListener { clickListener(reason) } + val listItem = binding.root + listItem.hideLeadingIcon() + listItem.setPrimaryText(binding.root.context.getString(reason.listDisplayResId)) + listItem.setOnClickListener { clickListener(reason) } } } } diff --git a/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/mainreason/MainReasonNegativeFeedbackFragment.kt b/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/mainreason/MainReasonNegativeFeedbackFragment.kt index 0ac623ee67ea..eeefa324d0bb 100644 --- a/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/mainreason/MainReasonNegativeFeedbackFragment.kt +++ b/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/mainreason/MainReasonNegativeFeedbackFragment.kt @@ -17,13 +17,11 @@ package com.duckduckgo.app.feedback.ui.negative.mainreason import android.os.Bundle -import androidx.core.content.ContextCompat import androidx.recyclerview.widget.LinearLayoutManager import com.duckduckgo.anvil.annotations.InjectWith import com.duckduckgo.app.browser.R import com.duckduckgo.app.browser.databinding.ContentFeedbackNegativeDisambiguationMainReasonBinding import com.duckduckgo.app.feedback.ui.common.FeedbackFragment -import com.duckduckgo.app.feedback.ui.common.FeedbackItemDecoration import com.duckduckgo.app.feedback.ui.negative.FeedbackType.MainReason import com.duckduckgo.app.feedback.ui.negative.FeedbackTypeDisplay import com.duckduckgo.app.feedback.ui.negative.FeedbackTypeDisplay.FeedbackTypeMainReasonDisplay @@ -58,7 +56,6 @@ class MainReasonNegativeFeedbackFragment : FeedbackFragment(R.layout.content_fee activity?.let { binding.recyclerView.layoutManager = LinearLayoutManager(it) binding.recyclerView.adapter = recyclerAdapter - binding.recyclerView.addItemDecoration(FeedbackItemDecoration(ContextCompat.getDrawable(it, R.drawable.feedback_list_divider)!!)) val listValues = getMainReasonsDisplayText() recyclerAdapter.submitList(listValues) diff --git a/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/openended/ShareOpenEndedFeedbackFragment.kt b/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/openended/ShareOpenEndedFeedbackFragment.kt index 40b08184f876..fb00acee2bf1 100644 --- a/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/openended/ShareOpenEndedFeedbackFragment.kt +++ b/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/openended/ShareOpenEndedFeedbackFragment.kt @@ -92,7 +92,7 @@ class ShareOpenEndedFeedbackFragment : FeedbackFragment(R.layout.content_feedbac private fun updateDisplayForPositiveFeedback() { binding.title.text = getString(R.string.feedbackShareDetails) binding.subtitle.text = getString(R.string.sharePositiveFeedbackWithTheTeam) - binding.openEndedFeedbackContainer.hint = getString(R.string.whatHaveYouBeenEnjoying) + binding.openEndedFeedback.hint = getString(R.string.whatHaveYouBeenEnjoying) binding.emoticonImage.setImageResource(R.drawable.ic_happy_face) } @@ -102,7 +102,7 @@ class ShareOpenEndedFeedbackFragment : FeedbackFragment(R.layout.content_feedbac binding.title.text = getDisplayText(mainReason!!) binding.subtitle.text = getDisplayText(subReason) - binding.openEndedFeedbackContainer.hint = getInputHintText(mainReason!!) + binding.openEndedFeedback.hint = getInputHintText(mainReason!!) binding.emoticonImage.setImageResource(R.drawable.ic_sad_face) } @@ -127,7 +127,7 @@ class ShareOpenEndedFeedbackFragment : FeedbackFragment(R.layout.content_feedbac override fun configureListeners() { with(binding) { rootScrollView.doOnNextLayout { - binding.openEndedFeedback.setOnTouchListener(LayoutScrollingTouchListener(rootScrollView, openEndedFeedbackContainer.y.toInt())) + binding.openEndedFeedback.setOnTouchListener(LayoutScrollingTouchListener(rootScrollView, openEndedFeedback.y.toInt())) } submitFeedbackButton.setOnClickListener { diff --git a/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/subreason/SubReasonAdapter.kt b/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/subreason/SubReasonAdapter.kt index ca438915d01f..bcf55e3c6e33 100644 --- a/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/subreason/SubReasonAdapter.kt +++ b/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/subreason/SubReasonAdapter.kt @@ -21,8 +21,8 @@ import android.view.ViewGroup import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView -import com.duckduckgo.app.browser.databinding.ItemFeedbackReasonBinding import com.duckduckgo.app.feedback.ui.negative.FeedbackTypeDisplay.FeedbackTypeSubReasonDisplay +import com.duckduckgo.mobile.android.databinding.RowOneLineListItemBinding class SubReasonAdapter(private val itemClickListener: (FeedbackTypeSubReasonDisplay) -> Unit) : ListAdapter(DiffCallback()) { @@ -48,7 +48,7 @@ class SubReasonAdapter(private val itemClickListener: (FeedbackTypeSubReasonDisp viewType: Int, ): ViewHolder { val inflater = LayoutInflater.from(parent.context) - val binding = ItemFeedbackReasonBinding.inflate(inflater, parent, false) + val binding = RowOneLineListItemBinding.inflate(inflater, parent, false) return ViewHolder(binding) } @@ -59,14 +59,16 @@ class SubReasonAdapter(private val itemClickListener: (FeedbackTypeSubReasonDisp holder.bind(getItem(position), itemClickListener) } - data class ViewHolder(val binding: ItemFeedbackReasonBinding) : RecyclerView.ViewHolder(binding.root) { + data class ViewHolder(val binding: RowOneLineListItemBinding) : RecyclerView.ViewHolder(binding.root) { fun bind( reason: FeedbackTypeSubReasonDisplay, clickListener: (FeedbackTypeSubReasonDisplay) -> Unit, ) { - binding.reason.text = binding.root.context.getString(reason.listDisplayResId) - binding.root.setOnClickListener { clickListener(reason) } + val listItem = binding.root + listItem.hideLeadingIcon() + listItem.setPrimaryText(binding.root.context.getString(reason.listDisplayResId)) + listItem.setOnClickListener { clickListener(reason) } } } } diff --git a/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/subreason/SubReasonNegativeFeedbackFragment.kt b/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/subreason/SubReasonNegativeFeedbackFragment.kt index a9a7042f7ccc..89bc8a097504 100644 --- a/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/subreason/SubReasonNegativeFeedbackFragment.kt +++ b/app/src/main/java/com/duckduckgo/app/feedback/ui/negative/subreason/SubReasonNegativeFeedbackFragment.kt @@ -17,13 +17,11 @@ package com.duckduckgo.app.feedback.ui.negative.subreason import android.os.Bundle -import androidx.core.content.ContextCompat import androidx.recyclerview.widget.LinearLayoutManager import com.duckduckgo.anvil.annotations.InjectWith import com.duckduckgo.app.browser.R import com.duckduckgo.app.browser.databinding.ContentFeedbackNegativeDisambiguationSubReasonBinding import com.duckduckgo.app.feedback.ui.common.FeedbackFragment -import com.duckduckgo.app.feedback.ui.common.FeedbackItemDecoration import com.duckduckgo.app.feedback.ui.negative.FeedbackType.* import com.duckduckgo.app.feedback.ui.negative.FeedbackType.MainReason.* import com.duckduckgo.app.feedback.ui.negative.FeedbackTypeDisplay @@ -94,7 +92,6 @@ class SubReasonNegativeFeedbackFragment : FeedbackFragment(R.layout.content_feed activity?.let { binding.recyclerView.layoutManager = LinearLayoutManager(it) binding.recyclerView.adapter = recyclerAdapter - binding.recyclerView.addItemDecoration(FeedbackItemDecoration(ContextCompat.getDrawable(it, R.drawable.feedback_list_divider)!!)) arguments?.let { args -> diff --git a/app/src/main/res/drawable/feedback_list_divider.xml b/app/src/main/res/drawable/feedback_list_divider.xml deleted file mode 100644 index d527681d96fc..000000000000 --- a/app/src/main/res/drawable/feedback_list_divider.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/content_feedback.xml b/app/src/main/res/layout/content_feedback.xml index 575922dd45db..f516a6f89d24 100644 --- a/app/src/main/res/layout/content_feedback.xml +++ b/app/src/main/res/layout/content_feedback.xml @@ -18,28 +18,39 @@ - + - + app:layout_constraintTop_toTopOf="parent" + app:typography="h1" /> - + app:layout_constraintTop_toBottomOf="@id/title" + app:typography="body1" /> + app:layout_constraintTop_toBottomOf="@id/subtitle" + tools:src="@drawable/button_happy_light_theme" /> + app:layout_constraintTop_toTopOf="@id/positiveFeedbackButton" + tools:src="@drawable/button_sad_light_theme" /> - + app:layout_constraintStart_toStartOf="parent" + app:textType="secondary" + app:typography="caption" /> \ No newline at end of file diff --git a/app/src/main/res/layout/content_feedback_negative_broken_site_feedback.xml b/app/src/main/res/layout/content_feedback_negative_broken_site_feedback.xml index 47c366a98412..46a6da7cf2f0 100644 --- a/app/src/main/res/layout/content_feedback_negative_broken_site_feedback.xml +++ b/app/src/main/res/layout/content_feedback_negative_broken_site_feedback.xml @@ -18,102 +18,94 @@ - + - + app:layout_constraintTop_toBottomOf="@id/emoticonImage" + app:typography="h1" /> - + app:layout_constraintTop_toBottomOf="@id/title" + app:typography="body1" /> - - - + app:layout_constraintTop_toBottomOf="@id/subtitle" + app:type="multi_line" /> - - - - - - - + app:layout_constraintTop_toBottomOf="@id/brokenSiteInput" + app:type="multi_line" /> - - \ No newline at end of file diff --git a/app/src/main/res/layout/content_feedback_negative_disambiguation_main_reason.xml b/app/src/main/res/layout/content_feedback_negative_disambiguation_main_reason.xml index a32a2d15a811..0b21284d3d4f 100644 --- a/app/src/main/res/layout/content_feedback_negative_disambiguation_main_reason.xml +++ b/app/src/main/res/layout/content_feedback_negative_disambiguation_main_reason.xml @@ -20,52 +20,64 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" - xmlns:tools="http://schemas.android.com/tools" android:fillViewport="true"> - + - + app:layout_constraintTop_toBottomOf="@id/emoticonImage" + app:typography="h1" /> - + app:layout_constraintTop_toBottomOf="@id/title" + app:typography="body1" /> + + - + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/divider" /> \ No newline at end of file diff --git a/app/src/main/res/layout/content_feedback_negative_disambiguation_sub_reason.xml b/app/src/main/res/layout/content_feedback_negative_disambiguation_sub_reason.xml index 75917a9a2c17..94eb367cc64f 100644 --- a/app/src/main/res/layout/content_feedback_negative_disambiguation_sub_reason.xml +++ b/app/src/main/res/layout/content_feedback_negative_disambiguation_sub_reason.xml @@ -18,56 +18,67 @@ - + - - + app:layout_constraintTop_toBottomOf="@id/title" + app:typography="body1" + tools:text="Which XXX feature can we improve or add?" /> + - + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/divider" /> \ No newline at end of file diff --git a/app/src/main/res/layout/content_feedback_open_ended_feedback.xml b/app/src/main/res/layout/content_feedback_open_ended_feedback.xml index e7b24dec7dad..c5753486950e 100644 --- a/app/src/main/res/layout/content_feedback_open_ended_feedback.xml +++ b/app/src/main/res/layout/content_feedback_open_ended_feedback.xml @@ -19,77 +19,80 @@ - + + app:layout_constraintTop_toTopOf="parent" + tools:src="@drawable/ic_sad_face" /> - - + app:layout_constraintTop_toBottomOf="@id/title" + app:typography="body1" + tools:text="Which feature can we improve or add?" /> - + app:layout_constraintTop_toBottomOf="@id/subtitle" + app:type="multi_line" /> - - - - - + app:layout_constraintTop_toBottomOf="@id/openEndedFeedback" + app:layout_constraintVertical_bias="0.9" /> \ No newline at end of file diff --git a/app/src/main/res/layout/content_feedback_positive_landing.xml b/app/src/main/res/layout/content_feedback_positive_landing.xml index 10943d335fb2..98185160a7b0 100644 --- a/app/src/main/res/layout/content_feedback_positive_landing.xml +++ b/app/src/main/res/layout/content_feedback_positive_landing.xml @@ -22,81 +22,83 @@ android:layout_height="match_parent" android:fillViewport="true"> - + - + app:layout_constraintTop_toBottomOf="@id/emoticonImage" + app:typography="h1" /> - + app:layout_constraintTop_toBottomOf="@id/title" + app:typography="body1" /> - - - + app:layout_constraintStart_toStartOf="parent" /> - + app:layout_constraintStart_toStartOf="parent" /> - + app:buttonSize="large" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" /> diff --git a/app/src/main/res/layout/item_feedback_reason.xml b/app/src/main/res/layout/item_feedback_reason.xml deleted file mode 100644 index 353cfc823e8a..000000000000 --- a/app/src/main/res/layout/item_feedback_reason.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/common-ui/src/main/java/com/duckduckgo/mobile/android/ui/view/listitem/OneLineListItem.kt b/common-ui/src/main/java/com/duckduckgo/mobile/android/ui/view/listitem/OneLineListItem.kt index a1b865fac680..5961b318d43a 100644 --- a/common-ui/src/main/java/com/duckduckgo/mobile/android/ui/view/listitem/OneLineListItem.kt +++ b/common-ui/src/main/java/com/duckduckgo/mobile/android/ui/view/listitem/OneLineListItem.kt @@ -117,6 +117,9 @@ class OneLineListItem @JvmOverloads constructor( binding.leadingIconBackground.show() } + /** Sets visibility of the item image resource to GONE */ + fun hideLeadingIcon() = binding.leadingIconBackground.gone() + fun leadingIcon() = binding.leadingIcon /** Sets the trailing icon image resource */ diff --git a/common-ui/src/main/java/com/duckduckgo/mobile/android/ui/view/text/DaxTextInput.kt b/common-ui/src/main/java/com/duckduckgo/mobile/android/ui/view/text/DaxTextInput.kt index daf69cd7f565..21193ec7ae04 100644 --- a/common-ui/src/main/java/com/duckduckgo/mobile/android/ui/view/text/DaxTextInput.kt +++ b/common-ui/src/main/java/com/duckduckgo/mobile/android/ui/view/text/DaxTextInput.kt @@ -47,6 +47,7 @@ import com.google.android.material.textfield.TextInputLayout.END_ICON_NONE interface TextInput { var text: String + var hint: String var isEditable: Boolean fun addTextChangedListener(textWatcher: TextWatcher) @@ -112,6 +113,12 @@ class DaxTextInput @JvmOverloads constructor( binding.internalEditText.setText(value) } + override var hint: String + get() = binding.internalEditText.text.toString() + set(value) { + binding.internalInputLayout.setHintWithoutAnimation(value) + } + override var isEditable: Boolean get() = binding.internalEditText.isEnabled set(value) { diff --git a/common-ui/src/main/res/values/styles.xml b/common-ui/src/main/res/values/styles.xml index 258b6c87654a..6df73a879a17 100644 --- a/common-ui/src/main/res/values/styles.xml +++ b/common-ui/src/main/res/values/styles.xml @@ -148,17 +148,11 @@ viewStart - - - - - - - - - - - -