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

Commit

Permalink
Fixes #351 Create home screen component for multitasking
Browse files Browse the repository at this point in the history
  • Loading branch information
colintheshots committed Feb 9, 2019
1 parent 77883c0 commit f09dc24
Show file tree
Hide file tree
Showing 28 changed files with 527 additions and 45 deletions.
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply from: "$project.rootDir/automation/gradle/versionCode.gradle"
apply plugin: 'androidx.navigation.safeargs'

android {
compileSdkVersion 28
Expand Down
7 changes: 2 additions & 5 deletions app/src/main/java/org/mozilla/fenix/HomeActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import mozilla.components.concept.engine.EngineView
import mozilla.components.feature.intent.IntentProcessor
import mozilla.components.support.base.feature.BackHandler
import mozilla.components.support.utils.SafeIntent
import org.mozilla.fenix.browser.BrowserFragment
import org.mozilla.fenix.ext.components

open class HomeActivity : AppCompatActivity() {
Expand Down Expand Up @@ -71,10 +70,8 @@ open class HomeActivity : AppCompatActivity() {
private fun openToBrowser() {
val sessionId = SafeIntent(intent).getStringExtra(IntentProcessor.ACTIVE_SESSION_ID)
val host = supportFragmentManager.findFragmentById(R.id.container) as NavHostFragment

host.navController.navigate(R.id.action_global_browser, Bundle().apply {
putString(BrowserFragment.SESSION_ID, sessionId)
})
val directions = NavGraphDirections.actionGlobalBrowser(sessionId)
host.navController.navigate(directions)
}

companion object {
Expand Down
15 changes: 6 additions & 9 deletions app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,19 @@ class BrowserFragment : Fragment(), BackHandler {
private val findInPageIntegration = ViewBoundFeatureWrapper<FindInPageIntegration>()
private val customTabsToolbarFeature = ViewBoundFeatureWrapper<CustomTabsToolbarFeature>()
private val toolbarIntegration = ViewBoundFeatureWrapper<ToolbarIntegration>()
var sessionId: String? = null

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
sessionId = BrowserFragmentArgs.fromBundle(arguments!!).sessionId
val view = inflater.inflate(R.layout.fragment_browser, container, false)

toolbarComponent = ToolbarComponent(
view.browserLayout,
ActionBusFactory.get(this),
ActionBusFactory.get(this), sessionId,
SearchState("", isEditing = false)
)

Expand Down Expand Up @@ -98,7 +100,7 @@ class BrowserFragment : Fragment(), BackHandler {
.subscribe {
when (it) {
is SearchAction.ToolbarTapped -> Navigation.findNavController(toolbar)
.navigate(R.id.action_browserFragment_to_searchFragment, null, null)
.navigate(BrowserFragmentDirections.actionBrowserFragmentToSearchFragment(null))
is SearchAction.ToolbarMenuItemTapped -> handleToolbarItemInteraction(it)
}
}
Expand All @@ -109,8 +111,6 @@ class BrowserFragment : Fragment(), BackHandler {

(activity as AppCompatActivity).supportActionBar?.hide()

val sessionId = arguments?.getString(SESSION_ID)

val sessionManager = requireComponents.core.sessionManager

contextMenuFeature.set(
Expand Down Expand Up @@ -182,8 +182,6 @@ class BrowserFragment : Fragment(), BackHandler {
if (sessionFeature.onBackPressed()) return true
if (customTabsToolbarFeature.onBackPressed()) return true

// We'll want to improve this when we add multitasking
requireComponents.core.sessionManager.remove()
return false
}

Expand Down Expand Up @@ -211,9 +209,9 @@ class BrowserFragment : Fragment(), BackHandler {
is ToolbarMenu.Item.Forward -> sessionUseCases.goForward.invoke()
is ToolbarMenu.Item.Reload -> sessionUseCases.reload.invoke()
is ToolbarMenu.Item.Settings -> Navigation.findNavController(toolbar)
.navigate(R.id.action_browserFragment_to_settingsFragment, null, null)
.navigate(BrowserFragmentDirections.actionBrowserFragmentToSettingsFragment())
is ToolbarMenu.Item.Library -> Navigation.findNavController(toolbar)
.navigate(R.id.action_browserFragment_to_libraryFragment, null, null)
.navigate(BrowserFragmentDirections.actionBrowserFragmentToLibraryFragment())
is ToolbarMenu.Item.RequestDesktop -> sessionUseCases.requestDesktopSite.invoke(action.item.isChecked)
is ToolbarMenu.Item.Share -> requireComponents.core.sessionManager
.selectedSession?.url?.apply { requireContext().share(this) }
Expand All @@ -231,7 +229,6 @@ class BrowserFragment : Fragment(), BackHandler {
}

companion object {
const val SESSION_ID = "session_id"
private const val REQUEST_CODE_DOWNLOAD_PERMISSIONS = 1
private const val REQUEST_CODE_PROMPT_PERMISSIONS = 2
private const val TOOLBAR_HEIGHT = 56f
Expand Down
21 changes: 21 additions & 0 deletions app/src/main/java/org/mozilla/fenix/ext/View.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* 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.ext

import android.graphics.Rect
import android.view.TouchDelegate
import android.view.View

fun View?.increaseTapArea(extraDps: Int) {
this!!.post {
val touchRect = Rect()
getHitRect(touchRect)
touchRect.top -= extraDps
touchRect.left -= extraDps
touchRect.right += extraDps
touchRect.bottom += extraDps
(parent as View).touchDelegate = TouchDelegate(touchRect, this)
}
}
94 changes: 90 additions & 4 deletions app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

package org.mozilla.fenix.home

import android.annotation.SuppressLint
import android.content.res.Resources
import android.graphics.drawable.BitmapDrawable
import android.os.Bundle
Expand All @@ -16,49 +17,84 @@ import androidx.fragment.app.Fragment
import androidx.navigation.Navigation
import kotlinx.android.synthetic.main.fragment_home.*
import kotlinx.android.synthetic.main.fragment_home.view.*
import kotlinx.android.synthetic.main.tab_list_header.view.*
import mozilla.components.browser.session.Session
import mozilla.components.browser.session.SessionManager
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.increaseTapArea
import org.mozilla.fenix.ThemeManager
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.home.sessions.SessionsComponent
import org.mozilla.fenix.home.sessions.layoutComponents
import org.mozilla.fenix.home.tabs.TabsAction
import org.mozilla.fenix.home.tabs.TabsChange
import org.mozilla.fenix.home.tabs.TabsComponent
import org.mozilla.fenix.home.tabs.TabsState
import org.mozilla.fenix.isPrivate
import org.mozilla.fenix.mvi.ActionBusFactory
import org.mozilla.fenix.mvi.getManagedEmitter
import org.mozilla.fenix.mvi.getSafeManagedObservable
import kotlin.math.roundToInt

class HomeFragment : Fragment() {
private val bus = ActionBusFactory.get(this)
private var sessionObserver: SessionManager.Observer? = null

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_home, container, false)
SessionsComponent(view.homeLayout, ActionBusFactory.get(this))
TabsComponent(view.homeLayout, bus, TabsState(requireComponents.core.sessionManager.sessions))
SessionsComponent(view.homeLayout, bus)
ActionBusFactory.get(this).logMergedObservables()
return view
}

@SuppressLint("CheckResult")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

(activity as AppCompatActivity).supportActionBar?.hide()

layoutComponents(view.homeLayout)

getSafeManagedObservable<TabsAction>()
.subscribe {
when (it) {
is TabsAction.Select -> {
requireComponents.core.sessionManager.select(it.session)
val directions = HomeFragmentDirections.actionHomeFragmentToBrowserFragment(it.session.id)
Navigation.findNavController(view).navigate(directions)
}
is TabsAction.Close -> {
requireComponents.core.sessionManager.remove(it.session)
}
}
}

val searchIcon = requireComponents.search.searchEngineManager.getDefaultSearchEngine(requireContext()).let {
BitmapDrawable(resources, it.icon)
}

// Temporary so we can easily test settings
view.menuButton.setOnClickListener {
Navigation.findNavController(it).navigate(R.id.action_homeFragment_to_settingsFragment, null, null)
val directions = HomeFragmentDirections.actionHomeFragmentToSettingsFragment()
Navigation.findNavController(it).navigate(directions)
}

view.toolbar.setCompoundDrawablesWithIntrinsicBounds(searchIcon, null, null, null)
val roundToInt = (toolbarPaddingDp * Resources.getSystem().displayMetrics.density).roundToInt()
view.toolbar.compoundDrawablePadding = roundToInt
view.toolbar.setOnClickListener { it ->
Navigation.findNavController(it).navigate(R.id.action_homeFragment_to_searchFragment, null, null)
val directions = HomeFragmentDirections.actionHomeFragmentToSearchFragment(null)
Navigation.findNavController(it).navigate(directions)
}
view.add_tab_button.increaseTapArea(addTabButtonIncreaseDps)
view.add_tab_button.setOnClickListener {
val directions = HomeFragmentDirections.actionHomeFragmentToSearchFragment(null)
Navigation.findNavController(it).navigate(directions)
}

// There is currently an issue with visibility changes in ConstraintLayout 2.0.0-alpha3
Expand All @@ -85,6 +121,7 @@ class HomeFragment : Fragment() {
firstKeyTrigger.conditionallyFire(progress)
secondKeyTrigger.conditionallyFire(progress)
}

override fun onTransitionCompleted(p0: MotionLayout?, p1: Int) { }
})

Expand Down Expand Up @@ -148,7 +185,56 @@ class HomeFragment : Fragment() {
}
}

override fun onResume() {
super.onResume()
sessionObserver = subscribeToSessions()
}

override fun onPause() {
super.onPause()
sessionObserver?.let {
requireComponents.core.sessionManager.unregister(it)
}
}

private fun subscribeToSessions(): SessionManager.Observer {
val observer = object : SessionManager.Observer {
override fun onSessionAdded(session: Session) {
super.onSessionAdded(session)
getManagedEmitter<TabsChange>().onNext(
TabsChange.Changed(requireComponents.core.sessionManager.sessions))
}

override fun onSessionRemoved(session: Session) {
super.onSessionRemoved(session)
getManagedEmitter<TabsChange>().onNext(
TabsChange.Changed(requireComponents.core.sessionManager.sessions))
}

override fun onSessionSelected(session: Session) {
super.onSessionSelected(session)
getManagedEmitter<TabsChange>().onNext(
TabsChange.Changed(requireComponents.core.sessionManager.sessions))
}

override fun onSessionsRestored() {
super.onSessionsRestored()
getManagedEmitter<TabsChange>().onNext(
TabsChange.Changed(requireComponents.core.sessionManager.sessions))
}

override fun onAllSessionsRemoved() {
super.onAllSessionsRemoved()
getManagedEmitter<TabsChange>().onNext(
TabsChange.Changed(requireComponents.core.sessionManager.sessions))
}
}
requireComponents.core.sessionManager.register(observer)
return observer
}

companion object {
const val addTabButtonIncreaseDps = 8
const val toolbarPaddingDp = 12f
const val firstKeyTriggerFrame = 55
const val secondKeyTriggerFrame = 90
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,41 @@
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.sessions
package org.mozilla.fenix.home

import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintLayout.LayoutParams.PARENT_ID
import kotlinx.android.synthetic.main.component_sessions.*
import kotlinx.android.synthetic.main.component_tabs.*
import kotlinx.android.synthetic.main.fragment_home.*
import kotlinx.android.synthetic.main.tab_list_header.*
import org.jetbrains.anko.constraint.layout.ConstraintSetBuilder.Side.BOTTOM
import org.jetbrains.anko.constraint.layout.ConstraintSetBuilder.Side.END
import org.jetbrains.anko.constraint.layout.ConstraintSetBuilder.Side.START
import org.jetbrains.anko.constraint.layout.ConstraintSetBuilder.Side.TOP
import org.jetbrains.anko.constraint.layout.applyConstraintSet
import org.mozilla.fenix.home.HomeFragment

fun HomeFragment.layoutComponents(layout: ConstraintLayout) {
layout.applyConstraintSet {
tabs_header {
connect(
TOP to BOTTOM of homeDivider,
START to START of tabs_list,
END to END of PARENT_ID
)
}
tabs_list {
connect(
TOP to BOTTOM of tabs_header,
START to START of PARENT_ID,
END to END of PARENT_ID
)
}
session_list {
connect(
BOTTOM to BOTTOM of PARENT_ID,
TOP to BOTTOM of tabs_list,
START to START of PARENT_ID,
END to END of PARENT_ID,
TOP to BOTTOM of toolbar_wrapper
END to END of PARENT_ID
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class SessionsComponent(

override val reducer: (SessionsState, SessionsChange) -> SessionsState = { state, change ->
when (change) {
is SessionsChange.SessionsChanged -> state // copy state with changes here
is SessionsChange.Changed -> state // copy state with changes here
}
}

Expand All @@ -42,5 +42,5 @@ sealed class SessionsAction : Action {
}

sealed class SessionsChange : Change {
object SessionsChanged : SessionsChange()
object Changed : SessionsChange()
}
Loading

0 comments on commit f09dc24

Please sign in to comment.