Skip to content
This repository has been archived by the owner on Feb 20, 2023. It is now read-only.

Extract current mode from home fragment #5343

Merged
merged 1 commit into from
Sep 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 37 additions & 67 deletions app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
package org.mozilla.fenix.home

import android.animation.Animator
import android.content.Context
import android.content.DialogInterface
import android.graphics.drawable.BitmapDrawable
import android.os.Bundle
Expand Down Expand Up @@ -49,7 +48,6 @@ import mozilla.components.browser.session.SessionManager
import mozilla.components.concept.sync.AccountObserver
import mozilla.components.concept.sync.AuthType
import mozilla.components.concept.sync.OAuthAccount
import mozilla.components.concept.sync.Profile
import mozilla.components.feature.media.ext.getSession
import mozilla.components.feature.media.ext.pauseIfPlaying
import mozilla.components.feature.media.ext.playIfPaused
Expand All @@ -72,17 +70,15 @@ import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.PrivateShortcutCreateManager
import org.mozilla.fenix.components.TabCollectionStorage
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.metrics
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.metrics
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.sessionsOfType
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.toTab
import org.mozilla.fenix.home.sessioncontrol.CollectionAction
import org.mozilla.fenix.home.sessioncontrol.Mode
import org.mozilla.fenix.home.sessioncontrol.OnboardingAction
import org.mozilla.fenix.home.sessioncontrol.OnboardingState
import org.mozilla.fenix.home.sessioncontrol.SessionControlAction
import org.mozilla.fenix.home.sessioncontrol.SessionControlChange
import org.mozilla.fenix.home.sessioncontrol.SessionControlComponent
Expand All @@ -103,7 +99,7 @@ import org.mozilla.fenix.utils.allowUndo
import org.mozilla.fenix.whatsnew.WhatsNew

@SuppressWarnings("TooManyFunctions", "LargeClass")
class HomeFragment : Fragment(), AccountObserver {
class HomeFragment : Fragment() {

private val bus = ActionBusFactory.get(this)

Expand Down Expand Up @@ -141,6 +137,7 @@ class HomeFragment : Fragment(), AccountObserver {

private val onboarding by lazy { FenixOnboarding(requireContext()) }
private lateinit var sessionControlComponent: SessionControlComponent
private lateinit var currentMode: CurrentMode

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Expand All @@ -167,7 +164,12 @@ class HomeFragment : Fragment(), AccountObserver {
): View? {
val view = inflater.inflate(R.layout.fragment_home, container, false)

val mode = currentMode(view.context)
currentMode = CurrentMode(
view.context,
onboarding,
browsingModeManager,
getManagedEmitter()
)

sessionControlComponent = SessionControlComponent(
view.homeLayout,
Expand All @@ -178,10 +180,10 @@ class HomeFragment : Fragment(), AccountObserver {
) {
SessionControlViewModel(
SessionControlState(
listOf(),
setOf(),
emptyList(),
emptySet(),
requireComponents.core.tabCollectionStorage.cachedTabCollections,
mode
currentMode.getCurrentMode()
)
)
}
Expand Down Expand Up @@ -304,17 +306,28 @@ class HomeFragment : Fragment(), AccountObserver {
getManagedEmitter<SessionControlChange>().onNext(
SessionControlChange.Change(
tabs = getListOfSessions().toTabs(),
mode = currentMode(context),
mode = currentMode.getCurrentMode(),
collections = components.core.tabCollectionStorage.cachedTabCollections
)
)

(activity as AppCompatActivity).supportActionBar?.hide()
components.backgroundServices.accountManager.register(this, owner = this)

if (context.settings.showPrivateModeContextualFeatureRecommender &&
browsingModeManager.mode.isPrivate
) {
requireComponents.backgroundServices.accountManager.register(currentMode, owner = this)
requireComponents.backgroundServices.accountManager.register(object : AccountObserver {
override fun onAuthenticated(account: OAuthAccount, authType: AuthType) {
if (authType != AuthType.Existing) {
view?.let {
FenixSnackbar.make(it, Snackbar.LENGTH_SHORT).setText(
it.context.getString(R.string.onboarding_firefox_account_sync_is_on)
).show()
}
}
}
}, owner = this)

if (context.settings().showPrivateModeContextualFeatureRecommender &&
browsingModeManager.mode.isPrivate) {
recommendPrivateBrowsingShortcut()
}
}
Expand All @@ -330,14 +343,8 @@ class HomeFragment : Fragment(), AccountObserver {
private fun handleOnboardingAction(action: OnboardingAction) {
Do exhaustive when (action) {
is OnboardingAction.Finish -> {
onboarding.finish()
homeLayout?.progress = 0F
val mode = currentMode(requireContext())
getManagedEmitter<SessionControlChange>().onNext(
SessionControlChange.ModeChange(
mode
)
)
hideOnboarding()
}
}
}
Expand All @@ -346,7 +353,7 @@ class HomeFragment : Fragment(), AccountObserver {
private fun handleTabAction(action: TabAction) {
Do exhaustive when (action) {
is TabAction.SaveTabGroup -> {
if ((activity as HomeActivity).browsingModeManager.mode.isPrivate) return
if (browsingModeManager.mode.isPrivate) return
invokePendingDeleteJobs()
saveTabToCollection(action.selectedTabSessionId)
}
Expand Down Expand Up @@ -429,7 +436,7 @@ class HomeFragment : Fragment(), AccountObserver {
is TabAction.ShareTabs -> {
invokePendingDeleteJobs()
val shareTabs = sessionManager
.sessionsOfType(private = (activity as HomeActivity).browsingModeManager.mode.isPrivate)
.sessionsOfType(private = browsingModeManager.mode.isPrivate)
.map { ShareTab(it.url, it.title) }
.toList()
share(tabs = shareTabs)
Expand Down Expand Up @@ -616,10 +623,12 @@ class HomeFragment : Fragment(), AccountObserver {
}

private fun hideOnboardingIfNeeded() {
if (!onboarding.userHasBeenOnboarded()) {
onboarding.finish()
emitModeChanges()
}
if (!onboarding.userHasBeenOnboarded()) hideOnboarding()
}

private fun hideOnboarding() {
onboarding.finish()
currentMode.emitModeChanges()
}

private fun setupHomeMenu() {
Expand Down Expand Up @@ -811,45 +820,6 @@ class HomeFragment : Fragment(), AccountObserver {
nav(R.id.homeFragment, directions)
}

private fun currentMode(context: Context): Mode = if (!onboarding.userHasBeenOnboarded()) {
val accountManager = requireComponents.backgroundServices.accountManager
val account = accountManager.authenticatedAccount()
if (account != null) {
Mode.Onboarding(OnboardingState.SignedIn)
} else {
val availableAccounts = accountManager.shareableAccounts(context)
if (availableAccounts.isEmpty()) {
Mode.Onboarding(OnboardingState.SignedOutNoAutoSignIn)
} else {
Mode.Onboarding(OnboardingState.SignedOutCanAutoSignIn(availableAccounts[0]))
}
}
} else {
Mode.fromBrowsingMode(browsingModeManager.mode)
}

private fun emitModeChanges() {
context?.let {
val mode = currentMode(it)
getManagedEmitter<SessionControlChange>().onNext(SessionControlChange.ModeChange(mode))
}
}

override fun onAuthenticated(account: OAuthAccount, authType: AuthType) {
if (authType != AuthType.Existing) {
view?.let {
FenixSnackbar.make(it, Snackbar.LENGTH_SHORT).setText(
it.context.getString(R.string.onboarding_firefox_account_sync_is_on)
).show()
}
}
emitModeChanges()
}

override fun onAuthenticationProblems() = emitModeChanges()
override fun onLoggedOut() = emitModeChanges()
override fun onProfileUpdated(profile: Profile) = emitModeChanges()

private fun scrollAndAnimateCollection(
tabsAddedToCollectionSize: Int,
changedCollection: TabCollection? = null
Expand Down
81 changes: 81 additions & 0 deletions app/src/main/java/org/mozilla/fenix/home/Mode.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/* 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

import android.content.Context
import io.reactivex.Observer
import mozilla.components.concept.sync.AccountObserver
import mozilla.components.concept.sync.AuthType
import mozilla.components.concept.sync.OAuthAccount
import mozilla.components.concept.sync.Profile
import mozilla.components.service.fxa.sharing.ShareableAccount
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.home.sessioncontrol.SessionControlChange
import org.mozilla.fenix.onboarding.FenixOnboarding

/**
* Describes various states of the home fragment UI.
*/
sealed class Mode {
object Normal : Mode()
object Private : Mode()
data class Onboarding(val state: OnboardingState) : Mode()

companion object {
fun fromBrowsingMode(browsingMode: BrowsingMode) = when (browsingMode) {
BrowsingMode.Normal -> Normal
BrowsingMode.Private -> Private
}
}
}

/**
* Describes various onboarding states.
*/
sealed class OnboardingState {
// Signed out, without an option to auto-login using a shared FxA account.
object SignedOutNoAutoSignIn : OnboardingState()
// Signed out, with an option to auto-login into a shared FxA account.
data class SignedOutCanAutoSignIn(val withAccount: ShareableAccount) : OnboardingState()
// Signed in.
object SignedIn : OnboardingState()
}

class CurrentMode(
private val context: Context,
private val onboarding: FenixOnboarding,
private val browsingModeManager: BrowsingModeManager,
private val emitter: Observer<SessionControlChange>
) : AccountObserver {

private val accountManager = context.components.backgroundServices.accountManager

fun getCurrentMode() = if (onboarding.userHasBeenOnboarded()) {
Mode.fromBrowsingMode(browsingModeManager.mode)
} else {
val account = accountManager.authenticatedAccount()
if (account != null) {
Mode.Onboarding(OnboardingState.SignedIn)
} else {
val availableAccounts = accountManager.shareableAccounts(context)
if (availableAccounts.isEmpty()) {
Mode.Onboarding(OnboardingState.SignedOutNoAutoSignIn)
} else {
Mode.Onboarding(OnboardingState.SignedOutCanAutoSignIn(availableAccounts[0]))
}
}
}

fun emitModeChanges() {
emitter.onNext(SessionControlChange.ModeChange(getCurrentMode()))
}

override fun onAuthenticated(account: OAuthAccount, authType: AuthType) = emitModeChanges()
override fun onAuthenticationProblems() = emitModeChanges()
override fun onLoggedOut() = emitModeChanges()
override fun onProfileUpdated(profile: Profile) = emitModeChanges()
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import androidx.recyclerview.widget.RecyclerView
import io.reactivex.Observer
import kotlinx.android.synthetic.main.tab_list_row.*
import mozilla.components.feature.media.state.MediaState
import org.mozilla.fenix.home.OnboardingState
import org.mozilla.fenix.home.sessioncontrol.viewholders.CollectionHeaderViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.CollectionViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.NoContentMessageViewHolder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ import androidx.recyclerview.widget.RecyclerView
import io.reactivex.Observer
import mozilla.components.browser.session.Session
import mozilla.components.feature.media.state.MediaState
import mozilla.components.service.fxa.sharing.ShareableAccount
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.home.Mode
import org.mozilla.fenix.mvi.Action
import org.mozilla.fenix.mvi.ActionBusFactory
import org.mozilla.fenix.mvi.Change
Expand Down Expand Up @@ -64,31 +63,6 @@ fun List<Tab>.toSessionBundle(context: Context): MutableList<Session> {
return sessionBundle
}

/**
* Describes various onboarding states.
*/
sealed class OnboardingState {
// Signed out, without an option to auto-login using a shared FxA account.
object SignedOutNoAutoSignIn : OnboardingState()
// Signed out, with an option to auto-login into a shared FxA account.
data class SignedOutCanAutoSignIn(val withAccount: ShareableAccount) : OnboardingState()
// Signed in.
object SignedIn : OnboardingState()
}

sealed class Mode {
object Normal : Mode()
object Private : Mode()
data class Onboarding(val state: OnboardingState) : Mode()

companion object {
fun fromBrowsingMode(browsingMode: BrowsingMode) = when (browsingMode) {
BrowsingMode.Normal -> Normal
BrowsingMode.Private -> Private
}
}
}

data class SessionControlState(
val tabs: List<Tab>,
val expandedCollections: Set<Long>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import io.reactivex.Observable
import io.reactivex.Observer
import io.reactivex.functions.Consumer
import org.mozilla.fenix.R
import org.mozilla.fenix.home.Mode
import org.mozilla.fenix.home.OnboardingState
import org.mozilla.fenix.mvi.UIView

val noTabMessage = AdapterItem.NoContentMessage(
Expand Down
Loading