* Adds Keyboard resuming, Snackbar verification, layout edits to collections Adds Keyboard resuming, Snackbar verification, layout edits to collections * Adds new strings for collections/tabs management * Adds constraintsets, hides checkboxes, adds scrim * Update strings to pluralsmaster
parent
9a2cf4339b
commit
2953b54a84
|
@ -18,6 +18,7 @@ import android.view.accessibility.AccessibilityManager
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.ViewModelProviders
|
||||||
import androidx.navigation.Navigation
|
import androidx.navigation.Navigation
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import kotlinx.android.synthetic.main.component_search.*
|
import kotlinx.android.synthetic.main.component_search.*
|
||||||
|
@ -54,6 +55,10 @@ import org.mozilla.fenix.DefaultThemeManager
|
||||||
import org.mozilla.fenix.HomeActivity
|
import org.mozilla.fenix.HomeActivity
|
||||||
import org.mozilla.fenix.IntentReceiverActivity
|
import org.mozilla.fenix.IntentReceiverActivity
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.collections.CreateCollectionFragment
|
||||||
|
import org.mozilla.fenix.collections.CreateCollectionViewModel
|
||||||
|
import org.mozilla.fenix.collections.SaveCollectionStep
|
||||||
|
import org.mozilla.fenix.collections.Tab
|
||||||
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
|
||||||
|
@ -68,6 +73,7 @@ import org.mozilla.fenix.customtabs.CustomTabsIntegration
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
import org.mozilla.fenix.ext.share
|
import org.mozilla.fenix.ext.share
|
||||||
|
import org.mozilla.fenix.ext.urlToHost
|
||||||
import org.mozilla.fenix.lib.Do
|
import org.mozilla.fenix.lib.Do
|
||||||
import org.mozilla.fenix.mvi.ActionBusFactory
|
import org.mozilla.fenix.mvi.ActionBusFactory
|
||||||
import org.mozilla.fenix.mvi.getAutoDisposeObservable
|
import org.mozilla.fenix.mvi.getAutoDisposeObservable
|
||||||
|
@ -547,12 +553,10 @@ class BrowserFragment : Fragment(), BackHandler, CoroutineScope,
|
||||||
val directions = BrowserFragmentDirections
|
val directions = BrowserFragmentDirections
|
||||||
.actionBrowserFragmentToSearchFragment(null)
|
.actionBrowserFragmentToSearchFragment(null)
|
||||||
Navigation.findNavController(view!!).navigate(directions)
|
Navigation.findNavController(view!!).navigate(directions)
|
||||||
(activity as HomeActivity).browsingModeManager.mode = BrowsingModeManager.Mode.Normal
|
(activity as HomeActivity).browsingModeManager.mode =
|
||||||
}
|
BrowsingModeManager.Mode.Normal
|
||||||
ToolbarMenu.Item.SaveToCollection -> {
|
|
||||||
ItsNotBrokenSnack(requireContext())
|
|
||||||
.showSnackbar("1843")
|
|
||||||
}
|
}
|
||||||
|
ToolbarMenu.Item.SaveToCollection -> showSaveToCollection()
|
||||||
ToolbarMenu.Item.OpenInFenix -> {
|
ToolbarMenu.Item.OpenInFenix -> {
|
||||||
val intent = Intent(context, IntentReceiverActivity::class.java)
|
val intent = Intent(context, IntentReceiverActivity::class.java)
|
||||||
intent.action = Intent.ACTION_VIEW
|
intent.action = Intent.ACTION_VIEW
|
||||||
|
@ -562,6 +566,24 @@ class BrowserFragment : Fragment(), BackHandler, CoroutineScope,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun showSaveToCollection() {
|
||||||
|
getSessionById()?.let {
|
||||||
|
val tabs = Tab(it.id, it.url, it.url.urlToHost(), it.title)
|
||||||
|
val viewModel = activity?.run {
|
||||||
|
ViewModelProviders.of(this).get(CreateCollectionViewModel::class.java)
|
||||||
|
}
|
||||||
|
viewModel?.tabs = listOf(tabs)
|
||||||
|
val selectedSet = setOf(tabs)
|
||||||
|
viewModel?.selectedTabs = selectedSet
|
||||||
|
viewModel?.saveCollectionStep = SaveCollectionStep.SelectCollection
|
||||||
|
CreateCollectionFragment()
|
||||||
|
.show(
|
||||||
|
requireActivity().supportFragmentManager,
|
||||||
|
CreateCollectionFragment.createCollectionTag
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun assignSitePermissionsRules() {
|
private fun assignSitePermissionsRules() {
|
||||||
val settings = Settings.getInstance(requireContext())
|
val settings = Settings.getInstance(requireContext())
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ sealed class CollectionCreationChange : Change {
|
||||||
sealed class CollectionCreationAction : Action {
|
sealed class CollectionCreationAction : Action {
|
||||||
object Close : CollectionCreationAction()
|
object Close : CollectionCreationAction()
|
||||||
object SelectAllTapped : CollectionCreationAction()
|
object SelectAllTapped : CollectionCreationAction()
|
||||||
|
object AddNewCollection : CollectionCreationAction()
|
||||||
data class AddTabToSelection(val tab: Tab) : CollectionCreationAction()
|
data class AddTabToSelection(val tab: Tab) : CollectionCreationAction()
|
||||||
data class RemoveTabFromSelection(val tab: Tab) : CollectionCreationAction()
|
data class RemoveTabFromSelection(val tab: Tab) : CollectionCreationAction()
|
||||||
data class SaveTabsToCollection(val tabs: List<Tab>) : CollectionCreationAction()
|
data class SaveTabsToCollection(val tabs: List<Tab>) : CollectionCreationAction()
|
||||||
|
@ -56,8 +57,6 @@ sealed class CollectionCreationAction : Action {
|
||||||
|
|
||||||
data class SelectCollection(val collection: Collection) :
|
data class SelectCollection(val collection: Collection) :
|
||||||
CollectionCreationAction()
|
CollectionCreationAction()
|
||||||
|
|
||||||
data class AddNewCollection(val tabs: List<Tab>) : CollectionCreationAction()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class CollectionCreationComponent(
|
class CollectionCreationComponent(
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
package org.mozilla.fenix.collections
|
package org.mozilla.fenix.collections
|
||||||
|
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
@ -24,9 +28,11 @@ class CollectionCreationTabListAdapter(
|
||||||
private var tabs: List<Tab> = listOf()
|
private var tabs: List<Tab> = listOf()
|
||||||
private var selectedTabs: Set<Tab> = setOf()
|
private var selectedTabs: Set<Tab> = setOf()
|
||||||
private lateinit var job: Job
|
private lateinit var job: Job
|
||||||
|
private var hideCheckboxes = false
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TabViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TabViewHolder {
|
||||||
val view = LayoutInflater.from(parent.context).inflate(TabViewHolder.LAYOUT_ID, parent, false)
|
val view =
|
||||||
|
LayoutInflater.from(parent.context).inflate(TabViewHolder.LAYOUT_ID, parent, false)
|
||||||
|
|
||||||
return TabViewHolder(view, actionEmitter, job)
|
return TabViewHolder(view, actionEmitter, job)
|
||||||
}
|
}
|
||||||
|
@ -34,7 +40,7 @@ class CollectionCreationTabListAdapter(
|
||||||
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)
|
holder.bind(tab, isSelected, hideCheckboxes)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int = tabs.size
|
override fun getItemCount(): Int = tabs.size
|
||||||
|
@ -49,11 +55,21 @@ class CollectionCreationTabListAdapter(
|
||||||
job.cancel()
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateData(tabs: List<Tab>, selectedTabs: Set<Tab>) {
|
fun updateData(tabs: List<Tab>, selectedTabs: Set<Tab>, hideCheckboxes: Boolean = false) {
|
||||||
val diffUtil = DiffUtil.calculateDiff(TabDiffUtil(this.tabs, tabs, this.selectedTabs, selectedTabs))
|
val diffUtil = DiffUtil.calculateDiff(
|
||||||
|
TabDiffUtil(
|
||||||
|
this.tabs,
|
||||||
|
tabs,
|
||||||
|
this.selectedTabs,
|
||||||
|
selectedTabs,
|
||||||
|
this.hideCheckboxes,
|
||||||
|
hideCheckboxes
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
this.tabs = tabs
|
this.tabs = tabs
|
||||||
this.selectedTabs = selectedTabs
|
this.selectedTabs = selectedTabs
|
||||||
|
this.hideCheckboxes = hideCheckboxes
|
||||||
|
|
||||||
diffUtil.dispatchUpdatesTo(this)
|
diffUtil.dispatchUpdatesTo(this)
|
||||||
}
|
}
|
||||||
|
@ -63,15 +79,19 @@ private class TabDiffUtil(
|
||||||
val old: List<Tab>,
|
val old: List<Tab>,
|
||||||
val new: List<Tab>,
|
val new: List<Tab>,
|
||||||
val oldSelected: Set<Tab>,
|
val oldSelected: Set<Tab>,
|
||||||
val newSelected: Set<Tab>
|
val newSelected: Set<Tab>,
|
||||||
|
val oldHideCheckboxes: Boolean,
|
||||||
|
val newHideCheckboxes: Boolean
|
||||||
) : DiffUtil.Callback() {
|
) : DiffUtil.Callback() {
|
||||||
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
|
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
|
||||||
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].url == new[newItemPosition].url
|
||||||
val sameSelectedState = oldSelected.contains(old[oldItemPosition]) == newSelected.contains(new[newItemPosition])
|
val sameSelectedState =
|
||||||
return isSameTab && sameSelectedState
|
oldSelected.contains(old[oldItemPosition]) == newSelected.contains(new[newItemPosition])
|
||||||
|
val isSameHideCheckboxes = oldHideCheckboxes == newHideCheckboxes
|
||||||
|
return isSameTab && sameSelectedState && isSameHideCheckboxes
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getOldListSize(): Int = old.size
|
override fun getOldListSize(): Int = old.size
|
||||||
|
@ -105,11 +125,13 @@ class TabViewHolder(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bind(tab: Tab, isSelected: 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.GONE else View.VISIBLE
|
||||||
|
view.isClickable = !shouldHideCheckBox
|
||||||
checkbox.setOnCheckedChangeListener(null)
|
checkbox.setOnCheckedChangeListener(null)
|
||||||
if (checkbox.isChecked != isSelected) {
|
if (checkbox.isChecked != isSelected) {
|
||||||
checkbox.isChecked = isSelected
|
checkbox.isChecked = isSelected
|
||||||
|
|
|
@ -4,21 +4,25 @@ package org.mozilla.fenix.collections
|
||||||
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/. */
|
||||||
|
|
||||||
import android.content.Context.INPUT_METHOD_SERVICE
|
import android.os.Handler
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
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.view.inputmethod.EditorInfo
|
import android.view.inputmethod.EditorInfo
|
||||||
import android.view.inputmethod.InputMethodManager
|
import androidx.constraintlayout.widget.ConstraintSet
|
||||||
import android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT
|
|
||||||
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.Transition
|
||||||
|
import androidx.transition.TransitionManager
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import io.reactivex.Observer
|
import io.reactivex.Observer
|
||||||
import io.reactivex.functions.Consumer
|
import io.reactivex.functions.Consumer
|
||||||
import kotlinx.android.synthetic.main.component_collection_creation.*
|
import kotlinx.android.synthetic.main.component_collection_creation.*
|
||||||
import kotlinx.android.synthetic.main.component_collection_creation.view.*
|
import kotlinx.android.synthetic.main.component_collection_creation.view.*
|
||||||
|
import mozilla.components.support.ktx.android.view.hideKeyboard
|
||||||
|
import mozilla.components.support.ktx.android.view.showKeyboard
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.ext.increaseTapArea
|
import org.mozilla.fenix.ext.increaseTapArea
|
||||||
import org.mozilla.fenix.mvi.UIView
|
import org.mozilla.fenix.mvi.UIView
|
||||||
|
@ -41,8 +45,24 @@ class CollectionCreationUIView(
|
||||||
private val collectionCreationTabListAdapter = CollectionCreationTabListAdapter(actionEmitter)
|
private val collectionCreationTabListAdapter = CollectionCreationTabListAdapter(actionEmitter)
|
||||||
private val collectionSaveListAdapter = SaveCollectionListAdapter(actionEmitter)
|
private val collectionSaveListAdapter = SaveCollectionListAdapter(actionEmitter)
|
||||||
private var selectedTabs: Set<Tab> = setOf()
|
private var selectedTabs: Set<Tab> = setOf()
|
||||||
|
private val selectTabsConstraints = ConstraintSet()
|
||||||
|
private val selectCollectionConstraints = ConstraintSet()
|
||||||
|
private val nameCollectionConstraints = ConstraintSet()
|
||||||
|
private val transition = AutoTransition()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
transition.duration = TRANSITION_DURATION
|
||||||
|
|
||||||
|
selectTabsConstraints.clone(collection_constraint_layout)
|
||||||
|
selectCollectionConstraints.clone(
|
||||||
|
view.context,
|
||||||
|
R.layout.component_collection_creation_select_collection
|
||||||
|
)
|
||||||
|
nameCollectionConstraints.clone(
|
||||||
|
view.context,
|
||||||
|
R.layout.component_collection_creation_name_collection
|
||||||
|
)
|
||||||
|
|
||||||
view.select_all_button.setOnClickListener {
|
view.select_all_button.setOnClickListener {
|
||||||
actionEmitter.onNext(CollectionCreationAction.SelectAllTapped)
|
actionEmitter.onNext(CollectionCreationAction.SelectAllTapped)
|
||||||
}
|
}
|
||||||
|
@ -54,7 +74,7 @@ class CollectionCreationUIView(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
name_collection_edittext.setOnEditorActionListener { v, actionId, event ->
|
view.name_collection_edittext.setOnEditorActionListener { v, actionId, event ->
|
||||||
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||||
actionEmitter.onNext(
|
actionEmitter.onNext(
|
||||||
CollectionCreationAction.SaveCollectionName(
|
CollectionCreationAction.SaveCollectionName(
|
||||||
|
@ -67,12 +87,12 @@ class CollectionCreationUIView(
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
view.add_tabs_button.setOnClickListener {
|
view.save_button.setOnClickListener {
|
||||||
actionEmitter.onNext(CollectionCreationAction.SaveTabsToCollection(selectedTabs.toList()))
|
actionEmitter.onNext(CollectionCreationAction.SaveTabsToCollection(selectedTabs.toList()))
|
||||||
}
|
}
|
||||||
|
|
||||||
view.add_collection_button.setOnClickListener {
|
view.add_collection_button.setOnClickListener {
|
||||||
actionEmitter.onNext(CollectionCreationAction.AddNewCollection(selectedTabs.toList()))
|
actionEmitter.onNext(CollectionCreationAction.AddNewCollection)
|
||||||
}
|
}
|
||||||
|
|
||||||
view.tab_list.run {
|
view.tab_list.run {
|
||||||
|
@ -86,6 +106,7 @@ class CollectionCreationUIView(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("ComplexMethod")
|
||||||
override fun updateView() = Consumer<CollectionCreationState> {
|
override fun updateView() = Consumer<CollectionCreationState> {
|
||||||
step = it.saveCollectionStep
|
step = it.saveCollectionStep
|
||||||
when (it.saveCollectionStep) {
|
when (it.saveCollectionStep) {
|
||||||
|
@ -93,73 +114,97 @@ class CollectionCreationUIView(
|
||||||
back_button.setOnClickListener {
|
back_button.setOnClickListener {
|
||||||
actionEmitter.onNext(CollectionCreationAction.BackPressed(SaveCollectionStep.SelectTabs))
|
actionEmitter.onNext(CollectionCreationAction.BackPressed(SaveCollectionStep.SelectTabs))
|
||||||
}
|
}
|
||||||
|
TransitionManager.beginDelayedTransition(
|
||||||
name_collection_edittext.visibility = View.GONE
|
view.collection_constraint_layout,
|
||||||
collections_list.visibility = View.GONE
|
transition
|
||||||
add_collection_button.visibility = View.GONE
|
)
|
||||||
divider.visibility = View.GONE
|
val constraint = selectTabsConstraints
|
||||||
|
constraint.applyTo(view.collection_constraint_layout)
|
||||||
|
|
||||||
this.selectedTabs = it.selectedTabs
|
this.selectedTabs = it.selectedTabs
|
||||||
collectionCreationTabListAdapter.updateData(it.tabs, it.selectedTabs)
|
collectionCreationTabListAdapter.updateData(it.tabs, it.selectedTabs)
|
||||||
|
|
||||||
back_button.text = view.context.getString(R.string.create_collection_select_tabs)
|
back_button.text = view.context.getString(R.string.create_collection_select_tabs)
|
||||||
|
|
||||||
val buttonText = if (it.selectedTabs.isEmpty()) {
|
val selectTabsText = if (it.selectedTabs.isEmpty()) {
|
||||||
view.context.getString(R.string.create_collection_save_to_collection_empty)
|
view.context.getString(R.string.create_collection_save_to_collection_empty)
|
||||||
} else {
|
} else {
|
||||||
view.context.getString(
|
view.context.resources.getQuantityString(
|
||||||
R.string.create_collection_save_to_collection_full,
|
R.plurals.create_collection_save_to_collection_full_plural,
|
||||||
|
it.selectedTabs.size,
|
||||||
it.selectedTabs.size
|
it.selectedTabs.size
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
view.select_tabs_layout_text.text = selectTabsText
|
||||||
|
|
||||||
tab_list.visibility = View.VISIBLE
|
save_button.visibility = if (it.selectedTabs.isEmpty()) {
|
||||||
select_all_button.visibility = View.VISIBLE
|
View.GONE
|
||||||
add_tabs_button.visibility = View.VISIBLE
|
} else {
|
||||||
|
View.VISIBLE
|
||||||
val enableSaveButton = it.selectedTabs.isNotEmpty()
|
}
|
||||||
view.add_tabs_button.isClickable = enableSaveButton
|
|
||||||
|
|
||||||
view.add_tabs_button.contentDescription = buttonText
|
|
||||||
view.add_tabs_button_text.text = buttonText
|
|
||||||
}
|
}
|
||||||
is SaveCollectionStep.SelectCollection -> {
|
is SaveCollectionStep.SelectCollection -> {
|
||||||
|
// Only show selected tabs and hide checkboxes
|
||||||
|
collectionCreationTabListAdapter.updateData(it.selectedTabs.toList(), setOf(), true)
|
||||||
|
|
||||||
back_button.setOnClickListener {
|
back_button.setOnClickListener {
|
||||||
actionEmitter.onNext(CollectionCreationAction.BackPressed(SaveCollectionStep.SelectCollection))
|
actionEmitter.onNext(CollectionCreationAction.BackPressed(SaveCollectionStep.SelectCollection))
|
||||||
}
|
}
|
||||||
collections_list.visibility = View.VISIBLE
|
TransitionManager.beginDelayedTransition(
|
||||||
add_collection_button.visibility = View.VISIBLE
|
view.collection_constraint_layout,
|
||||||
divider.visibility = View.VISIBLE
|
transition
|
||||||
tab_list.visibility = View.GONE
|
)
|
||||||
select_all_button.visibility = View.GONE
|
val constraint = selectCollectionConstraints
|
||||||
add_tabs_button.visibility = View.GONE
|
constraint.applyTo(view.collection_constraint_layout)
|
||||||
name_collection_edittext.visibility = View.GONE
|
|
||||||
|
|
||||||
back_button.text =
|
back_button.text =
|
||||||
view.context.getString(R.string.create_collection_select_collection)
|
view.context.getString(R.string.create_collection_select_collection)
|
||||||
}
|
}
|
||||||
is SaveCollectionStep.NameCollection -> {
|
is SaveCollectionStep.NameCollection -> {
|
||||||
back_button.setOnClickListener {
|
back_button.setOnClickListener {
|
||||||
actionEmitter.onNext(CollectionCreationAction.BackPressed(SaveCollectionStep.NameCollection))
|
name_collection_edittext.hideKeyboard()
|
||||||
|
val handler = Handler()
|
||||||
|
handler.postDelayed({
|
||||||
|
actionEmitter.onNext(CollectionCreationAction.BackPressed(SaveCollectionStep.NameCollection))
|
||||||
|
}, TRANSITION_DURATION)
|
||||||
}
|
}
|
||||||
name_collection_edittext.visibility = View.VISIBLE
|
transition.addListener(object : Transition.TransitionListener {
|
||||||
name_collection_edittext.requestFocus()
|
override fun onTransitionStart(transition: Transition) {
|
||||||
val imm =
|
}
|
||||||
view.context.getSystemService(INPUT_METHOD_SERVICE) as? InputMethodManager
|
|
||||||
imm?.showSoftInput(name_collection_edittext, SHOW_IMPLICIT)
|
|
||||||
collections_list.visibility = View.GONE
|
|
||||||
add_collection_button.visibility = View.GONE
|
|
||||||
divider.visibility = View.GONE
|
|
||||||
|
|
||||||
tab_list.visibility = View.GONE
|
override fun onTransitionEnd(transition: Transition) {
|
||||||
select_all_button.visibility = View.GONE
|
view.name_collection_edittext.showKeyboard()
|
||||||
add_tabs_button.visibility = View.GONE
|
transition.removeListener(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTransitionCancel(transition: Transition) {}
|
||||||
|
override fun onTransitionPause(transition: Transition) {}
|
||||||
|
override fun onTransitionResume(transition: Transition) {}
|
||||||
|
})
|
||||||
|
TransitionManager.beginDelayedTransition(
|
||||||
|
view.collection_constraint_layout,
|
||||||
|
transition
|
||||||
|
)
|
||||||
|
val constraint = nameCollectionConstraints
|
||||||
|
constraint.applyTo(view.collection_constraint_layout)
|
||||||
|
name_collection_edittext.setText(
|
||||||
|
view.context.getString(
|
||||||
|
R.string.create_collection_default_name,
|
||||||
|
1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
name_collection_edittext.setSelection(name_collection_edittext.text.length)
|
||||||
back_button.text =
|
back_button.text =
|
||||||
view.context.getString(R.string.create_collection_name_collection)
|
view.context.getString(R.string.create_collection_name_collection)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun onResumed() {
|
||||||
|
if (step == SaveCollectionStep.NameCollection) {
|
||||||
|
view.name_collection_edittext.showKeyboard()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun onKey(keyCode: Int, event: KeyEvent?): Boolean {
|
fun onKey(keyCode: Int, event: KeyEvent?): Boolean {
|
||||||
if (event?.action == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
|
if (event?.action == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
|
||||||
when (step) {
|
when (step) {
|
||||||
|
@ -178,6 +223,7 @@ class CollectionCreationUIView(
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private const val TRANSITION_DURATION = 200L
|
||||||
private const val increaseButtonByDps = 16
|
private const val increaseButtonByDps = 16
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,13 @@ import android.os.Bundle
|
||||||
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.view.inputmethod.InputMethodManager
|
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
import androidx.lifecycle.ViewModelProviders
|
import androidx.lifecycle.ViewModelProviders
|
||||||
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import kotlinx.android.synthetic.main.fragment_create_collection.view.*
|
import kotlinx.android.synthetic.main.fragment_create_collection.view.*
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.components.FenixSnackbar
|
||||||
|
import org.mozilla.fenix.ext.getRootView
|
||||||
import org.mozilla.fenix.mvi.ActionBusFactory
|
import org.mozilla.fenix.mvi.ActionBusFactory
|
||||||
import org.mozilla.fenix.mvi.getAutoDisposeObservable
|
import org.mozilla.fenix.mvi.getAutoDisposeObservable
|
||||||
import org.mozilla.fenix.mvi.getManagedEmitter
|
import org.mozilla.fenix.mvi.getManagedEmitter
|
||||||
|
@ -40,11 +42,16 @@ class CreateCollectionFragment : DialogFragment() {
|
||||||
}
|
}
|
||||||
val tabs = viewModel!!.tabs
|
val tabs = viewModel!!.tabs
|
||||||
val selectedTabs = viewModel.selectedTabs
|
val selectedTabs = viewModel.selectedTabs
|
||||||
|
val step = viewModel.saveCollectionStep
|
||||||
|
|
||||||
collectionCreationComponent = CollectionCreationComponent(
|
collectionCreationComponent = CollectionCreationComponent(
|
||||||
view.create_collection_wrapper,
|
view.create_collection_wrapper,
|
||||||
ActionBusFactory.get(this),
|
ActionBusFactory.get(this),
|
||||||
CollectionCreationState(tabs = tabs, selectedTabs = selectedTabs)
|
CollectionCreationState(
|
||||||
|
tabs = tabs,
|
||||||
|
selectedTabs = selectedTabs,
|
||||||
|
saveCollectionStep = step
|
||||||
|
)
|
||||||
)
|
)
|
||||||
return view
|
return view
|
||||||
}
|
}
|
||||||
|
@ -59,6 +66,7 @@ class CreateCollectionFragment : DialogFragment() {
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
(collectionCreationComponent.uiView as CollectionCreationUIView).onResumed()
|
||||||
subscribeToActions()
|
subscribeToActions()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +88,21 @@ class CreateCollectionFragment : DialogFragment() {
|
||||||
CollectionCreationChange.StepChanged(SaveCollectionStep.NameCollection)
|
CollectionCreationChange.StepChanged(SaveCollectionStep.NameCollection)
|
||||||
)
|
)
|
||||||
is CollectionCreationAction.BackPressed -> handleBackPress(backPressFrom = it.backPressFrom)
|
is CollectionCreationAction.BackPressed -> handleBackPress(backPressFrom = it.backPressFrom)
|
||||||
|
is CollectionCreationAction.SaveCollectionName -> {
|
||||||
|
showSavedSnackbar(it.tabs.size)
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showSavedSnackbar(tabSize: Int) {
|
||||||
|
context?.let { context: Context ->
|
||||||
|
val rootView = context.getRootView()
|
||||||
|
rootView?.let { view: View ->
|
||||||
|
val string = context.resources.getQuantityString(R.plurals.create_collection_tabs_saved, tabSize)
|
||||||
|
FenixSnackbar.make(view, Snackbar.LENGTH_LONG).setText(string)
|
||||||
|
.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,9 +114,6 @@ class CreateCollectionFragment : DialogFragment() {
|
||||||
CollectionCreationChange.StepChanged(SaveCollectionStep.SelectTabs)
|
CollectionCreationChange.StepChanged(SaveCollectionStep.SelectTabs)
|
||||||
)
|
)
|
||||||
SaveCollectionStep.NameCollection -> {
|
SaveCollectionStep.NameCollection -> {
|
||||||
val imm =
|
|
||||||
view?.context?.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
|
|
||||||
imm?.hideSoftInputFromWindow(view?.windowToken, 0)
|
|
||||||
getManagedEmitter<CollectionCreationChange>().onNext(
|
getManagedEmitter<CollectionCreationChange>().onNext(
|
||||||
CollectionCreationChange.StepChanged(SaveCollectionStep.SelectCollection)
|
CollectionCreationChange.StepChanged(SaveCollectionStep.SelectCollection)
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,4 +9,5 @@ import androidx.lifecycle.ViewModel
|
||||||
class CreateCollectionViewModel : ViewModel() {
|
class CreateCollectionViewModel : ViewModel() {
|
||||||
var selectedTabs = setOf<Tab>()
|
var selectedTabs = setOf<Tab>()
|
||||||
var tabs = listOf<Tab>()
|
var tabs = listOf<Tab>()
|
||||||
|
var saveCollectionStep: SaveCollectionStep = SaveCollectionStep.SelectTabs
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ import android.content.Intent.EXTRA_SUBJECT
|
||||||
import android.content.Intent.EXTRA_TEXT
|
import android.content.Intent.EXTRA_TEXT
|
||||||
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
import android.view.ContextThemeWrapper
|
import android.view.ContextThemeWrapper
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
import mozilla.components.support.base.log.Log
|
import mozilla.components.support.base.log.Log
|
||||||
|
@ -69,3 +71,11 @@ fun Context.share(text: String, subject: String = ""): Boolean {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Root View with an activity context
|
||||||
|
*
|
||||||
|
* @return ViewGroup? if it is able to get a root view from the context
|
||||||
|
*/
|
||||||
|
fun Context.getRootView(): View? =
|
||||||
|
asActivity()?.window?.decorView?.findViewById<View>(android.R.id.content) as? ViewGroup
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.mozilla.fenix.HomeActivity
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.collections.CreateCollectionFragment
|
import org.mozilla.fenix.collections.CreateCollectionFragment
|
||||||
import org.mozilla.fenix.collections.CreateCollectionViewModel
|
import org.mozilla.fenix.collections.CreateCollectionViewModel
|
||||||
|
import org.mozilla.fenix.collections.SaveCollectionStep
|
||||||
import org.mozilla.fenix.collections.Tab
|
import org.mozilla.fenix.collections.Tab
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
|
@ -75,7 +76,8 @@ class HomeFragment : Fragment(), CoroutineScope {
|
||||||
): View? {
|
): View? {
|
||||||
job = Job()
|
job = Job()
|
||||||
val view = inflater.inflate(R.layout.fragment_home, container, false)
|
val view = inflater.inflate(R.layout.fragment_home, container, false)
|
||||||
val mode = if ((activity as HomeActivity).browsingModeManager.isPrivate) Mode.Private else Mode.Normal
|
val mode =
|
||||||
|
if ((activity as HomeActivity).browsingModeManager.isPrivate) Mode.Private else Mode.Normal
|
||||||
sessionControlComponent = SessionControlComponent(
|
sessionControlComponent = SessionControlComponent(
|
||||||
view.homeLayout,
|
view.homeLayout,
|
||||||
bus,
|
bus,
|
||||||
|
@ -126,7 +128,8 @@ class HomeFragment : Fragment(), CoroutineScope {
|
||||||
orientation = BrowserMenu.Orientation.DOWN
|
orientation = BrowserMenu.Orientation.DOWN
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val roundToInt = (toolbarPaddingDp * Resources.getSystem().displayMetrics.density).roundToInt()
|
val roundToInt =
|
||||||
|
(toolbarPaddingDp * Resources.getSystem().displayMetrics.density).roundToInt()
|
||||||
view.toolbar.compoundDrawablePadding = roundToInt
|
view.toolbar.compoundDrawablePadding = roundToInt
|
||||||
view.toolbar.setOnClickListener {
|
view.toolbar.setOnClickListener {
|
||||||
val directions = HomeFragmentDirections.actionHomeFragmentToSearchFragment(null)
|
val directions = HomeFragmentDirections.actionHomeFragmentToSearchFragment(null)
|
||||||
|
@ -137,7 +140,8 @@ class HomeFragment : Fragment(), CoroutineScope {
|
||||||
|
|
||||||
val isPrivate = (activity as HomeActivity).browsingModeManager.isPrivate
|
val isPrivate = (activity as HomeActivity).browsingModeManager.isPrivate
|
||||||
|
|
||||||
privateBrowsingButton.contentDescription = contentDescriptionForPrivateBrowsingButton(isPrivate)
|
privateBrowsingButton.contentDescription =
|
||||||
|
contentDescriptionForPrivateBrowsingButton(isPrivate)
|
||||||
|
|
||||||
privateBrowsingButton.setOnClickListener {
|
privateBrowsingButton.setOnClickListener {
|
||||||
val browsingModeManager = (activity as HomeActivity).browsingModeManager
|
val browsingModeManager = (activity as HomeActivity).browsingModeManager
|
||||||
|
@ -189,39 +193,25 @@ class HomeFragment : Fragment(), CoroutineScope {
|
||||||
private fun handleTabAction(action: TabAction) {
|
private fun handleTabAction(action: TabAction) {
|
||||||
Do exhaustive when (action) {
|
Do exhaustive when (action) {
|
||||||
is TabAction.SaveTabGroup -> {
|
is TabAction.SaveTabGroup -> {
|
||||||
val tabs = requireComponents.core.sessionManager.sessions
|
showCollectionCreationFragment(action.selectedTabSessionId)
|
||||||
.map { Tab(it.id, it.url, it.url.urlToHost(), it.title) }
|
|
||||||
|
|
||||||
activity?.run {
|
|
||||||
ViewModelProviders.of(this).get(CreateCollectionViewModel::class.java)
|
|
||||||
}!!.tabs = tabs
|
|
||||||
|
|
||||||
val selectedTabs = tabs.find { tab -> tab.sessionId == action.selectedTabSessionId }
|
|
||||||
val selectedSet = if (selectedTabs == null) setOf() else setOf(selectedTabs)
|
|
||||||
activity?.run {
|
|
||||||
ViewModelProviders.of(this).get(CreateCollectionViewModel::class.java)
|
|
||||||
}!!.selectedTabs = selectedSet
|
|
||||||
|
|
||||||
CreateCollectionFragment()
|
|
||||||
.show(
|
|
||||||
requireActivity().supportFragmentManager,
|
|
||||||
CreateCollectionFragment.createCollectionTag
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
is TabAction.Select -> {
|
is TabAction.Select -> {
|
||||||
val session = requireComponents.core.sessionManager.findSessionById(action.sessionId)
|
val session =
|
||||||
|
requireComponents.core.sessionManager.findSessionById(action.sessionId)
|
||||||
requireComponents.core.sessionManager.select(session!!)
|
requireComponents.core.sessionManager.select(session!!)
|
||||||
(activity as HomeActivity).openToBrowser(BrowserDirection.FromHome)
|
(activity as HomeActivity).openToBrowser(BrowserDirection.FromHome)
|
||||||
}
|
}
|
||||||
is TabAction.Close -> {
|
is TabAction.Close -> {
|
||||||
requireComponents.core.sessionManager.findSessionById(action.sessionId)?.let { session ->
|
requireComponents.core.sessionManager.findSessionById(action.sessionId)
|
||||||
requireComponents.core.sessionManager.remove(session)
|
?.let { session ->
|
||||||
}
|
requireComponents.core.sessionManager.remove(session)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
is TabAction.Share -> {
|
is TabAction.Share -> {
|
||||||
requireComponents.core.sessionManager.findSessionById(action.sessionId)?.let { session ->
|
requireComponents.core.sessionManager.findSessionById(action.sessionId)
|
||||||
requireContext().share(session.url)
|
?.let { session ->
|
||||||
}
|
requireContext().share(session.url)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
is TabAction.CloseAll -> {
|
is TabAction.CloseAll -> {
|
||||||
requireComponents.useCases.tabsUseCases.removeAllTabsOfType.invoke(action.private)
|
requireComponents.useCases.tabsUseCases.removeAllTabsOfType.invoke(action.private)
|
||||||
|
@ -231,7 +221,8 @@ class HomeFragment : Fragment(), CoroutineScope {
|
||||||
searchTermOrURL = SupportUtils.getGenericSumoURLForTopic
|
searchTermOrURL = SupportUtils.getGenericSumoURLForTopic
|
||||||
(SupportUtils.SumoTopic.PRIVATE_BROWSING_MYTHS),
|
(SupportUtils.SumoTopic.PRIVATE_BROWSING_MYTHS),
|
||||||
newTab = true,
|
newTab = true,
|
||||||
from = BrowserDirection.FromHome)
|
from = BrowserDirection.FromHome
|
||||||
|
)
|
||||||
}
|
}
|
||||||
is TabAction.Add -> {
|
is TabAction.Add -> {
|
||||||
val directions = HomeFragmentDirections.actionHomeFragmentToSearchFragment(null)
|
val directions = HomeFragmentDirections.actionHomeFragmentToSearchFragment(null)
|
||||||
|
@ -333,16 +324,24 @@ class HomeFragment : Fragment(), CoroutineScope {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun openSessionMenu(sessionType: SessionBottomSheetFragment.SessionType) {
|
private fun showCollectionCreationFragment(selectedTabId: String?) {
|
||||||
SessionBottomSheetFragment
|
val tabs = requireComponents.core.sessionManager.sessions
|
||||||
.create(sessionType)
|
.map { Tab(it.id, it.url, it.url.urlToHost(), it.title) }
|
||||||
.apply {
|
|
||||||
onDelete = {
|
val viewModel = activity?.run {
|
||||||
val isPrivate = sessionType is SessionBottomSheetFragment.SessionType.Private
|
ViewModelProviders.of(this).get(CreateCollectionViewModel::class.java)
|
||||||
requireComponents.useCases.tabsUseCases.removeAllTabsOfType.invoke(isPrivate)
|
}
|
||||||
}
|
viewModel?.tabs = tabs
|
||||||
}
|
val selectedTabs = tabs.find { tab -> tab.sessionId == selectedTabId }
|
||||||
.show(requireActivity().supportFragmentManager, SessionBottomSheetFragment.overflowFragmentTag)
|
val selectedSet = if (selectedTabs == null) setOf() else setOf(selectedTabs)
|
||||||
|
viewModel?.selectedTabs = selectedSet
|
||||||
|
viewModel?.saveCollectionStep = SaveCollectionStep.SelectTabs
|
||||||
|
|
||||||
|
CreateCollectionFragment()
|
||||||
|
.show(
|
||||||
|
requireActivity().supportFragmentManager,
|
||||||
|
CreateCollectionFragment.createCollectionTag
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
@ -5,24 +5,24 @@
|
||||||
package org.mozilla.fenix.utils
|
package org.mozilla.fenix.utils
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import org.mozilla.fenix.components.FenixSnackbar
|
import org.mozilla.fenix.components.FenixSnackbar
|
||||||
import org.mozilla.fenix.ext.asActivity
|
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
|
import org.mozilla.fenix.ext.getRootView
|
||||||
|
|
||||||
class ItsNotBrokenSnack(val context: Context) {
|
class ItsNotBrokenSnack(val context: Context) {
|
||||||
fun showSnackbar(issueNumber: String) {
|
fun showSnackbar(issueNumber: String) {
|
||||||
val rootView =
|
val rootView =
|
||||||
context.asActivity()?.window?.decorView?.findViewById<View>(android.R.id.content) as ViewGroup
|
context.getRootView()
|
||||||
|
|
||||||
FenixSnackbar.make(rootView, FenixSnackbar.LENGTH_SHORT)
|
rootView?.let {
|
||||||
.setText(message.replace("%", issueNumber))
|
FenixSnackbar.make(it, FenixSnackbar.LENGTH_SHORT)
|
||||||
.setAction("Add Tab to Issue") {
|
.setText(message.replace("%", issueNumber))
|
||||||
context.components.useCases.tabsUseCases.addTab
|
.setAction("Add Tab to Issue") {
|
||||||
.invoke(issues + issueNumber)
|
context.components.useCases.tabsUseCases.addTab
|
||||||
}
|
.invoke(issues + issueNumber)
|
||||||
.show()
|
}
|
||||||
|
.show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
@ -5,5 +5,5 @@
|
||||||
|
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<corners android:radius="8dp"/>
|
<corners android:radius="8dp"/>
|
||||||
<solid android:color="?accentHighContrast" />
|
<solid android:color="?accentBright" />
|
||||||
</shape>
|
</shape>
|
|
@ -5,6 +5,7 @@
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout 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_constraint_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:clipToPadding="false">
|
android:clipToPadding="false">
|
||||||
|
@ -86,7 +87,7 @@
|
||||||
android:paddingTop="12dp"
|
android:paddingTop="12dp"
|
||||||
android:paddingEnd="20dp"
|
android:paddingEnd="20dp"
|
||||||
android:paddingBottom="12dp"
|
android:paddingBottom="12dp"
|
||||||
android:text="Collection 1"
|
android:text="@string/create_collection_default_name"
|
||||||
android:textColor="?primaryText"
|
android:textColor="?primaryText"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
|
@ -102,21 +103,30 @@
|
||||||
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/add_tabs_button"
|
app:layout_constraintBottom_toTopOf="@+id/add_tabs_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" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/tab_list_dim"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:alpha="0"
|
||||||
|
android:background="@drawable/scrim_background"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/tab_list"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/add_tabs_button"
|
android:id="@+id/add_tabs_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:background="@drawable/add_tabs_to_collection_background"
|
android:background="@drawable/add_tabs_to_collection_background"
|
||||||
android:clickable="true"
|
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:focusable="true"
|
|
||||||
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
|
||||||
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">
|
||||||
|
@ -135,12 +145,12 @@
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/add_tabs_button_text"
|
android:id="@+id/select_tabs_layout_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:importantForAccessibility="no"
|
android:gravity="center_vertical"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:text="@string/create_collection_save_to_collection_empty"
|
android:text="@string/create_collection_save_to_collection_empty"
|
||||||
android:textColor="?neutral"
|
android:textColor="?neutral"
|
||||||
|
@ -150,16 +160,16 @@
|
||||||
app:layout_constraintStart_toEndOf="@id/close_icon"
|
app:layout_constraintStart_toEndOf="@id/close_icon"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<ImageView
|
<Button
|
||||||
android:id="@+id/save_icon"
|
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:layout_margin="16dp"
|
android:background="?android:attr/selectableItemBackground"
|
||||||
android:importantForAccessibility="no"
|
android:text="@string/create_collection_save"
|
||||||
android:tint="?neutral"
|
android:textAppearance="@style/TextAppearance.MaterialComponents.Button"
|
||||||
|
android:textColor="?neutral"
|
||||||
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" />
|
||||||
app:srcCompat="@drawable/ic_archive" />
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
|
@ -0,0 +1,182 @@
|
||||||
|
<?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/. -->
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout 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/collection_constraint_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:clipToPadding="false">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/back_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
android:drawableStart="@drawable/mozac_ic_back"
|
||||||
|
android:drawablePadding="8dp"
|
||||||
|
android:drawableTint="@color/neutral_text"
|
||||||
|
android:text="@string/create_collection_name_collection"
|
||||||
|
android:textAppearance="@style/HeaderTextStyle"
|
||||||
|
android:textColor="@color/neutral_text"
|
||||||
|
android:textSize="20sp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/select_all_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:alpha="0"
|
||||||
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
android:text="@string/create_collection_select_all"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textColor="@color/neutral_text"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/collections_list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:alpha="0"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/add_collection_button" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/add_collection_button"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:alpha="0"
|
||||||
|
android:background="?foundation"
|
||||||
|
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
|
||||||
|
android:id="@+id/name_collection_edittext"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom|center"
|
||||||
|
android:alpha="1"
|
||||||
|
android:autofillHints="false"
|
||||||
|
android:background="?foundation"
|
||||||
|
android:focusedByDefault="true"
|
||||||
|
android:imeOptions="actionDone"
|
||||||
|
android:importantForAutofill="no"
|
||||||
|
android:inputType="text"
|
||||||
|
android:paddingStart="20dp"
|
||||||
|
android:paddingTop="12dp"
|
||||||
|
android:paddingEnd="20dp"
|
||||||
|
android:paddingBottom="12dp"
|
||||||
|
android:text="@string/create_collection_default_name"
|
||||||
|
android:textColor="?primaryText"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
tools:targetApi="o" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/tab_list"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:fadingEdgeLength="30dp"
|
||||||
|
android:requiresFadingEdge="vertical"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/name_collection_edittext"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/back_button" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/tab_list_dim"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:alpha="0.5"
|
||||||
|
android:background="@drawable/scrim_background"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/tab_list"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/add_tabs_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:alpha="0"
|
||||||
|
android:background="@drawable/add_tabs_to_collection_background"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent">
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/close_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
android:contentDescription="@string/create_collection_close"
|
||||||
|
android:src="@drawable/mozac_ic_close"
|
||||||
|
android:tint="?neutral"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/select_tabs_layout_text"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:text="@string/create_collection_save_to_collection_empty"
|
||||||
|
android:textColor="?neutral"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/close_icon"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/save_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
android:text="@string/create_collection_save"
|
||||||
|
android:textAppearance="@style/TextAppearance.MaterialComponents.Button"
|
||||||
|
android:textColor="?neutral"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,183 @@
|
||||||
|
<?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/. -->
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout 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/collection_constraint_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:clipToPadding="false">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/back_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
android:drawableStart="@drawable/mozac_ic_back"
|
||||||
|
android:drawablePadding="8dp"
|
||||||
|
android:drawableTint="@color/neutral_text"
|
||||||
|
android:text="@string/create_collection_select_collection"
|
||||||
|
android:textAppearance="@style/HeaderTextStyle"
|
||||||
|
android:textColor="@color/neutral_text"
|
||||||
|
android:textSize="20sp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/select_all_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:alpha="0"
|
||||||
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
android:text="@string/create_collection_select_all"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textColor="@color/neutral_text"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/collections_list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:alpha="1"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/add_collection_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: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:alpha="1"
|
||||||
|
android:background="?neutralFaded"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/name_collection_edittext"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom|center"
|
||||||
|
android:alpha="0"
|
||||||
|
android:autofillHints="false"
|
||||||
|
android:background="?foundation"
|
||||||
|
android:focusedByDefault="true"
|
||||||
|
android:imeOptions="actionDone"
|
||||||
|
android:importantForAutofill="no"
|
||||||
|
android:inputType="text"
|
||||||
|
android:paddingStart="20dp"
|
||||||
|
android:paddingTop="12dp"
|
||||||
|
android:paddingEnd="20dp"
|
||||||
|
android:paddingBottom="12dp"
|
||||||
|
android:text="@string/create_collection_default_name"
|
||||||
|
android:textColor="?primaryText"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
tools:targetApi="o" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/tab_list"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:fadingEdgeLength="30dp"
|
||||||
|
android:requiresFadingEdge="vertical"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/collections_list"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/back_button" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/tab_list_dim"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:alpha="0.5"
|
||||||
|
android:background="@drawable/scrim_background"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/tab_list"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/add_tabs_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:alpha="0"
|
||||||
|
android:background="@drawable/add_tabs_to_collection_background"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent">
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/close_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
android:contentDescription="@string/create_collection_close"
|
||||||
|
android:src="@drawable/mozac_ic_close"
|
||||||
|
android:tint="?neutral"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/select_tabs_layout_text"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:text="@string/create_collection_save_to_collection_empty"
|
||||||
|
android:textColor="?neutral"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/close_icon"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/save_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
android:text="@string/create_collection_save"
|
||||||
|
android:textAppearance="@style/TextAppearance.MaterialComponents.Button"
|
||||||
|
android:textColor="?neutral"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -436,7 +436,16 @@
|
||||||
|
|
||||||
<!-- Text to prompt users to select how many tabs they have
|
<!-- Text to prompt users to select how many tabs they have
|
||||||
selected in the "select tabs" stepof the collection creator -->
|
selected in the "select tabs" stepof the collection creator -->
|
||||||
<string name="create_collection_save_to_collection_full">%d tabs selected</string>
|
<plurals name="create_collection_save_to_collection_full_plural">
|
||||||
|
<item quantity="one">%d tab selected</item>
|
||||||
|
<item quantity="other">%d tabs selected</item>
|
||||||
|
</plurals>
|
||||||
|
|
||||||
|
<!-- Text shown in snackbar when tab(s) have been saved in a collection -->
|
||||||
|
<plurals name="create_collection_tabs_saved">
|
||||||
|
<item quantity="one">Tab saved!</item>
|
||||||
|
<item quantity="other">Tabs saved!</item>
|
||||||
|
</plurals>
|
||||||
|
|
||||||
<!-- Content description (not visible, for screen readers etc.): button to close the collection creator -->
|
<!-- Content description (not visible, for screen readers etc.): button to close the collection creator -->
|
||||||
<string name="create_collection_close">Close</string>
|
<string name="create_collection_close">Close</string>
|
||||||
|
@ -444,6 +453,18 @@
|
||||||
<!-- Button to save currently selected tabs in the "select tabs" step of the collection creator-->
|
<!-- Button to save currently selected tabs in the "select tabs" step of the collection creator-->
|
||||||
<string name="create_collection_save">Save</string>
|
<string name="create_collection_save">Save</string>
|
||||||
|
|
||||||
|
<!-- Default name for a new collection in "name new collection" step of the collection creator-->
|
||||||
|
<string name="create_collection_default_name">Collection %d</string>
|
||||||
|
|
||||||
|
<!-- Text shown in snackbar when user deletes a collection -->
|
||||||
|
<string name="snackbar_collection_deleted">Collection deleted</string>
|
||||||
|
|
||||||
|
<!-- Text shown in snackbar when user deletes a tab -->
|
||||||
|
<string name="snackbar_tab_deleted">Tab deleted</string>
|
||||||
|
|
||||||
|
<!-- Text for action to undo deleting a tab or collection shown in snackbar -->
|
||||||
|
<string name="snackbar_deleted_undo">UNDO</string>
|
||||||
|
|
||||||
<!-- QR code scanner prompt which appears after scanning a code, but before navigating to it
|
<!-- QR code scanner prompt which appears after scanning a code, but before navigating to it
|
||||||
First parameter is the name of the app, second parameter is the URL or text scanned-->
|
First parameter is the name of the app, second parameter is the URL or text scanned-->
|
||||||
<string name="qr_scanner_confirmation_dialog_message">Allow %1$s to open %2$s</string>
|
<string name="qr_scanner_confirmation_dialog_message">Allow %1$s to open %2$s</string>
|
||||||
|
|
Loading…
Reference in New Issue