diff --git a/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationComponent.kt b/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationComponent.kt index b28bca799a..c822da7540 100644 --- a/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationComponent.kt +++ b/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationComponent.kt @@ -1,5 +1,9 @@ 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.ViewGroup import org.mozilla.fenix.mvi.Action import org.mozilla.fenix.mvi.ActionBusFactory @@ -8,16 +12,17 @@ import org.mozilla.fenix.mvi.Reducer import org.mozilla.fenix.mvi.UIComponent import org.mozilla.fenix.mvi.ViewState -/* 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/. */ +data class Tab( + val sessionId: String, + val url: String, + val hostname: String, + val title: String +) -sealed class CollectionCreationState : ViewState { - object Empty : CollectionCreationState() -} +data class CollectionCreationState(val tabs: List = listOf()) : ViewState sealed class CollectionCreationChange : Change { - + data class TabListChange(val tabs: List) : CollectionCreationChange() } sealed class CollectionCreationAction : Action { @@ -27,13 +32,15 @@ sealed class CollectionCreationAction : Action { class CollectionCreationComponent( private val container: ViewGroup, bus: ActionBusFactory, - override var initialState: CollectionCreationState = CollectionCreationState.Empty + override var initialState: CollectionCreationState = CollectionCreationState() ) : UIComponent( bus.getManagedEmitter(CollectionCreationAction::class.java), bus.getSafeManagedObservable(CollectionCreationChange::class.java) ) { override val reducer: Reducer = { state, change -> - CollectionCreationState.Empty + when (change) { + is CollectionCreationChange.TabListChange -> state.copy(tabs = change.tabs) + } } override fun initView() = CollectionCreationUIView(container, actionEmitter, changesObservable) diff --git a/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationTabListAdapter.kt b/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationTabListAdapter.kt new file mode 100644 index 0000000000..b64416f534 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationTabListAdapter.kt @@ -0,0 +1,86 @@ +package org.mozilla.fenix.collections + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import io.reactivex.Observer +import kotlinx.android.synthetic.main.collection_tab_list_row.view.* +import kotlinx.android.synthetic.main.tab_list_row.* +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import mozilla.components.browser.icons.IconRequest +import org.mozilla.fenix.R +import org.mozilla.fenix.ext.components +import kotlin.coroutines.CoroutineContext + +class CollectionCreationTabListAdapter( + val actionEmitter: Observer +) : RecyclerView.Adapter() { + + + private var data: List = listOf() + private lateinit var job: Job + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TabViewHolder { + val view = LayoutInflater.from(parent.context).inflate(TabViewHolder.LAYOUT_ID, parent, false) + + return TabViewHolder(view, actionEmitter, job) + } + + override fun onBindViewHolder(holder: TabViewHolder, position: Int) { + holder.bind(data[position]) + } + + override fun getItemCount(): Int = data.size + + override fun onAttachedToRecyclerView(recyclerView: RecyclerView) { + super.onAttachedToRecyclerView(recyclerView) + job = Job() + } + + override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) { + super.onDetachedFromRecyclerView(recyclerView) + job.cancel() + } + + fun updateData(tabs: List) { + data = tabs + notifyDataSetChanged() + } +} + +class TabViewHolder( + val view: View, + actionEmitter: Observer, + val job: Job +) : + RecyclerView.ViewHolder(view), CoroutineScope { + + override val coroutineContext: CoroutineContext + get() = Dispatchers.IO + job + + var tab: Tab? = null + + init { } + + fun bind(tab: Tab) { + this.tab = tab + + view.hostname.text = tab.hostname + view.tab_title.text = tab.title + launch(Dispatchers.IO) { + val bitmap = view.favicon_image.context.components.utils.icons + .loadIcon(IconRequest(tab.url)).await().bitmap + launch(Dispatchers.Main) { + view.favicon_image.setImageBitmap(bitmap) + } + } + } + + companion object { + const val LAYOUT_ID = R.layout.collection_tab_list_row + } +} \ No newline at end of file diff --git a/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationUIView.kt b/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationUIView.kt index 40779bd15f..b72e5301b4 100644 --- a/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationUIView.kt +++ b/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationUIView.kt @@ -4,12 +4,16 @@ package org.mozilla.fenix.collections 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.util.Log import android.view.LayoutInflater import android.view.ViewGroup +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import org.mozilla.fenix.R import io.reactivex.Observer import io.reactivex.Observable import io.reactivex.functions.Consumer +import kotlinx.android.synthetic.main.component_collection_creation.view.* import org.mozilla.fenix.mvi.UIView class CollectionCreationUIView( @@ -24,7 +28,24 @@ class CollectionCreationUIView( override val view = LayoutInflater.from(container.context) .inflate(R.layout.component_collection_creation, container, true) - override fun updateView() = Consumer { + private val collectionCreationTabListAdapter = CollectionCreationTabListAdapter(actionEmitter) + + init { + view.back_button.setOnClickListener { + Log.e("Collection Creation", "Back button tapped") + } + + view.select_all_button.setOnClickListener { + Log.e("Collection Creation", "Select All Tapped!") + } + view.tab_list.run { + adapter = collectionCreationTabListAdapter + layoutManager = LinearLayoutManager(container.context, RecyclerView.VERTICAL, true) + } + } + + override fun updateView() = Consumer { + collectionCreationTabListAdapter.updateData(it.tabs) } } \ No newline at end of file diff --git a/app/src/main/java/org/mozilla/fenix/collections/CreateCollectionFragment.kt b/app/src/main/java/org/mozilla/fenix/collections/CreateCollectionFragment.kt index 892b68fce9..a38abaf510 100644 --- a/app/src/main/java/org/mozilla/fenix/collections/CreateCollectionFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/collections/CreateCollectionFragment.kt @@ -9,9 +9,11 @@ import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.lifecycle.ViewModelProviders import kotlinx.android.synthetic.main.fragment_create_collection.view.* import org.mozilla.fenix.R import org.mozilla.fenix.mvi.ActionBusFactory +import org.mozilla.fenix.mvi.getManagedEmitter class CreateCollectionFragment : Fragment() { @@ -30,4 +32,13 @@ class CreateCollectionFragment : Fragment() { return view } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + val tabs = activity?.run { + ViewModelProviders.of(this).get(CreateCollectionViewModel::class.java) + }!!.tabs + + getManagedEmitter().onNext(CollectionCreationChange.TabListChange(tabs)) + } } diff --git a/app/src/main/java/org/mozilla/fenix/collections/CreateCollectionViewModel.kt b/app/src/main/java/org/mozilla/fenix/collections/CreateCollectionViewModel.kt new file mode 100644 index 0000000000..9d2ba952df --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/collections/CreateCollectionViewModel.kt @@ -0,0 +1,11 @@ +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 androidx.lifecycle.ViewModel + +class CreateCollectionViewModel: ViewModel() { + var tabs = listOf() +} diff --git a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt index 28557ff347..ab38859240 100644 --- a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt @@ -17,6 +17,7 @@ import android.view.View import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProviders import androidx.navigation.Navigation import kotlinx.android.synthetic.main.fragment_home.* import kotlinx.android.synthetic.main.fragment_home.view.* @@ -32,6 +33,8 @@ import org.mozilla.fenix.BrowsingModeManager import org.mozilla.fenix.DefaultThemeManager import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R +import org.mozilla.fenix.collections.CreateCollectionViewModel +import org.mozilla.fenix.collections.Tab import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.share @@ -177,6 +180,13 @@ class HomeFragment : Fragment(), CoroutineScope { private fun handleTabAction(action: TabAction) { Do exhaustive when (action) { is TabAction.SaveTabGroup -> { + val tabs = requireComponents.core.sessionManager.sessions + .map { Tab(it.id, it.url, it.url.urlToHost(), it.title) } + + activity?.run { + ViewModelProviders.of(this).get(CreateCollectionViewModel::class.java) + }!!.tabs = tabs + val direction = HomeFragmentDirections.actionHomeFragmentToCreateCollectionFragment() Navigation.findNavController(view!!).navigate(direction) } diff --git a/app/src/main/res/layout/collection_tab_list_row.xml b/app/src/main/res/layout/collection_tab_list_row.xml new file mode 100644 index 0000000000..1d624f16a8 --- /dev/null +++ b/app/src/main/res/layout/collection_tab_list_row.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/component_collection_creation.xml b/app/src/main/res/layout/component_collection_creation.xml index 0b7ce87d32..a0a3826b1e 100644 --- a/app/src/main/res/layout/component_collection_creation.xml +++ b/app/src/main/res/layout/component_collection_creation.xml @@ -24,6 +24,7 @@ app:layout_constraintStart_toStartOf="parent" />