Skip to content

Commit

Permalink
For mozilla-mobile#9328: Adds tips to homescreen
Browse files Browse the repository at this point in the history
  • Loading branch information
sblatz committed Mar 30, 2020
1 parent 1e63d6c commit d0d270b
Show file tree
Hide file tree
Showing 22 changed files with 445 additions and 17 deletions.
6 changes: 4 additions & 2 deletions app/src/main/java/org/mozilla/fenix/components/Components.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,17 @@ import android.content.Intent
import androidx.core.net.toUri
import mozilla.components.feature.addons.AddonManager
import mozilla.components.feature.addons.amo.AddonCollectionProvider
import mozilla.components.feature.addons.migration.DefaultSupportedAddonsChecker
import mozilla.components.feature.addons.migration.SupportedAddonsChecker
import mozilla.components.feature.addons.update.AddonUpdater
import mozilla.components.feature.addons.update.DefaultAddonUpdater
import mozilla.components.feature.addons.migration.SupportedAddonsChecker
import mozilla.components.feature.addons.migration.DefaultSupportedAddonsChecker
import mozilla.components.feature.tabs.TabsUseCases
import mozilla.components.lib.publicsuffixlist.PublicSuffixList
import mozilla.components.support.migration.state.MigrationStore
import org.mozilla.fenix.BuildConfig
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.home.sessioncontrol.viewholders.tips.TipManager
import org.mozilla.fenix.test.Mockable
import org.mozilla.fenix.utils.ClipboardHandler
import org.mozilla.fenix.wifi.WifiConnectionMonitor
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ import org.mozilla.fenix.home.sessioncontrol.SessionControlAdapter
import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor
import org.mozilla.fenix.home.sessioncontrol.SessionControlView
import org.mozilla.fenix.home.sessioncontrol.viewholders.CollectionViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.tips.TipManager
import org.mozilla.fenix.onboarding.FenixOnboarding
import org.mozilla.fenix.settings.SupportUtils
import org.mozilla.fenix.settings.deletebrowsingdata.deleteAndQuit
Expand Down Expand Up @@ -203,7 +204,8 @@ class HomeFragment : Fragment() {
expandedCollections = emptySet(),
mode = currentMode.getCurrentMode(),
tabs = emptyList(),
topSites = requireComponents.core.topSiteStorage.cachedTopSites
topSites = requireComponents.core.topSiteStorage.cachedTopSites,
tips = TipManager(requireContext()).getTipOrCriticalMessage()
)
)
}
Expand Down
13 changes: 11 additions & 2 deletions app/src/main/java/org/mozilla/fenix/home/HomeFragmentStore.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import mozilla.components.feature.top.sites.TopSite
import mozilla.components.lib.state.Action
import mozilla.components.lib.state.State
import mozilla.components.lib.state.Store
import org.mozilla.fenix.home.sessioncontrol.viewholders.tips.Tip

