1
0
Fork 0

For #1575: Enables adding tabs to existing collection

master
Sawyer Blatz 2019-05-20 08:44:29 -07:00
parent 7e7edc8b7a
commit afbe397f94
9 changed files with 57 additions and 24 deletions

View File

@ -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 {

View File

@ -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)
}
} }
} }
} }

View File

@ -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>()

View File

@ -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()

View File

@ -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()

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"