1
0
Fork 0

Add helper for underlining text (#12520)

master
Tiger Oakes 2020-07-15 22:38:46 -07:00 committed by GitHub
parent a0491b702e
commit d4bb432e24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 152 additions and 45 deletions

View File

@ -0,0 +1,19 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.ext
import android.text.style.UnderlineSpan
import android.widget.TextView
import androidx.core.text.toSpannable
/**
* Adds an underline effect to the text displayed in the TextView.
*/
fun TextView.addUnderline() {
val currentText = text
text = currentText.toSpannable().apply {
setSpan(UnderlineSpan(), 0, currentText.length, 0)
}
}

View File

@ -4,13 +4,12 @@
package org.mozilla.fenix.home.sessioncontrol.viewholders
import android.text.SpannableString
import android.text.method.LinkMovementMethod
import android.text.style.UnderlineSpan
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.private_browsing_description.view.*
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.addUnderline
import org.mozilla.fenix.home.sessioncontrol.TabSessionInteractor
class PrivateBrowsingDescriptionViewHolder(
@ -24,13 +23,9 @@ class PrivateBrowsingDescriptionViewHolder(
view.private_session_description.text = resources.getString(
R.string.private_browsing_placeholder_description_2, appName
)
val commonMythsText = view.private_session_common_myths.text.toString()
val textWithLink = SpannableString(commonMythsText).apply {
setSpan(UnderlineSpan(), 0, commonMythsText.length, 0)
}
with(view.private_session_common_myths) {
movementMethod = LinkMovementMethod.getInstance()
text = textWithLink
addUnderline()
setOnClickListener {
interactor.onPrivateBrowsingLearnMoreClicked()
}

View File

@ -6,8 +6,8 @@ package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
import android.widget.TextView
import androidx.annotation.DrawableRes
import androidx.appcompat.content.res.AppCompatResources
import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.android.content.getDrawableWithTint
import mozilla.components.support.ktx.android.view.putCompoundDrawablesRelative
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.setBounds
@ -16,9 +16,9 @@ import org.mozilla.fenix.ext.setBounds
* Sets the drawableStart of a header in an onboarding card.
*/
fun TextView.setOnboardingIcon(@DrawableRes id: Int) {
val icon = AppCompatResources.getDrawable(context, id)
val size = context.resources.getDimensionPixelSize(R.dimen.onboarding_header_icon_height_width)
icon?.setBounds(size)
icon?.setTint(context.getColorFromAttr(R.attr.onboardingSelected))
val icon = context.getDrawableWithTint(id, context.getColorFromAttr(R.attr.onboardingSelected))?.apply {
val size = context.resources.getDimensionPixelSize(R.dimen.onboarding_header_icon_height_width)
setBounds(size)
}
putCompoundDrawablesRelative(start = icon)
}

View File

@ -5,11 +5,11 @@
package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
import android.view.View
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.ContextCompat
import androidx.navigation.Navigation
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.onboarding_manual_signin.view.*
import mozilla.components.support.ktx.android.content.getDrawableWithTint
import mozilla.components.support.ktx.android.view.putCompoundDrawablesRelativeWithIntrinsicBounds
import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event
@ -34,8 +34,10 @@ class OnboardingManualSignInViewHolder(view: View) : RecyclerView.ViewHolder(vie
val appName = context.getString(R.string.app_name)
headerText.text = context.getString(R.string.onboarding_firefox_account_header, appName)
val icon = AppCompatResources.getDrawable(context, R.drawable.ic_onboarding_firefox_accounts)
icon?.setTint(ContextCompat.getColor(context, R.color.white_color))
val icon = context.getDrawableWithTint(
R.drawable.ic_onboarding_firefox_accounts,
ContextCompat.getColor(context, R.color.white_color)
)
headerText.putCompoundDrawablesRelativeWithIntrinsicBounds(start = icon)
}

View File

@ -4,13 +4,12 @@
package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
import android.text.SpannableString
import android.text.style.UnderlineSpan
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.onboarding_whats_new.view.*
import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.addUnderline
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.home.sessioncontrol.OnboardingInteractor
@ -25,12 +24,7 @@ class OnboardingWhatsNewViewHolder(
val appName = view.context.getString(R.string.app_name)
view.description_text.text = view.context.getString(R.string.onboarding_whats_new_description, appName)
val getAnswersText = view.get_answers.text.toString()
val textWithLink = SpannableString(getAnswersText).apply {
setSpan(UnderlineSpan(), 0, getAnswersText.length, 0)
}
view.get_answers.text = textWithLink
view.get_answers.addUnderline()
view.get_answers.setOnClickListener {
interactor.onWhatsNewGetAnswersClicked()
view.context.components.analytics.metrics.track(Event.OnboardingWhatsNew)

View File

@ -1,7 +1,5 @@
package org.mozilla.fenix.home.tips
import android.text.SpannableString
import android.text.style.UnderlineSpan
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.button_tip_item.view.*
@ -11,6 +9,7 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.tips.Tip
import org.mozilla.fenix.components.tips.TipType
import org.mozilla.fenix.ext.addUnderline
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor
@ -36,12 +35,7 @@ class ButtonTipViewHolder(
if (tip.learnMoreURL == null) {
tip_learn_more.visibility = View.GONE
} else {
val learnMoreText = context.getString(R.string.search_suggestions_onboarding_learn_more_link)
val textWithLink = SpannableString(learnMoreText).apply {
setSpan(UnderlineSpan(), 0, learnMoreText.length, 0)
}
tip_learn_more.text = textWithLink
tip_learn_more.addUnderline()
tip_learn_more.setOnClickListener {
(context as HomeActivity).openToBrowserAndLoad(

View File

@ -4,9 +4,7 @@
package org.mozilla.fenix.settings.logins
import android.text.SpannableString
import android.text.method.LinkMovementMethod
import android.text.style.UnderlineSpan
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.FrameLayout
@ -14,8 +12,8 @@ import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.main.component_saved_logins.view.*
import kotlinx.android.synthetic.main.component_saved_logins.view.progress_bar
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.addUnderline
import org.mozilla.fenix.utils.Settings
/**
@ -39,13 +37,9 @@ class SavedLoginsView(
itemAnimator = null
}
val learnMoreText = view.saved_passwords_empty_learn_more.text.toString()
val textWithLink = SpannableString(learnMoreText).apply {
setSpan(UnderlineSpan(), 0, learnMoreText.length, 0)
}
with(view.saved_passwords_empty_learn_more) {
movementMethod = LinkMovementMethod.getInstance()
text = textWithLink
addUnderline()
setOnClickListener { interactor.onLearnMore() }
}

View File

@ -5,17 +5,16 @@
package org.mozilla.fenix.trackingprotectionexceptions
import android.text.method.LinkMovementMethod
import android.text.style.UnderlineSpan
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.core.text.toSpannable
import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.main.component_exceptions.*
import mozilla.components.concept.engine.content.blocking.TrackingProtectionException
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.addUnderline
/**
* Interface for the ExceptionsViewInteractor. This interface is implemented by objects that want
@ -62,10 +61,7 @@ class ExceptionsView(
}
with(exceptions_learn_more) {
val learnMoreText = text
text = learnMoreText.toSpannable().apply {
setSpan(UnderlineSpan(), 0, learnMoreText.length, 0)
}
addUnderline()
movementMethod = LinkMovementMethod.getInstance()
setOnClickListener { interactor.onLearnMore() }

View File

@ -0,0 +1,39 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.home.sessioncontrol.viewholders
import android.view.LayoutInflater
import android.view.View
import io.mockk.mockk
import io.mockk.verify
import kotlinx.android.synthetic.main.private_browsing_description.view.*
import mozilla.components.support.test.robolectric.testContext
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.home.sessioncontrol.TabSessionInteractor
@RunWith(FenixRobolectricTestRunner::class)
class PrivateBrowsingDescriptionViewHolderTest {
private lateinit var view: View
private lateinit var interactor: TabSessionInteractor
@Before
fun setup() {
view = LayoutInflater.from(testContext)
.inflate(PrivateBrowsingDescriptionViewHolder.LAYOUT_ID, null)
interactor = mockk(relaxed = true)
}
@Test
fun `call interactor on click`() {
PrivateBrowsingDescriptionViewHolder(view, interactor)
view.private_session_common_myths.performClick()
verify { interactor.onPrivateBrowsingLearnMoreClicked() }
}
}

View File

@ -0,0 +1,74 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
import android.content.res.Resources
import android.text.Spanned
import android.view.LayoutInflater
import android.view.View
import androidx.core.text.HtmlCompat
import androidx.core.text.HtmlCompat.TO_HTML_PARAGRAPH_LINES_CONSECUTIVE
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkStatic
import io.mockk.unmockkStatic
import io.mockk.verify
import kotlinx.android.synthetic.main.onboarding_whats_new.view.*
import mozilla.components.support.ktx.android.content.res.resolveAttribute
import mozilla.components.support.test.robolectric.testContext
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.home.sessioncontrol.OnboardingInteractor
@RunWith(FenixRobolectricTestRunner::class)
class OnboardingWhatsNewViewHolderTest {
private lateinit var view: View
private lateinit var interactor: OnboardingInteractor
@Before
fun setup() {
mockkStatic("mozilla.components.support.ktx.android.content.res.ThemeKt")
view = LayoutInflater.from(testContext)
.inflate(OnboardingWhatsNewViewHolder.LAYOUT_ID, null)
interactor = mockk(relaxed = true)
every {
any<Resources.Theme>().resolveAttribute(R.attr.onboardingSelected)
} returns R.color.onboarding_illustration_selected_normal_theme
}
@After
fun teardown() {
unmockkStatic("mozilla.components.support.ktx.android.content.res.ThemeKt")
}
@Test
fun `sets and styles strings`() {
OnboardingWhatsNewViewHolder(view, interactor)
assertEquals(
"Have questions about the redesigned Firefox Preview? Want to know whats changed?",
view.description_text.text
)
val getAnswersHtml = HtmlCompat.toHtml(view.get_answers.text as Spanned, TO_HTML_PARAGRAPH_LINES_CONSECUTIVE)
assertTrue(getAnswersHtml, "<u>Get answers here</u>" in getAnswersHtml)
}
@Test
fun `call interactor on click`() {
OnboardingWhatsNewViewHolder(view, interactor)
view.get_answers.performClick()
verify { interactor.onWhatsNewGetAnswersClicked() }
}
}