/**
* The [Store] for holding the [HomeFragmentState] and applying [HomeFragmentAction]s.
Expand Down Expand Up @@ -58,15 +59,17 @@ data class HomeFragmentState(
val expandedCollections: Set<Long>,
val mode: Mode,
val tabs: List<Tab>,
val topSites: List<TopSite>
val topSites: List<TopSite>,
val tips: List<Tip>? = null
) : State

sealed class HomeFragmentAction : Action {
data class Change(
val tabs: List<Tab>,
val topSites: List<TopSite>,
val mode: Mode,
val collections: List<TabCollection>
val collections: List<TabCollection>,
val tips: List<Tip>? = null
) :
HomeFragmentAction()

Expand All @@ -77,6 +80,7 @@ sealed class HomeFragmentAction : Action {
data class ModeChange(val mode: Mode, val tabs: List<Tab> = emptyList()) : HomeFragmentAction()
data class TabsChange(val tabs: List<Tab>) : HomeFragmentAction()
data class TopSitesChange(val topSites: List<TopSite>) : HomeFragmentAction()
data class RemoveTip(val tip: Tip) : HomeFragmentAction()
}

private fun homeFragmentStateReducer(
Expand Down Expand Up @@ -105,5 +109,10 @@ private fun homeFragmentStateReducer(
is HomeFragmentAction.ModeChange -> state.copy(mode = action.mode, tabs = action.tabs)
is HomeFragmentAction.TabsChange -> state.copy(tabs = action.tabs)
is HomeFragmentAction.TopSitesChange -> state.copy(topSites = action.topSites)
is HomeFragmentAction.RemoveTip -> {
val copiedTips = state.tips!!.toMutableList()
copiedTips.remove(action.tip)
state.copy(tips = copiedTips.toList())
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,12 @@ import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingTh
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingToolbarPositionPickerViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingTrackingProtectionViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingWhatsNewViewHolder

import org.mozilla.fenix.home.sessioncontrol.viewholders.tips.Tip
import org.mozilla.fenix.home.sessioncontrol.viewholders.tips.TipViewHolder
import mozilla.components.feature.tab.collections.Tab as ComponentTab

sealed class AdapterItem(@LayoutRes val viewType: Int) {
data class TipItem(val tip: Tip) : AdapterItem(TipViewHolder.LAYOUT_ID)
data class TabHeader(val isPrivate: Boolean, val hasTabs: Boolean) : AdapterItem(TabHeaderViewHolder.LAYOUT_ID)
data class TabItem(val tab: Tab) : AdapterItem(TabViewHolder.LAYOUT_ID) {
override fun sameAs(other: AdapterItem) = other is TabItem && tab.sessionId == other.tab.sessionId
Expand Down Expand Up @@ -162,6 +164,7 @@ class SessionControlAdapter(
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(viewType, parent, false)
return when (viewType) {
TipViewHolder.LAYOUT_ID -> TipViewHolder(view, interactor)
TabHeaderViewHolder.LAYOUT_ID -> TabHeaderViewHolder(view, interactor)
TabViewHolder.LAYOUT_ID -> TabViewHolder(view, interactor)
TopSiteViewHolder.LAYOUT_ID -> TopSiteViewHolder(view, interactor)
Expand All @@ -183,6 +186,7 @@ class SessionControlAdapter(
OnboardingFinishViewHolder.LAYOUT_ID -> OnboardingFinishViewHolder(view, interactor)
OnboardingWhatsNewViewHolder.LAYOUT_ID -> OnboardingWhatsNewViewHolder(view)
OnboardingToolbarPositionPickerViewHolder.LAYOUT_ID -> OnboardingToolbarPositionPickerViewHolder(view)
// TODO: interactor
else -> throw IllegalStateException()
}
}
Expand All @@ -193,6 +197,10 @@ class SessionControlAdapter(
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val item = getItem(position)
when (holder) {
is TipViewHolder -> {
val tipItem = item as AdapterItem.TipItem
holder.bind(tipItem.tip)
}
is TabHeaderViewHolder -> {
val tabHeader = item as AdapterItem.TabHeader
holder.bind(tabHeader.isPrivate, tabHeader.hasTabs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import org.mozilla.fenix.home.HomeFragmentAction
import org.mozilla.fenix.home.HomeFragmentDirections
import org.mozilla.fenix.home.HomeFragmentStore
import org.mozilla.fenix.home.Tab
import org.mozilla.fenix.home.sessioncontrol.viewholders.tips.Tip
import org.mozilla.fenix.settings.SupportUtils
import mozilla.components.feature.tab.collections.Tab as ComponentTab

Expand Down Expand Up @@ -153,6 +154,8 @@ interface SessionControlController {
* @see [TabSessionInteractor.onOpenNewTabClicked]
*/
fun handleonOpenNewTabClicked()

fun handleCloseTip(tip: Tip)
}

@SuppressWarnings("TooManyFunctions", "LargeClass")
Expand Down Expand Up @@ -366,6 +369,10 @@ class DefaultSessionControlController(
openSearchScreen()
}

override fun handleCloseTip(tip: Tip) {
store.dispatch(HomeFragmentAction.RemoveTip(tip))
}

private fun showCollectionCreationFragment(
step: SaveCollectionStep,
selectedTabIds: Array<String>? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import android.view.View
import mozilla.components.feature.tab.collections.Tab
import mozilla.components.feature.tab.collections.TabCollection
import mozilla.components.feature.top.sites.TopSite
import org.mozilla.fenix.home.sessioncontrol.viewholders.tips.Tip

/**
* Interface for collection related actions in the [SessionControlInteractor].
Expand Down Expand Up @@ -94,6 +95,13 @@ interface OnboardingInteractor {
fun onOpenSettingsClicked()
}

interface TipInteractor {
/**
* Dismisses the tip view adapter
*/
fun onCloseTip(tip: Tip)
}

