1
0
Fork 0
fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlComponent.kt

150 lines
5.3 KiB
Kotlin
Raw Normal View History

2019-04-06 06:24:28 +02:00
/* This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.home.sessioncontrol
import android.graphics.Bitmap
import android.os.Parcelable
2019-04-06 06:24:28 +02:00
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProviders
2019-04-06 06:24:28 +02:00
import androidx.recyclerview.widget.RecyclerView
import io.reactivex.Observable
2019-04-06 06:24:28 +02:00
import io.reactivex.Observer
import kotlinx.android.parcel.Parcelize
2019-04-06 06:24:28 +02:00
import org.mozilla.fenix.mvi.Action
import org.mozilla.fenix.mvi.ActionBusFactory
import org.mozilla.fenix.mvi.Change
import org.mozilla.fenix.mvi.UIComponent
import org.mozilla.fenix.mvi.UIComponentViewModel
2019-04-06 06:24:28 +02:00
import org.mozilla.fenix.mvi.ViewState
class SessionControlComponent(
private val container: ViewGroup,
owner: Fragment,
2019-04-06 06:24:28 +02:00
bus: ActionBusFactory,
override var initialState: SessionControlState = SessionControlState(emptyList(), emptyList(), Mode.Normal)
2019-04-06 06:24:28 +02:00
) :
UIComponent<SessionControlState, SessionControlAction, SessionControlChange>(
owner,
2019-04-06 06:24:28 +02:00
bus.getManagedEmitter(SessionControlAction::class.java),
bus.getSafeManagedObservable(SessionControlChange::class.java)
) {
var stateObservable: Observable<SessionControlState>
lateinit var viewModel: SessionControlViewModel
2019-04-06 06:24:28 +02:00
override fun initView() = SessionControlUIView(container, actionEmitter, changesObservable)
val view: RecyclerView
get() = uiView.view as RecyclerView
override fun render(): Observable<SessionControlState> {
viewModel = ViewModelProviders.of(owner, SessionControlViewModel.Factory(initialState))
.get(SessionControlViewModel::class.java)
return viewModel.render(changesObservable, uiView)
}
2019-04-06 06:24:28 +02:00
init {
stateObservable = render()
2019-04-06 06:24:28 +02:00
}
}
@Parcelize
data class Tab(
val sessionId: String,
val url: String,
val hostname: String,
val title: String,
val selected: Boolean? = null,
val thumbnail: Bitmap? = null
) : Parcelable
@Parcelize
data class TabCollection(
val id: Int,
val title: String,
val tabs: MutableList<Tab>,
val iconColor: Int = 0,
var expanded: Boolean = false
) : Parcelable
2019-04-06 06:24:28 +02:00
sealed class Mode {
object Normal : Mode()
object Private : Mode()
}
data class SessionControlState(
val tabs: List<Tab>,
val collections: List<TabCollection>,
2019-04-06 06:24:28 +02:00
val mode: Mode
) : ViewState
sealed class TabAction : Action {
data class SaveTabGroup(val selectedTabSessionId: String?) : TabAction()
2019-04-06 06:24:28 +02:00
object Add : TabAction()
object ShareTabs : TabAction()
2019-04-06 06:24:28 +02:00
data class CloseAll(val private: Boolean) : TabAction()
data class Select(val sessionId: String) : TabAction()
data class Close(val sessionId: String) : TabAction()
data class Share(val sessionId: String) : TabAction()
2019-04-06 06:24:28 +02:00
object PrivateBrowsingLearnMore : TabAction()
}
sealed class CollectionAction : Action {
data class Expand(val collection: TabCollection) : CollectionAction()
data class Collapse(val collection: TabCollection) : CollectionAction()
data class Delete(val collection: TabCollection) : CollectionAction()
data class AddTab(val collection: TabCollection) : CollectionAction()
data class Rename(val collection: TabCollection) : CollectionAction()
data class OpenTabs(val collection: TabCollection) : CollectionAction()
data class ShareTabs(val collection: TabCollection) : CollectionAction()
data class RemoveTab(val collection: TabCollection, val tab: Tab) : CollectionAction()
}
2019-04-06 06:24:28 +02:00
sealed class SessionControlAction : Action {
data class Tab(val action: TabAction) : SessionControlAction()
data class Collection(val action: CollectionAction) : SessionControlAction()
2019-04-06 06:24:28 +02:00
}
fun Observer<SessionControlAction>.onNext(tabAction: TabAction) {
onNext(SessionControlAction.Tab(tabAction))
}
fun Observer<SessionControlAction>.onNext(collectionAction: CollectionAction) {
onNext(SessionControlAction.Collection(collectionAction))
}
2019-04-06 06:24:28 +02:00
sealed class SessionControlChange : Change {
data class TabsChange(val tabs: List<Tab>) : SessionControlChange()
data class ModeChange(val mode: Mode) : SessionControlChange()
data class CollectionsChange(val collections: List<TabCollection>) : SessionControlChange()
2019-04-06 06:24:28 +02:00
}
class SessionControlViewModel(initialState: SessionControlState) :
UIComponentViewModel<SessionControlState, SessionControlAction, SessionControlChange>(
initialState,
reducer
) {
class Factory(
private val initialState: SessionControlState
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel?> create(modelClass: Class<T>): T =
SessionControlViewModel(initialState) as T
}
companion object {
val reducer: (SessionControlState, SessionControlChange) -> SessionControlState = { state, change ->
when (change) {
is SessionControlChange.CollectionsChange -> state.copy(collections = change.collections)
is SessionControlChange.TabsChange -> state.copy(tabs = change.tabs)
is SessionControlChange.ModeChange -> state.copy(mode = change.mode)
}
}
}
}