For #1575: Enables adding tabs to existing collection
parent
7e7edc8b7a
commit
afbe397f94
|
@ -664,7 +664,7 @@ class BrowserFragment : Fragment(), BackHandler, CoroutineScope {
|
||||||
ViewModelProviders.of(this).get(CreateCollectionViewModel::class.java)
|
ViewModelProviders.of(this).get(CreateCollectionViewModel::class.java)
|
||||||
}
|
}
|
||||||
viewModel?.tabs = listOf(tabs)
|
viewModel?.tabs = listOf(tabs)
|
||||||
val selectedSet = setOf(tabs)
|
val selectedSet = mutableSetOf(tabs)
|
||||||
viewModel?.selectedTabs = selectedSet
|
viewModel?.selectedTabs = selectedSet
|
||||||
viewModel?.saveCollectionStep = SaveCollectionStep.SelectCollection
|
viewModel?.saveCollectionStep = SaveCollectionStep.SelectCollection
|
||||||
view?.let {
|
view?.let {
|
||||||
|
|
|
@ -19,11 +19,11 @@ import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.mozilla.fenix.FenixViewModelProvider
|
import org.mozilla.fenix.FenixViewModelProvider
|
||||||
import mozilla.components.browser.session.Session
|
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.components.FenixSnackbar
|
import org.mozilla.fenix.components.FenixSnackbar
|
||||||
import org.mozilla.fenix.ext.getRootView
|
import org.mozilla.fenix.ext.getRootView
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
|
import org.mozilla.fenix.home.sessioncontrol.toSessionBundle
|
||||||
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
|
||||||
|
@ -32,6 +32,8 @@ import kotlin.coroutines.CoroutineContext
|
||||||
class CreateCollectionFragment : DialogFragment(), CoroutineScope {
|
class CreateCollectionFragment : DialogFragment(), CoroutineScope {
|
||||||
private lateinit var collectionCreationComponent: CollectionCreationComponent
|
private lateinit var collectionCreationComponent: CollectionCreationComponent
|
||||||
private lateinit var job: Job
|
private lateinit var job: Job
|
||||||
|
private lateinit var viewModel: CreateCollectionViewModel
|
||||||
|
|
||||||
override val coroutineContext: CoroutineContext
|
override val coroutineContext: CoroutineContext
|
||||||
get() = Dispatchers.Main + job
|
get() = Dispatchers.Main + job
|
||||||
|
|
||||||
|
@ -49,13 +51,9 @@ class CreateCollectionFragment : DialogFragment(), CoroutineScope {
|
||||||
job = Job()
|
job = Job()
|
||||||
val view = inflater.inflate(R.layout.fragment_create_collection, container, false)
|
val view = inflater.inflate(R.layout.fragment_create_collection, container, false)
|
||||||
|
|
||||||
val viewModel = activity?.run {
|
viewModel = activity!!.run {
|
||||||
ViewModelProviders.of(this).get(CreateCollectionViewModel::class.java)
|
ViewModelProviders.of(this).get(CreateCollectionViewModel::class.java)
|
||||||
}
|
}
|
||||||
val tabs = viewModel!!.tabs
|
|
||||||
val selectedTabs = viewModel.selectedTabs
|
|
||||||
val step = viewModel.saveCollectionStep
|
|
||||||
val tabCollections = viewModel.tabCollections
|
|
||||||
|
|
||||||
collectionCreationComponent = CollectionCreationComponent(
|
collectionCreationComponent = CollectionCreationComponent(
|
||||||
view.create_collection_wrapper,
|
view.create_collection_wrapper,
|
||||||
|
@ -64,7 +62,12 @@ class CreateCollectionFragment : DialogFragment(), CoroutineScope {
|
||||||
this,
|
this,
|
||||||
CollectionCreationViewModel::class.java
|
CollectionCreationViewModel::class.java
|
||||||
) {
|
) {
|
||||||
CollectionCreationViewModel(CollectionCreationState(tabs, selectedTabs, step, tabCollections))
|
CollectionCreationViewModel(CollectionCreationState(
|
||||||
|
viewModel.tabs,
|
||||||
|
viewModel.selectedTabs,
|
||||||
|
viewModel.saveCollectionStep,
|
||||||
|
viewModel.tabCollections
|
||||||
|
))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return view
|
return view
|
||||||
|
@ -98,10 +101,16 @@ class CreateCollectionFragment : DialogFragment(), CoroutineScope {
|
||||||
getManagedEmitter<CollectionCreationChange>()
|
getManagedEmitter<CollectionCreationChange>()
|
||||||
.onNext(CollectionCreationChange.StepChanged(SaveCollectionStep.SelectCollection))
|
.onNext(CollectionCreationChange.StepChanged(SaveCollectionStep.SelectCollection))
|
||||||
}
|
}
|
||||||
is CollectionCreationAction.AddTabToSelection -> getManagedEmitter<CollectionCreationChange>()
|
is CollectionCreationAction.AddTabToSelection -> {
|
||||||
.onNext(CollectionCreationChange.TabAdded(it.tab))
|
viewModel.selectedTabs.add(it.tab)
|
||||||
is CollectionCreationAction.RemoveTabFromSelection -> getManagedEmitter<CollectionCreationChange>()
|
getManagedEmitter<CollectionCreationChange>()
|
||||||
.onNext(CollectionCreationChange.TabRemoved(it.tab))
|
.onNext(CollectionCreationChange.TabAdded(it.tab))
|
||||||
|
}
|
||||||
|
is CollectionCreationAction.RemoveTabFromSelection -> {
|
||||||
|
viewModel.selectedTabs.remove(it.tab)
|
||||||
|
getManagedEmitter<CollectionCreationChange>()
|
||||||
|
.onNext(CollectionCreationChange.TabRemoved(it.tab))
|
||||||
|
}
|
||||||
is CollectionCreationAction.SelectAllTapped -> getManagedEmitter<CollectionCreationChange>()
|
is CollectionCreationAction.SelectAllTapped -> getManagedEmitter<CollectionCreationChange>()
|
||||||
.onNext(CollectionCreationChange.AddAllTabs)
|
.onNext(CollectionCreationChange.AddAllTabs)
|
||||||
is CollectionCreationAction.AddNewCollection -> getManagedEmitter<CollectionCreationChange>().onNext(
|
is CollectionCreationAction.AddNewCollection -> getManagedEmitter<CollectionCreationChange>().onNext(
|
||||||
|
@ -111,16 +120,22 @@ class CreateCollectionFragment : DialogFragment(), CoroutineScope {
|
||||||
is CollectionCreationAction.SaveCollectionName -> {
|
is CollectionCreationAction.SaveCollectionName -> {
|
||||||
showSavedSnackbar(it.tabs.size)
|
showSavedSnackbar(it.tabs.size)
|
||||||
dismiss()
|
dismiss()
|
||||||
|
context?.let { context ->
|
||||||
val sessionBundle = mutableListOf<Session>()
|
val sessionBundle = it.tabs.toSessionBundle(context)
|
||||||
it.tabs.forEach {
|
launch(Dispatchers.IO) {
|
||||||
requireComponents.core.sessionManager.findSessionById(it.sessionId)?.let { session ->
|
requireComponents.core.tabCollectionStorage.createCollection(it.name, sessionBundle)
|
||||||
sessionBundle.add(session)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
launch(Dispatchers.IO) {
|
is CollectionCreationAction.SelectCollection -> {
|
||||||
requireComponents.core.tabCollectionStorage.createCollection(it.name, sessionBundle)
|
showSavedSnackbar(viewModel.selectedTabs.size)
|
||||||
|
dismiss()
|
||||||
|
context?.let { context ->
|
||||||
|
val sessionBundle = viewModel.selectedTabs.toList().toSessionBundle(context)
|
||||||
|
launch(Dispatchers.IO) {
|
||||||
|
requireComponents.core.tabCollectionStorage
|
||||||
|
.addTabsToCollection(it.collection, sessionBundle)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import org.mozilla.fenix.home.sessioncontrol.Tab
|
||||||
import org.mozilla.fenix.home.sessioncontrol.TabCollection
|
import org.mozilla.fenix.home.sessioncontrol.TabCollection
|
||||||
|
|
||||||
class CreateCollectionViewModel : ViewModel() {
|
class CreateCollectionViewModel : ViewModel() {
|
||||||
var selectedTabs = setOf<Tab>()
|
var selectedTabs = mutableSetOf<Tab>()
|
||||||
var tabs = listOf<Tab>()
|
var tabs = listOf<Tab>()
|
||||||
var saveCollectionStep: SaveCollectionStep = SaveCollectionStep.SelectTabs
|
var saveCollectionStep: SaveCollectionStep = SaveCollectionStep.SelectTabs
|
||||||
var tabCollections = listOf<TabCollection>()
|
var tabCollections = listOf<TabCollection>()
|
||||||
|
|
|
@ -534,10 +534,10 @@ class HomeFragment : Fragment(), CoroutineScope {
|
||||||
}
|
}
|
||||||
viewModel?.tabs = tabs
|
viewModel?.tabs = tabs
|
||||||
val selectedTabs = tabs.find { tab -> tab.sessionId == selectedTabId }
|
val selectedTabs = tabs.find { tab -> tab.sessionId == selectedTabId }
|
||||||
val selectedSet = if (selectedTabs == null) setOf() else setOf(selectedTabs)
|
val selectedSet = if (selectedTabs == null) mutableSetOf() else mutableSetOf(selectedTabs)
|
||||||
viewModel?.selectedTabs = selectedSet
|
viewModel?.selectedTabs = selectedSet
|
||||||
viewModel?.saveCollectionStep = SaveCollectionStep.SelectTabs
|
viewModel?.saveCollectionStep = SaveCollectionStep.SelectTabs
|
||||||
viewModel?.tabCollections = requireComponents.core.tabCollectionStorage.cachedTabCollections
|
viewModel?.tabCollections = requireComponents.core.tabCollectionStorage.cachedTabCollections.reversed()
|
||||||
|
|
||||||
view?.let {
|
view?.let {
|
||||||
val directions = HomeFragmentDirections.actionHomeFragmentToCreateCollectionFragment()
|
val directions = HomeFragmentDirections.actionHomeFragmentToCreateCollectionFragment()
|
||||||
|
|
|
@ -4,12 +4,15 @@
|
||||||
|
|
||||||
package org.mozilla.fenix.home.sessioncontrol
|
package org.mozilla.fenix.home.sessioncontrol
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import io.reactivex.Observer
|
import io.reactivex.Observer
|
||||||
import kotlinx.android.parcel.Parcelize
|
import kotlinx.android.parcel.Parcelize
|
||||||
|
import mozilla.components.browser.session.Session
|
||||||
|
import org.mozilla.fenix.ext.components
|
||||||
import org.mozilla.fenix.mvi.ViewState
|
import org.mozilla.fenix.mvi.ViewState
|
||||||
import org.mozilla.fenix.mvi.Change
|
import org.mozilla.fenix.mvi.Change
|
||||||
import mozilla.components.feature.tab.collections.TabCollection as ACTabCollection
|
import mozilla.components.feature.tab.collections.TabCollection as ACTabCollection
|
||||||
|
@ -51,6 +54,16 @@ data class Tab(
|
||||||
val thumbnail: Bitmap? = null
|
val thumbnail: Bitmap? = null
|
||||||
) : Parcelable
|
) : Parcelable
|
||||||
|
|
||||||
|
fun List<Tab>.toSessionBundle(context: Context): MutableList<Session> {
|
||||||
|
val sessionBundle = mutableListOf<Session>()
|
||||||
|
this.forEach {
|
||||||
|
context.components.core.sessionManager.findSessionById(it.sessionId)?.let { session ->
|
||||||
|
sessionBundle.add(session)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sessionBundle
|
||||||
|
}
|
||||||
sealed class Mode {
|
sealed class Mode {
|
||||||
object Normal : Mode()
|
object Normal : Mode()
|
||||||
object Private : Mode()
|
object Private : Mode()
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
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:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content"
|
||||||
|
android:foreground="?android:attr/selectableItemBackground">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/collection_item"
|
android:id="@+id/collection_item"
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="?foundation"
|
android:background="?foundation"
|
||||||
|
android:foreground="?android:attr/selectableItemBackground"
|
||||||
android:drawableStart="@drawable/ic_new"
|
android:drawableStart="@drawable/ic_new"
|
||||||
android:drawablePadding="14dp"
|
android:drawablePadding="14dp"
|
||||||
android:drawableTint="?accent"
|
android:drawableTint="?accent"
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:background="?foundation"
|
android:background="?foundation"
|
||||||
|
android:foreground="?android:attr/selectableItemBackground"
|
||||||
android:drawableStart="@drawable/ic_new"
|
android:drawableStart="@drawable/ic_new"
|
||||||
android:drawablePadding="14dp"
|
android:drawablePadding="14dp"
|
||||||
android:drawableTint="?accent"
|
android:drawableTint="?accent"
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:alpha="1"
|
android:alpha="1"
|
||||||
android:background="?foundation"
|
android:background="?foundation"
|
||||||
|
android:foreground="?android:attr/selectableItemBackground"
|
||||||
android:drawableStart="@drawable/ic_new"
|
android:drawableStart="@drawable/ic_new"
|
||||||
android:drawablePadding="14dp"
|
android:drawablePadding="14dp"
|
||||||
android:drawableTint="?accent"
|
android:drawableTint="?accent"
|
||||||
|
@ -75,6 +76,7 @@
|
||||||
android:id="@+id/divider"
|
android:id="@+id/divider"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
|
android:elevation="5dp"
|
||||||
android:alpha="1"
|
android:alpha="1"
|
||||||
android:background="?neutralFaded"
|
android:background="?neutralFaded"
|
||||||
android:visibility="visible"
|
android:visibility="visible"
|
||||||
|
|
Loading…
Reference in New Issue