/**
* Interface for tab related actions in the [SessionControlInteractor].
*/
Expand Down Expand Up @@ -195,7 +203,7 @@ interface TopSiteInteractor {
@SuppressWarnings("TooManyFunctions")
class SessionControlInteractor(
private val controller: SessionControlController
) : CollectionInteractor, OnboardingInteractor, TabSessionInteractor, TopSiteInteractor {
) : CollectionInteractor, OnboardingInteractor, TabSessionInteractor, TopSiteInteractor, TipInteractor {
override fun onCloseTab(sessionId: String) {
controller.handleCloseTab(sessionId)
}
Expand Down Expand Up @@ -283,4 +291,8 @@ class SessionControlInteractor(
override fun onOpenNewTabClicked() {
controller.handleonOpenNewTabClicked()
}

override fun onCloseTip(tip: Tip) {
controller.handleCloseTip(tip)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import org.mozilla.fenix.home.HomeScreenViewModel
import org.mozilla.fenix.home.Mode
import org.mozilla.fenix.home.OnboardingState
import org.mozilla.fenix.home.Tab
import org.mozilla.fenix.home.sessioncontrol.viewholders.tips.Tip

val noTabMessage = AdapterItem.NoContentMessageWithAction(
R.string.no_open_tabs_header_2,
Expand All @@ -39,16 +40,20 @@ private fun normalModeAdapterItems(
tabs: List<Tab>,
topSites: List<TopSite>,
collections: List<TabCollection>,
expandedCollections: Set<Long>
expandedCollections: Set<Long>,
tips: List<Tip>?
): List<AdapterItem> {
val items = mutableListOf<AdapterItem>()

tips?.forEach { items.add(AdapterItem.TipItem(it)) }

if (topSites.isNotEmpty()) {
items.add(AdapterItem.TopSiteList(topSites))
}

items.add(AdapterItem.TabHeader(false, tabs.isNotEmpty()))


when {
tabs.isNotEmpty() && collections.isNotEmpty() -> {
showTabs(items, tabs)
Expand Down Expand Up @@ -149,7 +154,7 @@ private fun onboardingAdapterItems(onboardingState: OnboardingState): List<Adapt
}

private fun HomeFragmentState.toAdapterList(): List<AdapterItem> = when (mode) {
is Mode.Normal -> normalModeAdapterItems(tabs, topSites, collections, expandedCollections)
is Mode.Normal -> normalModeAdapterItems(tabs, topSites, collections, expandedCollections, tips)
is Mode.Private -> privateModeAdapterItems(tabs)
is Mode.Onboarding -> onboardingAdapterItems(mode.state)
}
Expand Down Expand Up @@ -194,6 +199,7 @@ class SessionControlView(
sessionControlAdapter.submitList(null)
}

// TODO: this may be helpful
val stateAdapterList = state.toAdapterList()

if (homeScreenViewModel.shouldScrollToTopSites) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@ import org.mozilla.fenix.ext.setBounds
/**
* Sets the drawableStart of a header in an onboarding card.
*/
fun TextView.setOnboardingIcon(@DrawableRes id: Int) {
fun TextView.setOnboardingIcon(@DrawableRes id: Int, shouldTint: Boolean = true) {
val icon = AppCompatResources.getDrawable(context, id)
val size = context.resources.getDimensionPixelSize(R.dimen.onboarding_header_icon_height_width)
icon?.setBounds(size)
icon?.setTint(ContextCompat.getColor(context, R.color.onboarding_card_icon))

if (shouldTint) {
icon?.setTint(ContextCompat.getColor(context, R.color.onboarding_card_icon))
}

putCompoundDrawablesRelative(start = icon)
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ class OnboardingToolbarPositionPickerViewHolder(view: View) : RecyclerView.ViewH
init {
val radioTopToolbar = view.toolbar_top_radio_button
val radioBottomToolbar = view.toolbar_bottom_radio_button

radioTopToolbar.addToRadioGroup(radioBottomToolbar)
radioBottomToolbar.addToRadioGroup(radioTopToolbar)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import kotlinx.android.synthetic.main.onboarding_whats_new.view.*
import org.mozilla.fenix.R
import org.mozilla.fenix.settings.SupportUtils

class OnboardingWhatsNewViewHolder(view: View) : RecyclerView.ViewHolder(view) {
class OnboardingWhatsNewViewHolder(
view: View
) : RecyclerView.ViewHolder(view) {

init {
view.header_text.setOnboardingIcon(R.drawable.ic_whats_new)
Expand Down
Loading

0 comments on commit d0d270b

Please sign in to comment.