1
0
Fork 0

For #2977 - Update add new collections flow (#2991)

* For #2977 - Update add new collections flow

* Rename shared elements to be more general

* Make tab list not clickable in other modes

* For #2577 - Stop Flickering in List

* Add extensions function for next step with collections list size
master
Emily Kager 2019-05-31 10:59:51 -07:00 committed by Colin Lee
parent f48db90716
commit 0327b1146b
12 changed files with 248 additions and 187 deletions

View File

@ -62,6 +62,7 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.ThemeManager import org.mozilla.fenix.ThemeManager
import org.mozilla.fenix.collections.CreateCollectionViewModel import org.mozilla.fenix.collections.CreateCollectionViewModel
import org.mozilla.fenix.collections.SaveCollectionStep import org.mozilla.fenix.collections.SaveCollectionStep
import org.mozilla.fenix.collections.getStepForCollectionsSize
import org.mozilla.fenix.components.FenixSnackbar import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.FindInPageIntegration import org.mozilla.fenix.components.FindInPageIntegration
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
@ -698,8 +699,9 @@ class BrowserFragment : Fragment(), BackHandler, CoroutineScope {
viewModel?.tabs = listOf(tabs) viewModel?.tabs = listOf(tabs)
val selectedSet = mutableSetOf(tabs) val selectedSet = mutableSetOf(tabs)
viewModel?.selectedTabs = selectedSet viewModel?.selectedTabs = selectedSet
viewModel?.saveCollectionStep = SaveCollectionStep.SelectCollection
viewModel?.tabCollections = requireComponents.core.tabCollectionStorage.cachedTabCollections.reversed() viewModel?.tabCollections = requireComponents.core.tabCollectionStorage.cachedTabCollections.reversed()
viewModel?.saveCollectionStep =
viewModel?.tabCollections?.getStepForCollectionsSize() ?: SaveCollectionStep.SelectCollection
viewModel?.snackbarAnchorView = nestedScrollQuickAction viewModel?.snackbarAnchorView = nestedScrollQuickAction
view?.let { view?.let {
val directions = BrowserFragmentDirections.actionBrowserFragmentToCreateCollectionFragment() val directions = BrowserFragmentDirections.actionBrowserFragmentToCreateCollectionFragment()

View File

@ -7,7 +7,6 @@ package org.mozilla.fenix.collections
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.CompoundButton
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import io.reactivex.Observer import io.reactivex.Observer
@ -25,9 +24,8 @@ import kotlin.coroutines.CoroutineContext
class CollectionCreationTabListAdapter( class CollectionCreationTabListAdapter(
val actionEmitter: Observer<CollectionCreationAction> val actionEmitter: Observer<CollectionCreationAction>
) : RecyclerView.Adapter<TabViewHolder>() { ) : RecyclerView.Adapter<TabViewHolder>() {
private var tabs: List<Tab> = listOf() private var tabs: List<Tab> = listOf()
private var selectedTabs: Set<Tab> = setOf() private var selectedTabs: MutableSet<Tab> = mutableSetOf()
private lateinit var job: Job private lateinit var job: Job
private var hideCheckboxes = false private var hideCheckboxes = false
@ -35,13 +33,40 @@ class CollectionCreationTabListAdapter(
val view = val view =
LayoutInflater.from(parent.context).inflate(TabViewHolder.LAYOUT_ID, parent, false) LayoutInflater.from(parent.context).inflate(TabViewHolder.LAYOUT_ID, parent, false)
return TabViewHolder(view, actionEmitter, job) return TabViewHolder(view, job)
}
override fun onBindViewHolder(holder: TabViewHolder, position: Int, payloads: MutableList<Any>) {
if (payloads.isEmpty()) {
super.onBindViewHolder(holder, position, payloads)
} else {
when (payloads[0]) {
is CheckChanged -> {
val checkChanged = payloads[0] as CheckChanged
if (checkChanged.shouldBeChecked) {
holder.view.tab_selected_checkbox.isChecked = true
} else if (checkChanged.shouldBeUnchecked) {
holder.view.tab_selected_checkbox.isChecked = false
}
}
}
}
} }
override fun onBindViewHolder(holder: TabViewHolder, position: Int) { override fun onBindViewHolder(holder: TabViewHolder, position: Int) {
val tab = tabs[position] val tab = tabs[position]
val isSelected = selectedTabs.contains(tab) val isSelected = selectedTabs.contains(tab)
holder.bind(tab, isSelected, hideCheckboxes) holder.bind(tab, isSelected, hideCheckboxes)
holder.view.tab_selected_checkbox.setOnCheckedChangeListener { _, isChecked ->
val action = if (isChecked) {
selectedTabs.add(tab)
CollectionCreationAction.AddTabToSelection(tab)
} else {
selectedTabs.remove(tab)
CollectionCreationAction.RemoveTabFromSelection(tab)
}
actionEmitter.onNext(action)
}
} }
override fun getItemCount(): Int = tabs.size override fun getItemCount(): Int = tabs.size
@ -69,7 +94,7 @@ class CollectionCreationTabListAdapter(
) )
this.tabs = tabs this.tabs = tabs
this.selectedTabs = selectedTabs this.selectedTabs = selectedTabs.toMutableSet()
this.hideCheckboxes = hideCheckboxes this.hideCheckboxes = hideCheckboxes
diffUtil.dispatchUpdatesTo(this) diffUtil.dispatchUpdatesTo(this)
@ -88,20 +113,27 @@ private class TabDiffUtil(
old[oldItemPosition].sessionId == new[newItemPosition].sessionId old[oldItemPosition].sessionId == new[newItemPosition].sessionId
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
val isSameTab = old[oldItemPosition].url == new[newItemPosition].url val isSameTab = old[oldItemPosition].sessionId == new[newItemPosition].sessionId
val sameSelectedState = val sameSelectedState = oldSelected.contains(old[oldItemPosition]) == newSelected.contains(new[newItemPosition])
oldSelected.contains(old[oldItemPosition]) == newSelected.contains(new[newItemPosition])
val isSameHideCheckboxes = oldHideCheckboxes == newHideCheckboxes val isSameHideCheckboxes = oldHideCheckboxes == newHideCheckboxes
return isSameTab && sameSelectedState && isSameHideCheckboxes return isSameTab && sameSelectedState && isSameHideCheckboxes
} }
override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? {
val shouldBeChecked = newSelected.contains(new[newItemPosition]) && !oldSelected.contains(old[oldItemPosition])
val shouldBeUnchecked =
!newSelected.contains(new[newItemPosition]) && oldSelected.contains(old[oldItemPosition])
return CheckChanged(shouldBeChecked, shouldBeUnchecked)
}
override fun getOldListSize(): Int = old.size override fun getOldListSize(): Int = old.size
override fun getNewListSize(): Int = new.size override fun getNewListSize(): Int = new.size
} }
data class CheckChanged(val shouldBeChecked: Boolean, val shouldBeUnchecked: Boolean)
class TabViewHolder( class TabViewHolder(
val view: View, val view: View,
actionEmitter: Observer<CollectionCreationAction>,
val job: Job val job: Job
) : ) :
RecyclerView.ViewHolder(view), CoroutineScope { RecyclerView.ViewHolder(view), CoroutineScope {
@ -111,14 +143,6 @@ class TabViewHolder(
private var tab: Tab? = null private var tab: Tab? = null
private val checkbox = view.tab_selected_checkbox!! private val checkbox = view.tab_selected_checkbox!!
private val checkboxListener = CompoundButton.OnCheckedChangeListener { _, isChecked ->
tab?.apply {
val action = if (isChecked) CollectionCreationAction.AddTabToSelection(this)
else CollectionCreationAction.RemoveTabFromSelection(this)
actionEmitter.onNext(action)
}
}
init { init {
view.collection_item_tab.setOnClickListener { view.collection_item_tab.setOnClickListener {
@ -128,16 +152,13 @@ class TabViewHolder(
fun bind(tab: Tab, isSelected: Boolean, shouldHideCheckBox: Boolean) { fun bind(tab: Tab, isSelected: Boolean, shouldHideCheckBox: Boolean) {
this.tab = tab this.tab = tab
view.hostname.text = tab.hostname view.hostname.text = tab.hostname
view.tab_title.text = tab.title view.tab_title.text = tab.title
checkbox.visibility = if (shouldHideCheckBox) View.INVISIBLE else View.VISIBLE checkbox.visibility = if (shouldHideCheckBox) View.INVISIBLE else View.VISIBLE
view.isClickable = !shouldHideCheckBox view.isClickable = !shouldHideCheckBox
checkbox.setOnCheckedChangeListener(null)
if (checkbox.isChecked != isSelected) { if (checkbox.isChecked != isSelected) {
checkbox.isChecked = isSelected checkbox.isChecked = isSelected
} }
checkbox.setOnCheckedChangeListener(checkboxListener)
launch(Dispatchers.IO) { launch(Dispatchers.IO) {
val bitmap = view.favicon_image.context.components.core.icons val bitmap = view.favicon_image.context.components.core.icons

View File

@ -11,6 +11,7 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.inputmethod.EditorInfo import android.view.inputmethod.EditorInfo
import androidx.constraintlayout.widget.ConstraintSet import androidx.constraintlayout.widget.ConstraintSet
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.transition.AutoTransition import androidx.transition.AutoTransition
@ -67,15 +68,12 @@ class CollectionCreationUIView(
R.layout.component_collection_creation_name_collection R.layout.component_collection_creation_name_collection
) )
view.close_icon.apply { view.bottom_bar_icon_button.apply {
increaseTapArea(increaseButtonByDps) increaseTapArea(increaseButtonByDps)
setOnClickListener {
actionEmitter.onNext(CollectionCreationAction.Close)
}
} }
view.name_collection_edittext.setOnEditorActionListener { v, actionId, _ -> view.name_collection_edittext.setOnEditorActionListener { v, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE && !v.text.toString().isEmpty()) { if (actionId == EditorInfo.IME_ACTION_DONE && v.text.toString().isNotEmpty()) {
when (step) { when (step) {
is SaveCollectionStep.NameCollection -> { is SaveCollectionStep.NameCollection -> {
actionEmitter.onNext( actionEmitter.onNext(
@ -95,10 +93,6 @@ class CollectionCreationUIView(
false false
} }
view.add_collection_button.setOnClickListener {
actionEmitter.onNext(CollectionCreationAction.AddNewCollection)
}
view.tab_list.run { view.tab_list.run {
adapter = collectionCreationTabListAdapter adapter = collectionCreationTabListAdapter
layoutManager = LinearLayoutManager(container.context, RecyclerView.VERTICAL, true) layoutManager = LinearLayoutManager(container.context, RecyclerView.VERTICAL, true)
@ -118,6 +112,8 @@ class CollectionCreationUIView(
when (it.saveCollectionStep) { when (it.saveCollectionStep) {
is SaveCollectionStep.SelectTabs -> { is SaveCollectionStep.SelectTabs -> {
view.tab_list.isClickable = true
back_button.setOnClickListener { back_button.setOnClickListener {
actionEmitter.onNext(CollectionCreationAction.BackPressed(SaveCollectionStep.SelectTabs)) actionEmitter.onNext(CollectionCreationAction.BackPressed(SaveCollectionStep.SelectTabs))
} }
@ -134,6 +130,18 @@ class CollectionCreationUIView(
actionEmitter.onNext(CollectionCreationAction.SelectAllTapped) actionEmitter.onNext(CollectionCreationAction.SelectAllTapped)
} }
} }
view.bottom_button_bar_layout.setOnClickListener(null)
view.bottom_button_bar_layout.isClickable = false
val drawable = view.context.getDrawable(R.drawable.ic_close)
drawable?.setTint(ContextCompat.getColor(view.context, R.color.photonWhite))
view.bottom_bar_icon_button.setImageDrawable(drawable)
view.bottom_bar_icon_button.setOnClickListener {
actionEmitter.onNext(CollectionCreationAction.Close)
}
TransitionManager.beginDelayedTransition( TransitionManager.beginDelayedTransition(
view.collection_constraint_layout, view.collection_constraint_layout,
transition transition
@ -156,7 +164,7 @@ class CollectionCreationUIView(
) )
} }
view.select_tabs_layout_text.text = selectTabsText view.bottom_bar_text.text = selectTabsText
save_button.setOnClickListener { _ -> save_button.setOnClickListener { _ ->
if (selectedCollection != null) { if (selectedCollection != null) {
@ -178,8 +186,22 @@ class CollectionCreationUIView(
} }
} }
is SaveCollectionStep.SelectCollection -> { is SaveCollectionStep.SelectCollection -> {
// Only show selected tabs and hide checkboxes view.tab_list.isClickable = false
collectionCreationTabListAdapter.updateData(it.selectedTabs.toList(), setOf(), true)
save_button.visibility = View.GONE
view.bottom_bar_text.text =
view.context.getString(R.string.create_collection_add_new_collection)
val drawable = view.context.getDrawable(R.drawable.ic_new)
drawable?.setTint(ContextCompat.getColor(view.context, R.color.photonWhite))
view.bottom_bar_icon_button.setImageDrawable(drawable)
view.bottom_bar_icon_button.setOnClickListener(null)
view.bottom_button_bar_layout.isClickable = true
view.bottom_button_bar_layout.setOnClickListener {
actionEmitter.onNext(CollectionCreationAction.AddNewCollection)
}
back_button.setOnClickListener { back_button.setOnClickListener {
actionEmitter.onNext(CollectionCreationAction.BackPressed(SaveCollectionStep.SelectCollection)) actionEmitter.onNext(CollectionCreationAction.BackPressed(SaveCollectionStep.SelectCollection))
@ -194,6 +216,9 @@ class CollectionCreationUIView(
view.context.getString(R.string.create_collection_select_collection) view.context.getString(R.string.create_collection_select_collection)
} }
is SaveCollectionStep.NameCollection -> { is SaveCollectionStep.NameCollection -> {
view.tab_list.isClickable = false
collectionCreationTabListAdapter.updateData(it.selectedTabs.toList(), it.selectedTabs, true)
back_button.setOnClickListener { back_button.setOnClickListener {
name_collection_edittext.hideKeyboard() name_collection_edittext.hideKeyboard()
val handler = Handler() val handler = Handler()
@ -231,6 +256,8 @@ class CollectionCreationUIView(
view.context.getString(R.string.create_collection_name_collection) view.context.getString(R.string.create_collection_name_collection)
} }
is SaveCollectionStep.RenameCollection -> { is SaveCollectionStep.RenameCollection -> {
view.tab_list.isClickable = false
it.selectedTabCollection?.let { tabCollection -> it.selectedTabCollection?.let { tabCollection ->
tabCollection.tabs.map { tab -> tabCollection.tabs.map { tab ->
Tab( Tab(
@ -240,7 +267,7 @@ class CollectionCreationUIView(
tab.title tab.title
) )
}.let { tabs -> }.let { tabs ->
collectionCreationTabListAdapter.updateData(tabs, setOf(), true) collectionCreationTabListAdapter.updateData(tabs, tabs.toSet(), true)
} }
} }

View File

@ -62,13 +62,15 @@ class CreateCollectionFragment : DialogFragment(), CoroutineScope {
this, this,
CollectionCreationViewModel::class.java CollectionCreationViewModel::class.java
) { ) {
CollectionCreationViewModel(CollectionCreationState( CollectionCreationViewModel(
viewModel.tabs, CollectionCreationState(
viewModel.selectedTabs, viewModel.tabs,
viewModel.saveCollectionStep, viewModel.selectedTabs,
viewModel.tabCollections, viewModel.saveCollectionStep,
viewModel.selectedTabCollection viewModel.tabCollections,
)) viewModel.selectedTabCollection
)
)
} }
) )
return view return view
@ -100,7 +102,11 @@ class CreateCollectionFragment : DialogFragment(), CoroutineScope {
is CollectionCreationAction.Close -> dismiss() is CollectionCreationAction.Close -> dismiss()
is CollectionCreationAction.SaveTabsToCollection -> { is CollectionCreationAction.SaveTabsToCollection -> {
getManagedEmitter<CollectionCreationChange>() getManagedEmitter<CollectionCreationChange>()
.onNext(CollectionCreationChange.StepChanged(SaveCollectionStep.SelectCollection)) .onNext(
CollectionCreationChange.StepChanged(
viewModel.tabCollections.getStepForCollectionsSize()
)
)
} }
is CollectionCreationAction.AddTabToSelection -> { is CollectionCreationAction.AddTabToSelection -> {
getManagedEmitter<CollectionCreationChange>() getManagedEmitter<CollectionCreationChange>()
@ -189,11 +195,16 @@ class CreateCollectionFragment : DialogFragment(), CoroutineScope {
CollectionCreationChange.StepChanged(SaveCollectionStep.SelectTabs) CollectionCreationChange.StepChanged(SaveCollectionStep.SelectTabs)
) )
SaveCollectionStep.NameCollection -> { SaveCollectionStep.NameCollection -> {
getManagedEmitter<CollectionCreationChange>().onNext( getManagedEmitter<CollectionCreationChange>()
CollectionCreationChange.StepChanged(SaveCollectionStep.SelectCollection) .onNext(
) CollectionCreationChange.StepChanged(
viewModel.tabCollections.getStepForCollectionsSize()
)
)
}
SaveCollectionStep.RenameCollection -> {
dismiss()
} }
SaveCollectionStep.RenameCollection -> { dismiss() }
} }
} }
} }

View File

@ -17,3 +17,6 @@ class CreateCollectionViewModel : ViewModel() {
var selectedTabCollection: TabCollection? = null var selectedTabCollection: TabCollection? = null
var snackbarAnchorView: View? = null var snackbarAnchorView: View? = null
} }
fun List<TabCollection>.getStepForCollectionsSize(): SaveCollectionStep =
if (isEmpty()) SaveCollectionStep.NameCollection else SaveCollectionStep.SelectCollection

View File

@ -7,13 +7,17 @@ package org.mozilla.fenix.collections
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import io.reactivex.Observer import io.reactivex.Observer
import kotlinx.android.synthetic.main.collections_list_item.view.* import kotlinx.android.synthetic.main.collections_list_item.view.*
import kotlinx.android.synthetic.main.collections_list_item.view.collection_description
import kotlinx.android.synthetic.main.collections_list_item.view.collection_icon
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.ext.urlToTrimmedHost
import org.mozilla.fenix.home.sessioncontrol.Tab import org.mozilla.fenix.home.sessioncontrol.Tab
import org.mozilla.fenix.home.sessioncontrol.TabCollection import org.mozilla.fenix.home.sessioncontrol.TabCollection
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
@ -78,9 +82,46 @@ class CollectionViewHolder(
fun bind(collection: TabCollection) { fun bind(collection: TabCollection) {
this.collection = collection this.collection = collection
view.collection_item.text = collection.title view.collection_item.text = collection.title
val hostNameList = collection.tabs.map { it.url.urlToTrimmedHost().capitalize() }
var tabsDisplayed = 0
val tabTitlesList = hostNameList.joinToString(", ") {
if (it.length > maxTitleLength) {
it.substring(
0,
maxTitleLength
) + "..."
} else {
tabsDisplayed += 1
it
}
}
view.collection_description.text = tabTitlesList
view.collection_icon.setColorFilter(
ContextCompat.getColor(
view.context,
getIconColor(collection.id)
),
android.graphics.PorterDuff.Mode.SRC_IN
)
}
@Suppress("ComplexMethod", "MagicNumber")
private fun getIconColor(id: Long): Int {
return when ((id % 4).toInt()) {
0 -> R.color.collection_icon_color_violet
1 -> R.color.collection_icon_color_blue
2 -> R.color.collection_icon_color_pink
3 -> R.color.collection_icon_color_green
4 -> R.color.collection_icon_color_yellow
else -> R.color.white_color
}
} }
companion object { companion object {
const val LAYOUT_ID = R.layout.collections_list_item const val LAYOUT_ID = R.layout.collections_list_item
const val maxTitleLength = 20
} }
} }

View File

@ -2,9 +2,9 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public <!-- 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 - 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/. --> - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<LinearLayout <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/item_collection" android:id="@+id/item_collection"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -34,7 +34,7 @@
<TextView <TextView
android:id="@+id/collection_title" android:id="@+id/collection_title"
android:layout_width="0dp" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="12dp" android:layout_marginStart="12dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
@ -42,23 +42,23 @@
android:gravity="start" android:gravity="start"
android:maxLines="1" android:maxLines="1"
android:minLines="1" android:minLines="1"
android:text="The quick brown fox jumped over the lazy dog"
android:textAppearance="@style/Header16TextStyle" android:textAppearance="@style/Header16TextStyle"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toStartOf="@id/chevron" app:layout_constraintEnd_toStartOf="@id/chevron"
app:layout_constraintHorizontal_bias="0.0" app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintHorizontal_chainStyle="packed" app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toEndOf="@+id/collection_icon" app:layout_constraintStart_toEndOf="@+id/collection_icon"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="wrap" /> tools:text="@tools:sample/lorem/random" />
<ImageView <ImageView
android:id="@+id/chevron" android:id="@+id/chevron"
android:layout_width="10dp" android:layout_width="10dp"
android:layout_height="6dp" android:layout_height="6dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:background="@drawable/ic_chevron_down" android:background="@drawable/ic_chevron_down"
android:contentDescription="@string/tab_menu" android:contentDescription="@string/tab_menu"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toStartOf="@+id/collection_share_button" app:layout_constraintEnd_toStartOf="@+id/collection_share_button"
app:layout_constraintStart_toEndOf="@+id/collection_title" app:layout_constraintStart_toEndOf="@+id/collection_title"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
@ -76,7 +76,8 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/collection_share_button" app:layout_constraintEnd_toStartOf="@id/collection_share_button"
app:layout_constraintStart_toStartOf="@id/collection_title" app:layout_constraintStart_toStartOf="@id/collection_title"
app:layout_constraintTop_toBottomOf="@id/collection_share_button" /> app:layout_constraintTop_toBottomOf="@id/collection_share_button"
tools:text="@tools:sample/lorem/random" />
<ImageButton <ImageButton
android:id="@+id/collection_share_button" android:id="@+id/collection_share_button"

View File

@ -44,7 +44,6 @@
android:textColor="?secondaryText" android:textColor="?secondaryText"
android:textSize="12sp" android:textSize="12sp"
android:textStyle="bold" android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@id/close_tab_button"
app:layout_constraintStart_toEndOf="@id/favicon_image" app:layout_constraintStart_toEndOf="@id/favicon_image"
app:layout_constraintTop_toTopOf="@id/favicon_image" /> app:layout_constraintTop_toTopOf="@id/favicon_image" />

View File

@ -1,35 +1,66 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public <!-- 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 - 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/. --> - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/collection_item_tab"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:foreground="?android:attr/selectableItemBackground"> android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:clickable="true"
android:clipToPadding="false"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
app:cardBackgroundColor="?above"
app:cardCornerRadius="@dimen/tab_corner_radius"
app:cardElevation="5dp">
<TextView <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/collection_item"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?foundation" android:layout_margin="16dp">
android:drawableStart="@drawable/ic_tab_collection"
android:drawablePadding="14dp"
android:drawableTint="?accent"
android:paddingStart="20dp"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:textColor="?primaryText"
android:textSize="16sp"
app:layout_constraintBottom_toTopOf="@+id/divider"
app:layout_constraintTop_toTopOf="parent"
tools:targetApi="m" />
<View <ImageView
android:id="@+id/divider" android:id="@+id/collection_icon"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="1dp" android:layout_height="wrap_content"
android:background="?neutralFaded" android:importantForAccessibility="no"
app:layout_constraintBottom_toBottomOf="parent" /> android:src="@drawable/ic_tab_collection"
</androidx.constraintlayout.widget.ConstraintLayout> android:tint="@null"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/collection_item"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:ellipsize="end"
android:gravity="start"
android:maxLines="1"
android:minLines="1"
android:textAppearance="@style/Header16TextStyle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/collection_icon"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/lorem/random" />
<TextView
android:id="@+id/collection_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:ellipsize="end"
android:maxLines="2"
android:minLines="2"
android:textAppearance="@style/SubtitleTextStyle"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/collection_item"
app:layout_constraintStart_toStartOf="@+id/collection_item"
app:layout_constraintTop_toBottomOf="@+id/collection_item"
tools:text="@tools:sample/lorem/random" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

View File

@ -44,38 +44,11 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:visibility="gone" android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/add_collection_button" app:layout_constraintBottom_toTopOf="@id/bottom_button_bar_layout"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/back_button"/> app:layout_constraintTop_toBottomOf="@id/back_button"/>
<TextView
android:id="@+id/add_collection_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?foundation"
android:foreground="?android:attr/selectableItemBackground"
android:drawableStart="@drawable/ic_new"
android:drawablePadding="14dp"
android:drawableTint="?accent"
android:paddingStart="20dp"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:text="@string/create_collection_add_new_collection"
android:textColor="?primaryText"
android:textSize="16sp"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/divider"
tools:targetApi="m" />
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?neutralFaded"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent" />
<EditText <EditText
android:id="@+id/name_collection_edittext" android:id="@+id/name_collection_edittext"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -105,7 +78,7 @@
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
app:layout_constraintBottom_toTopOf="@id/add_tabs_layout" app:layout_constraintBottom_toTopOf="@id/bottom_button_bar_layout"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/back_button" /> app:layout_constraintTop_toBottomOf="@id/back_button" />
@ -123,10 +96,11 @@
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/add_tabs_layout" android:id="@+id/bottom_button_bar_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="16dp" android:layout_margin="16dp"
android:foreground="@drawable/rounded_ripple"
android:background="@drawable/add_tabs_to_collection_background" android:background="@drawable/add_tabs_to_collection_background"
android:clipToPadding="false" android:clipToPadding="false"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
@ -134,7 +108,7 @@
app:layout_constraintStart_toStartOf="parent"> app:layout_constraintStart_toStartOf="parent">
<ImageButton <ImageButton
android:id="@+id/close_icon" android:id="@+id/bottom_bar_icon_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="16dp" android:layout_margin="16dp"
@ -147,7 +121,7 @@
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<TextView <TextView
android:id="@+id/select_tabs_layout_text" android:id="@+id/bottom_bar_text"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
@ -160,7 +134,7 @@
android:textStyle="bold" android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/save_button" app:layout_constraintEnd_toStartOf="@id/save_button"
app:layout_constraintStart_toEndOf="@id/close_icon" app:layout_constraintStart_toEndOf="@id/bottom_bar_icon_button"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<Button <Button

View File

@ -45,33 +45,7 @@
android:id="@+id/collections_list" android:id="@+id/collections_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:visibility="gone" android:alpha="0.0"
app:layout_constraintBottom_toTopOf="@+id/add_collection_button" />
<TextView
android:id="@+id/add_collection_button"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="?foundation"
android:foreground="?android:attr/selectableItemBackground"
android:drawableStart="@drawable/ic_new"
android:drawablePadding="14dp"
android:drawableTint="?accent"
android:paddingStart="20dp"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:text="@string/create_collection_add_new_collection"
android:textColor="?primaryText"
android:textSize="16sp"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/divider"
tools:targetApi="m" />
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?neutralFaded"
android:visibility="gone" android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent" /> app:layout_constraintBottom_toBottomOf="parent" />
@ -125,7 +99,7 @@
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/add_tabs_layout" android:id="@+id/bottom_button_bar_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="16dp" android:layout_margin="16dp"
@ -138,7 +112,7 @@
app:layout_constraintStart_toStartOf="parent"> app:layout_constraintStart_toStartOf="parent">
<ImageButton <ImageButton
android:id="@+id/close_icon" android:id="@+id/bottom_bar_icon_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="16dp" android:layout_margin="16dp"
@ -151,7 +125,7 @@
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<TextView <TextView
android:id="@+id/select_tabs_layout_text" android:id="@+id/bottom_bar_text"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
@ -164,7 +138,7 @@
android:textStyle="bold" android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/save_button" app:layout_constraintEnd_toStartOf="@id/save_button"
app:layout_constraintStart_toEndOf="@id/close_icon" app:layout_constraintStart_toEndOf="@id/bottom_bar_icon_button"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<Button <Button

View File

@ -44,43 +44,18 @@
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/collections_list" android:id="@+id/collections_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:alpha="1" android:alpha="1"
android:background="?foundation" android:background="?foundation"
android:fadingEdgeLength="30dp"
android:visibility="visible" android:visibility="visible"
app:layout_constraintBottom_toTopOf="@id/add_collection_button" app:layout_constraintBottom_toTopOf="@+id/bottom_button_bar_layout"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/> app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/back_button" />
<TextView
android:id="@+id/add_collection_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:alpha="1"
android:background="?foundation"
android:foreground="?android:attr/selectableItemBackground"
android:drawableStart="@drawable/ic_new"
android:drawablePadding="14dp"
android:drawableTint="?accent"
android:paddingStart="20dp"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:text="@string/create_collection_add_new_collection"
android:textColor="?primaryText"
android:textSize="16sp"
android:visibility="visible"
app:layout_constraintBottom_toTopOf="@id/divider"
tools:targetApi="m" />
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:elevation="5dp"
android:alpha="1"
android:background="?neutralFaded"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent" />
<EditText <EditText
android:id="@+id/name_collection_edittext" android:id="@+id/name_collection_edittext"
@ -114,7 +89,8 @@
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:fadingEdgeLength="30dp" android:fadingEdgeLength="30dp"
android:requiresFadingEdge="vertical" android:requiresFadingEdge="vertical"
app:layout_constraintBottom_toTopOf="@id/collections_list" android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/bottom_button_bar_layout"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/back_button" /> app:layout_constraintTop_toBottomOf="@id/back_button" />
@ -123,65 +99,66 @@
android:id="@+id/tab_list_dim" android:id="@+id/tab_list_dim"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:alpha="0.5"
android:background="@drawable/scrim_background" android:background="@drawable/scrim_background"
android:visibility="visible" android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/collections_list" app:layout_constraintBottom_toTopOf="@id/collections_list"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/add_tabs_layout" android:id="@+id/bottom_button_bar_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="16dp" android:layout_margin="16dp"
android:alpha="0" android:alpha="1.0"
android:background="@drawable/add_tabs_to_collection_background" android:background="@drawable/add_tabs_to_collection_background"
android:clipToPadding="false" android:clipToPadding="false"
android:visibility="gone" android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"> app:layout_constraintStart_toStartOf="parent">
<ImageButton <ImageButton
android:id="@+id/close_icon" android:id="@+id/bottom_bar_icon_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="16dp" android:layout_margin="16dp"
android:background="?android:attr/selectableItemBackground" android:background="?android:attr/selectableItemBackground"
android:contentDescription="@string/create_collection_close" android:contentDescription="@string/create_collection_close"
android:src="@drawable/mozac_ic_close" android:src="@drawable/ic_new"
android:tint="?neutral" android:tint="?neutral"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<TextView <TextView
android:id="@+id/select_tabs_layout_text" android:id="@+id/bottom_bar_text"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:gravity="center_vertical" android:gravity="center_vertical"
android:singleLine="true" android:singleLine="true"
android:text="@string/create_collection_save_to_collection_empty" android:text="@string/create_collection_add_new_collection"
android:textColor="?neutral" android:textColor="?neutral"
android:textSize="16sp" android:textSize="16sp"
android:textStyle="bold" android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/save_button" app:layout_constraintEnd_toStartOf="@id/save_button"
app:layout_constraintStart_toEndOf="@id/close_icon" app:layout_constraintStart_toEndOf="@id/bottom_bar_icon_button"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<Button <Button
android:id="@+id/save_button" android:id="@+id/save_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:alpha="0.0"
android:background="?android:attr/selectableItemBackground" android:background="?android:attr/selectableItemBackground"
android:text="@string/create_collection_save" android:text="@string/create_collection_save"
android:textAppearance="@style/TextAppearance.MaterialComponents.Button" android:textAppearance="@style/TextAppearance.MaterialComponents.Button"
android:textColor="?neutral" android:textColor="?neutral"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />