/* 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.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import io.reactivex.Observable import io.reactivex.Observer import io.reactivex.functions.Consumer import org.mozilla.fenix.R import org.mozilla.fenix.mvi.UIView import androidx.recyclerview.widget.ItemTouchHelper private fun normalModeAdapterItems( tabs: List, collections: List, expandedCollections: Set ): List { val items = mutableListOf() items.add(AdapterItem.TabHeader(false, tabs.isNotEmpty())) if (tabs.isNotEmpty()) { items.addAll(tabs.reversed().map(AdapterItem::TabItem)) items.add(AdapterItem.SaveTabGroup) } else { items.add(AdapterItem.NoTabMessage) } items.add(AdapterItem.CollectionHeader) if (collections.isNotEmpty()) { // If the collection is expanded, we want to add all of its tabs beneath it in the adapter collections.map(AdapterItem::CollectionItem).forEach { items.add(it) if (it.collection.isExpanded(expandedCollections)) { items.addAll(collectionTabItems(it.collection)) } } } else { items.add(AdapterItem.NoCollectionMessage) } return items } private fun privateModeAdapterItems(tabs: List): List { val items = mutableListOf() items.add(AdapterItem.TabHeader(true, tabs.isNotEmpty())) if (tabs.isNotEmpty()) { items.addAll(tabs.reversed().map(AdapterItem::TabItem)) } else { items.add(AdapterItem.PrivateBrowsingDescription) } return items } private fun onboardingAdapterItems(onboardingState: OnboardingState): List { val items: MutableList = mutableListOf(AdapterItem.OnboardingHeader) // Customize FxA items based on where we are with the account state: items.addAll(when (onboardingState) { OnboardingState.SignedOut -> { listOf( AdapterItem.OnboardingSectionHeader { it.getString(R.string.onboarding_fxa_section_header) }, AdapterItem.OnboardingFirefoxAccount(onboardingState) ) } OnboardingState.AutoSignedIn -> { listOf( AdapterItem.OnboardingFirefoxAccount(onboardingState) ) } else -> listOf() }) items.addAll(listOf( AdapterItem.OnboardingSectionHeader { val appName = it.getString(R.string.app_name) it.getString(R.string.onboarding_feature_section_header, appName) }, AdapterItem.OnboardingThemePicker, AdapterItem.OnboardingTrackingProtection, AdapterItem.OnboardingPrivateBrowsing, AdapterItem.OnboardingPrivacyNotice, AdapterItem.OnboardingFinish )) return items } private fun SessionControlState.toAdapterList(): List = when (mode) { is Mode.Normal -> normalModeAdapterItems(tabs, collections, expandedCollections) is Mode.Private -> privateModeAdapterItems(tabs) is Mode.Onboarding -> onboardingAdapterItems(mode.state) } private fun collectionTabItems(collection: TabCollection) = collection.tabs.mapIndexed { index, tab -> AdapterItem.TabInCollectionItem(collection, tab, index == collection.tabs.lastIndex) } private fun TabCollection.isExpanded(expandedCollections: Set): Boolean { return expandedCollections.contains(this.id) } class SessionControlUIView( container: ViewGroup, actionEmitter: Observer, changesObservable: Observable ) : UIView( container, actionEmitter, changesObservable ) { override val view: RecyclerView = LayoutInflater.from(container.context) .inflate(R.layout.component_session_control, container, true) .findViewById(R.id.home_component) private val sessionControlAdapter = SessionControlAdapter(actionEmitter) init { view.apply { adapter = sessionControlAdapter layoutManager = LinearLayoutManager(container.context) val itemTouchHelper = ItemTouchHelper( SwipeToDeleteCallback( actionEmitter ) ) itemTouchHelper.attachToRecyclerView(this) } } override fun updateView() = Consumer { sessionControlAdapter.reloadData(it.toAdapterList(), it.expandedCollections) actionEmitter.onNext(SessionControlAction.ReloadData) } }