Skip to content
This repository has been archived by the owner on Feb 20, 2023. It is now read-only.

Commit

Permalink
Add helper for underlining text
Browse files Browse the repository at this point in the history
  • Loading branch information
NotWoods committed Jul 13, 2020
1 parent 88af736 commit eb649a4
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,16 @@
package org.mozilla.fenix.exceptions

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
Expand Down Expand Up @@ -59,10 +58,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() }
Expand Down
19 changes: 19 additions & 0 deletions app/src/main/java/org/mozilla/fenix/ext/TextView.kt
Original file line number Diff line number Diff line change
@@ -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)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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.*
Expand All @@ -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
Expand All @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,16 @@

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
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

/**
Expand All @@ -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() }
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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() }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/* 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 what’s 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() }
}
}

0 comments on commit eb649a4

Please sign in to comment.