2
0
mirror of https://github.com/fork-maintainers/iceraven-browser synced 2024-11-09 19:10:42 +00:00

For #11112 - Adds save tabs to collection button to the no collections message

This commit is contained in:
Jeff Boek 2020-06-12 15:46:00 -07:00
parent 55a3b6a622
commit 2861421312
11 changed files with 108 additions and 127 deletions

View File

@ -8,7 +8,6 @@ import android.content.Context
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.annotation.LayoutRes import androidx.annotation.LayoutRes
import androidx.annotation.StringRes
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
@ -19,7 +18,7 @@ import org.mozilla.fenix.home.OnboardingState
import org.mozilla.fenix.home.Tab import org.mozilla.fenix.home.Tab
import org.mozilla.fenix.home.sessioncontrol.viewholders.CollectionHeaderViewHolder import org.mozilla.fenix.home.sessioncontrol.viewholders.CollectionHeaderViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.CollectionViewHolder import org.mozilla.fenix.home.sessioncontrol.viewholders.CollectionViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.NoContentMessageViewHolder import org.mozilla.fenix.home.sessioncontrol.viewholders.NoCollectionsMessageViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.PrivateBrowsingDescriptionViewHolder import org.mozilla.fenix.home.sessioncontrol.viewholders.PrivateBrowsingDescriptionViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.TabInCollectionViewHolder import org.mozilla.fenix.home.sessioncontrol.viewholders.TabInCollectionViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.TopSiteViewHolder import org.mozilla.fenix.home.sessioncontrol.viewholders.TopSiteViewHolder
@ -42,10 +41,7 @@ sealed class AdapterItem(@LayoutRes val viewType: Int) {
ButtonTipViewHolder.LAYOUT_ID) ButtonTipViewHolder.LAYOUT_ID)
data class TopSiteList(val topSites: List<TopSite>) : AdapterItem(TopSiteViewHolder.LAYOUT_ID) data class TopSiteList(val topSites: List<TopSite>) : AdapterItem(TopSiteViewHolder.LAYOUT_ID)
object PrivateBrowsingDescription : AdapterItem(PrivateBrowsingDescriptionViewHolder.LAYOUT_ID) object PrivateBrowsingDescription : AdapterItem(PrivateBrowsingDescriptionViewHolder.LAYOUT_ID)
data class NoContentMessage( object NoCollectionsMessage : AdapterItem(NoCollectionsMessageViewHolder.LAYOUT_ID)
@StringRes val header: Int,
@StringRes val description: Int
) : AdapterItem(NoContentMessageViewHolder.LAYOUT_ID)
object CollectionHeader : AdapterItem(CollectionHeaderViewHolder.LAYOUT_ID) object CollectionHeader : AdapterItem(CollectionHeaderViewHolder.LAYOUT_ID)
data class CollectionItem( data class CollectionItem(
@ -123,7 +119,7 @@ class SessionControlAdapter(
ButtonTipViewHolder.LAYOUT_ID -> ButtonTipViewHolder(view, interactor) ButtonTipViewHolder.LAYOUT_ID -> ButtonTipViewHolder(view, interactor)
TopSiteViewHolder.LAYOUT_ID -> TopSiteViewHolder(view, interactor) TopSiteViewHolder.LAYOUT_ID -> TopSiteViewHolder(view, interactor)
PrivateBrowsingDescriptionViewHolder.LAYOUT_ID -> PrivateBrowsingDescriptionViewHolder(view, interactor) PrivateBrowsingDescriptionViewHolder.LAYOUT_ID -> PrivateBrowsingDescriptionViewHolder(view, interactor)
NoContentMessageViewHolder.LAYOUT_ID -> NoContentMessageViewHolder(view) NoCollectionsMessageViewHolder.LAYOUT_ID -> NoCollectionsMessageViewHolder(view, interactor)
CollectionHeaderViewHolder.LAYOUT_ID -> CollectionHeaderViewHolder(view) CollectionHeaderViewHolder.LAYOUT_ID -> CollectionHeaderViewHolder(view)
CollectionViewHolder.LAYOUT_ID -> CollectionViewHolder(view, interactor) CollectionViewHolder.LAYOUT_ID -> CollectionViewHolder(view, interactor)
TabInCollectionViewHolder.LAYOUT_ID -> TabInCollectionViewHolder(view, interactor, differentLastItem = true) TabInCollectionViewHolder.LAYOUT_ID -> TabInCollectionViewHolder(view, interactor, differentLastItem = true)
@ -155,10 +151,6 @@ class SessionControlAdapter(
is TopSiteViewHolder -> { is TopSiteViewHolder -> {
holder.bind((item as AdapterItem.TopSiteList).topSites) holder.bind((item as AdapterItem.TopSiteList).topSites)
} }
is NoContentMessageViewHolder -> {
val (header, description) = item as AdapterItem.NoContentMessage
holder.bind(header, description)
}
is CollectionViewHolder -> { is CollectionViewHolder -> {
val (collection, expanded) = item as AdapterItem.CollectionItem val (collection, expanded) = item as AdapterItem.CollectionItem
holder.bindSession(collection, expanded) holder.bindSession(collection, expanded)

View File

@ -120,6 +120,11 @@ interface SessionControlController {
fun handleToggleCollectionExpanded(collection: TabCollection, expand: Boolean) fun handleToggleCollectionExpanded(collection: TabCollection, expand: Boolean)
fun handleCloseTip(tip: Tip) fun handleCloseTip(tip: Tip)
/**
* @see [CollectionInteractor.onAddTabsToCollectionTapped]
*/
fun handleCreateCollection()
} }
@SuppressWarnings("TooManyFunctions", "LargeClass") @SuppressWarnings("TooManyFunctions", "LargeClass")
@ -301,6 +306,10 @@ class DefaultSessionControlController(
navController.nav(R.id.homeFragment, directions) navController.nav(R.id.homeFragment, directions)
} }
override fun handleCreateCollection() {
showCollectionCreationFragment(step = SaveCollectionStep.SelectTabs)
}
private fun showShareFragment(data: List<ShareData>) { private fun showShareFragment(data: List<ShareData>) {
val directions = HomeFragmentDirections.actionGlobalShareFragment( val directions = HomeFragmentDirections.actionGlobalShareFragment(
data = data.toTypedArray() data = data.toTypedArray()

View File

@ -88,6 +88,11 @@ interface CollectionInteractor {
* @param expand True if the given tab collection should be expanded or collapse if false. * @param expand True if the given tab collection should be expanded or collapse if false.
*/ */
fun onToggleCollectionExpanded(collection: TabCollection, expand: Boolean) fun onToggleCollectionExpanded(collection: TabCollection, expand: Boolean)
/**
* Opens the collection creator
*/
fun onAddTabsToCollectionTapped()
} }
/** /**
@ -219,6 +224,10 @@ class SessionControlInteractor(
controller.handleToggleCollectionExpanded(collection, expand) controller.handleToggleCollectionExpanded(collection, expand)
} }
override fun onAddTabsToCollectionTapped() {
controller.handleCreateCollection()
}
override fun onCloseTip(tip: Tip) { override fun onCloseTip(tip: Tip) {
controller.handleCloseTip(tip) controller.handleCloseTip(tip)
} }

View File

@ -19,11 +19,6 @@ import org.mozilla.fenix.home.Mode
import org.mozilla.fenix.home.OnboardingState import org.mozilla.fenix.home.OnboardingState
import org.mozilla.fenix.components.tips.Tip import org.mozilla.fenix.components.tips.Tip
val noCollectionMessage = AdapterItem.NoContentMessage(
R.string.no_collections_header1,
R.string.no_collections_description1
)
// This method got a little complex with the addition of the tab tray feature flag // This method got a little complex with the addition of the tab tray feature flag
// When we remove the tabs from the home screen this will get much simpler again. // When we remove the tabs from the home screen this will get much simpler again.
@SuppressWarnings("LongParameterList", "ComplexMethod") @SuppressWarnings("LongParameterList", "ComplexMethod")
@ -43,7 +38,7 @@ private fun normalModeAdapterItems(
if (collections.isEmpty()) { if (collections.isEmpty()) {
items.add(AdapterItem.CollectionHeader) items.add(AdapterItem.CollectionHeader)
items.add(noCollectionMessage) items.add(AdapterItem.NoCollectionsMessage)
} else { } else {
showCollections(collections, expandedCollections, items) showCollections(collections, expandedCollections, items)
} }

View File

@ -0,0 +1,26 @@
/* 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.View
import kotlinx.android.synthetic.main.no_collections_message.view.*
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.ViewHolder
import org.mozilla.fenix.home.sessioncontrol.CollectionInteractor
open class NoCollectionsMessageViewHolder(
view: View,
interactor: CollectionInteractor
) : ViewHolder(view) {
init {
view.add_tabs_to_collections_button.setOnClickListener {
interactor.onAddTabsToCollectionTapped()
}
}
companion object {
const val LAYOUT_ID = R.layout.no_collections_message
}
}

View File

@ -1,28 +0,0 @@
/* 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.View
import androidx.annotation.StringRes
import kotlinx.android.synthetic.main.no_content_message.*
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.ViewHolder
open class NoContentMessageViewHolder(view: View) : ViewHolder(view) {
fun bind(
@StringRes header: Int,
@StringRes description: Int
) {
with(itemView.context) {
no_content_header.text = getString(header)
no_content_description.text = getString(description)
}
}
companion object {
const val LAYOUT_ID = R.layout.no_content_message
}
}

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/no_collections_wrapper"
android:background="@drawable/empty_session_control_background"
android:layout_marginBottom="12dp"
android:padding="16dp"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/no_collections_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/no_collections_header1"
tools:drawableEnd="@drawable/ic_tab_collection"
android:textAppearance="@style/HeaderTextStyle"
android:textSize="16sp"
app:fontFamily="@font/metropolis_semibold" />
<TextView
android:id="@+id/no_collections_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="@string/no_collections_description1"
android:textColor="?primaryText"
android:textSize="14sp"
android:textAlignment="viewStart"
app:fontFamily="@font/metropolis_medium" />
<com.google.android.material.button.MaterialButton
android:id="@+id/add_tabs_to_collections_button"
style="@style/PositiveButton"
app:icon="@drawable/ic_tab_collection"
android:text="@string/tabs_menu_save_to_collection1"
android:layout_marginTop="8dp"/>
</LinearLayout>

View File

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/no_content_wrapper"
android:background="@drawable/empty_session_control_background"
android:layout_marginBottom="12dp"
android:padding="16dp"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/no_content_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="@tools:sample/lorem"
tools:drawableEnd="@drawable/ic_tab_collection"
android:textAppearance="@style/HeaderTextStyle"
android:textSize="16sp"
app:fontFamily="@font/metropolis_semibold" />
<TextView
android:id="@+id/no_content_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
tools:text="@tools:sample/lorem"
android:textColor="?primaryText"
android:textSize="14sp"
android:textAlignment="viewStart"
app:fontFamily="@font/metropolis_medium" />
</LinearLayout>

View File

@ -1,44 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!-- 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/. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/no_content_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:background="@drawable/empty_session_control_background"
android:orientation="vertical"
android:padding="8dp">
<TextView
android:id="@+id/no_content_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
android:textAppearance="@style/HeaderTextStyle"
android:textSize="16sp"
tools:text="@tools:sample/lorem" />
<TextView
android:id="@+id/no_content_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:textAlignment="viewStart"
android:textColor="?primaryText"
android:textSize="14sp"
android:textStyle="normal"
tools:text="@tools:sample/lorem" />
<com.google.android.material.button.MaterialButton
android:id="@+id/add_new_tab_button"
style="@style/NeutralButton"
android:layout_marginTop="6dp"
android:visibility="gone"
tools:icon="@drawable/ic_new"
tools:text="@string/home_screen_shortcut_open_new_tab_2"
tools:visibility="visible" />
</LinearLayout>

View File

@ -24,10 +24,13 @@ import org.junit.Before
import org.junit.Test import org.junit.Test
import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.collections.SaveCollectionStep
import org.mozilla.fenix.components.TabCollectionStorage import org.mozilla.fenix.components.TabCollectionStorage
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.MetricController import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.home.sessioncontrol.DefaultSessionControlController import org.mozilla.fenix.home.sessioncontrol.DefaultSessionControlController
import org.mozilla.fenix.settings.SupportUtils import org.mozilla.fenix.settings.SupportUtils
import mozilla.components.feature.tab.collections.Tab as ComponentTab import mozilla.components.feature.tab.collections.Tab as ComponentTab
@ -204,4 +207,11 @@ class DefaultSessionControlControllerTest {
controller.handleToggleCollectionExpanded(collection, true) controller.handleToggleCollectionExpanded(collection, true)
verify { fragmentStore.dispatch(HomeFragmentAction.CollectionExpanded(collection, true)) } verify { fragmentStore.dispatch(HomeFragmentAction.CollectionExpanded(collection, true)) }
} }
@Test
fun handleCreateCollection() {
controller.handleCreateCollection()
val directions = HomeFragmentDirections.actionGlobalCollectionCreationFragment(saveCollectionStep = SaveCollectionStep.SelectTabs)
verify { navController.nav(R.id.homeFragment, directions) }
}
} }

View File

@ -92,4 +92,10 @@ class SessionControlInteractorTest {
interactor.onToggleCollectionExpanded(collection, true) interactor.onToggleCollectionExpanded(collection, true)
verify { controller.handleToggleCollectionExpanded(collection, true) } verify { controller.handleToggleCollectionExpanded(collection, true) }
} }
@Test
fun onAddTabsToCollection() {
interactor.onAddTabsToCollectionTapped()
verify { controller.handleCreateCollection() }
}
} }