For #631 - Passes data into the sessions component and render a list
parent
56dadad35a
commit
d62d41b46a
|
@ -7,12 +7,14 @@ package org.mozilla.fenix.home
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.graphics.drawable.BitmapDrawable
|
import android.graphics.drawable.BitmapDrawable
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.constraintlayout.motion.widget.MotionLayout
|
import androidx.constraintlayout.motion.widget.MotionLayout
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.Observer
|
||||||
import androidx.navigation.Navigation
|
import androidx.navigation.Navigation
|
||||||
import kotlinx.android.synthetic.main.fragment_home.*
|
import kotlinx.android.synthetic.main.fragment_home.*
|
||||||
import kotlinx.android.synthetic.main.fragment_home.view.*
|
import kotlinx.android.synthetic.main.fragment_home.view.*
|
||||||
|
@ -24,6 +26,8 @@ import org.mozilla.fenix.DefaultThemeManager
|
||||||
import org.mozilla.fenix.HomeActivity
|
import org.mozilla.fenix.HomeActivity
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
|
import org.mozilla.fenix.home.sessions.ArchivedSession
|
||||||
|
import org.mozilla.fenix.home.sessions.SessionsChange
|
||||||
import org.mozilla.fenix.home.sessions.SessionsComponent
|
import org.mozilla.fenix.home.sessions.SessionsComponent
|
||||||
import org.mozilla.fenix.home.tabs.TabsAction
|
import org.mozilla.fenix.home.tabs.TabsAction
|
||||||
import org.mozilla.fenix.home.tabs.TabsChange
|
import org.mozilla.fenix.home.tabs.TabsChange
|
||||||
|
@ -51,7 +55,7 @@ class HomeFragment : Fragment() {
|
||||||
TabsComponent(view.homeLayout, bus, (activity as HomeActivity).browsingModeManager.isPrivate,
|
TabsComponent(view.homeLayout, bus, (activity as HomeActivity).browsingModeManager.isPrivate,
|
||||||
TabsState(sessionManager.sessions.map { it.toSessionViewState(it == sessionManager.selectedSession) })
|
TabsState(sessionManager.sessions.map { it.toSessionViewState(it == sessionManager.selectedSession) })
|
||||||
)
|
)
|
||||||
SessionsComponent(view.homeLayout, bus, (activity as HomeActivity).browsingModeManager.isPrivate)
|
SessionsComponent(view.homeLayout, bus)
|
||||||
layoutComponents(view)
|
layoutComponents(view)
|
||||||
ActionBusFactory.get(this).logMergedObservables()
|
ActionBusFactory.get(this).logMergedObservables()
|
||||||
val activity = activity as HomeActivity
|
val activity = activity as HomeActivity
|
||||||
|
@ -64,6 +68,16 @@ class HomeFragment : Fragment() {
|
||||||
|
|
||||||
setupHomeMenu()
|
setupHomeMenu()
|
||||||
|
|
||||||
|
val bundles = requireComponents.core.sessionStorage.bundles(40)
|
||||||
|
|
||||||
|
bundles.observe(this, Observer {sessionBundles ->
|
||||||
|
val archivedSessions = sessionBundles.mapNotNull { sessionBundle ->
|
||||||
|
sessionBundle.id?.let { ArchivedSession(it, sessionBundle.lastSavedAt, sessionBundle.urls) }
|
||||||
|
}
|
||||||
|
|
||||||
|
getManagedEmitter<SessionsChange>().onNext(SessionsChange.Changed(archivedSessions))
|
||||||
|
})
|
||||||
|
|
||||||
val searchIcon = requireComponents.search.searchEngineManager.getDefaultSearchEngine(requireContext()).let {
|
val searchIcon = requireComponents.search.searchEngineManager.getDefaultSearchEngine(requireContext()).let {
|
||||||
BitmapDrawable(resources, it.icon)
|
BitmapDrawable(resources, it.icon)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
package org.mozilla.fenix.home.sessions
|
package org.mozilla.fenix.home.sessions
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.text.SpannableString
|
import android.text.SpannableString
|
||||||
import android.text.style.ClickableSpan
|
import android.text.style.ClickableSpan
|
||||||
import android.text.style.ForegroundColorSpan
|
import android.text.style.ForegroundColorSpan
|
||||||
|
@ -16,35 +15,34 @@ import androidx.recyclerview.widget.RecyclerView
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
|
|
||||||
class SessionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
class SessionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
var isPrivate = false
|
private var isPrivate = false
|
||||||
var context: Context? = null
|
private var items = listOf<ArchivedSession>()
|
||||||
|
|
||||||
|
|
||||||
|
fun reloadDatat(items: List<ArchivedSession>) {
|
||||||
|
this.items = items
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
val view = LayoutInflater.from(parent.context).inflate(viewType, parent, false)
|
val view = LayoutInflater.from(parent.context).inflate(viewType, parent, false)
|
||||||
|
|
||||||
return when (viewType) {
|
return when (viewType) {
|
||||||
HeaderViewHolder.LAYOUT_ID -> HeaderViewHolder(view)
|
HeaderViewHolder.LAYOUT_ID -> HeaderViewHolder(view)
|
||||||
EmptyListViewHolder.LAYOUT_ID -> EmptyListViewHolder(view)
|
|
||||||
PrivateEmptyListViewHolder.LAYOUT_ID -> PrivateEmptyListViewHolder(view)
|
|
||||||
else -> EmptyListViewHolder(view)
|
else -> EmptyListViewHolder(view)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemViewType(position: Int) = when (position) {
|
override fun getItemViewType(position: Int) = when (position) {
|
||||||
0 -> HeaderViewHolder.LAYOUT_ID
|
0 -> HeaderViewHolder.LAYOUT_ID
|
||||||
1 -> if (isPrivate) PrivateEmptyListViewHolder.LAYOUT_ID else EmptyListViewHolder.LAYOUT_ID
|
else -> EmptyListViewHolder.LAYOUT_ID
|
||||||
else -> -1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int = 2
|
override fun getItemCount(): Int = items.size + 1
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
when (holder) {
|
when (holder) {
|
||||||
is HeaderViewHolder -> if (isPrivate) {
|
is HeaderViewHolder -> holder.headerText.text = "Today"
|
||||||
holder.headerText.text = "Private Session"
|
|
||||||
} else {
|
|
||||||
holder.headerText.text = "Today"
|
|
||||||
}
|
|
||||||
is PrivateEmptyListViewHolder -> {
|
is PrivateEmptyListViewHolder -> {
|
||||||
// Format the description text to include a hyperlink
|
// Format the description text to include a hyperlink
|
||||||
val descriptionText = String
|
val descriptionText = String
|
||||||
|
@ -66,21 +64,21 @@ class SessionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class HeaderViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
|
private class HeaderViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||||
val headerText = view.findViewById<TextView>(R.id.header_text)
|
val headerText = view.findViewById<TextView>(R.id.header_text)
|
||||||
companion object {
|
companion object {
|
||||||
const val LAYOUT_ID = R.layout.session_list_header
|
const val LAYOUT_ID = R.layout.session_list_header
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class PrivateEmptyListViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
|
private class PrivateEmptyListViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||||
val description = view.findViewById<TextView>(R.id.session_description)
|
val description = view.findViewById<TextView>(R.id.session_description)
|
||||||
companion object {
|
companion object {
|
||||||
const val LAYOUT_ID = R.layout.session_list_empty_private
|
const val LAYOUT_ID = R.layout.session_list_empty_private
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class EmptyListViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
|
private class EmptyListViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||||
companion object {
|
companion object {
|
||||||
const val LAYOUT_ID = R.layout.session_list_empty
|
const val LAYOUT_ID = R.layout.session_list_empty
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,11 @@ import org.mozilla.fenix.mvi.Change
|
||||||
import org.mozilla.fenix.mvi.UIComponent
|
import org.mozilla.fenix.mvi.UIComponent
|
||||||
import org.mozilla.fenix.mvi.ViewState
|
import org.mozilla.fenix.mvi.ViewState
|
||||||
|
|
||||||
|
data class ArchivedSession(val id: Long, private val savedAt: Long, val urls: List<String>)
|
||||||
|
|
||||||
class SessionsComponent(
|
class SessionsComponent(
|
||||||
private val container: ViewGroup,
|
private val container: ViewGroup,
|
||||||
bus: ActionBusFactory,
|
bus: ActionBusFactory,
|
||||||
private val isPrivate: Boolean,
|
|
||||||
override var initialState: SessionsState = SessionsState(emptyList())
|
override var initialState: SessionsState = SessionsState(emptyList())
|
||||||
) :
|
) :
|
||||||
UIComponent<SessionsState, SessionsAction, SessionsChange>(
|
UIComponent<SessionsState, SessionsAction, SessionsChange>(
|
||||||
|
@ -25,23 +26,23 @@ class SessionsComponent(
|
||||||
|
|
||||||
override val reducer: (SessionsState, SessionsChange) -> SessionsState = { state, change ->
|
override val reducer: (SessionsState, SessionsChange) -> SessionsState = { state, change ->
|
||||||
when (change) {
|
when (change) {
|
||||||
is SessionsChange.Changed -> state // copy state with changes here
|
is SessionsChange.Changed -> state.copy(archivedSessions = change.archivedSessions) // copy state with changes here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun initView() = SessionsUIView(container, actionEmitter, isPrivate, changesObservable)
|
override fun initView() = SessionsUIView(container, actionEmitter, changesObservable)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
render(reducer)
|
render(reducer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class SessionsState(val sessions: List<Session>, val isPrivate: Boolean = false) : ViewState
|
data class SessionsState(val archivedSessions: List<ArchivedSession>) : ViewState
|
||||||
|
|
||||||
sealed class SessionsAction : Action {
|
sealed class SessionsAction : Action {
|
||||||
object Select : SessionsAction()
|
data class Select(val archivedSession: ArchivedSession) : SessionsAction()
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class SessionsChange : Change {
|
sealed class SessionsChange : Change {
|
||||||
data class Changed(val isPrivate: Boolean) : SessionsChange()
|
data class Changed(val archivedSessions: List<ArchivedSession>) : SessionsChange()
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ import org.mozilla.fenix.mvi.UIView
|
||||||
class SessionsUIView(
|
class SessionsUIView(
|
||||||
container: ViewGroup,
|
container: ViewGroup,
|
||||||
actionEmitter: Observer<SessionsAction>,
|
actionEmitter: Observer<SessionsAction>,
|
||||||
isPrivate: Boolean,
|
|
||||||
changesObservable: Observable<SessionsChange>
|
changesObservable: Observable<SessionsChange>
|
||||||
) :
|
) :
|
||||||
UIView<SessionsState, SessionsAction, SessionsChange>(container, actionEmitter, changesObservable) {
|
UIView<SessionsState, SessionsAction, SessionsChange>(container, actionEmitter, changesObservable) {
|
||||||
|
@ -31,12 +30,11 @@ class SessionsUIView(
|
||||||
init {
|
init {
|
||||||
view.apply {
|
view.apply {
|
||||||
layoutManager = LinearLayoutManager(container.context)
|
layoutManager = LinearLayoutManager(container.context)
|
||||||
sessionsAdapter.isPrivate = isPrivate
|
|
||||||
sessionsAdapter.context = context
|
|
||||||
adapter = sessionsAdapter
|
adapter = sessionsAdapter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun updateView() = Consumer<SessionsState> {
|
override fun updateView() = Consumer<SessionsState> {
|
||||||
|
sessionsAdapter.reloadDatat(it.archivedSessions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue