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

Tabs! 🔁 #48

Merged
merged 6 commits into from
Jul 9, 2018
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
14 changes: 12 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ android {
}
}

kotlin {
experimental {
coroutines 'enable'
}
}

lintOptions {
lintConfig file("${rootDir}/config/lint.xml")
}
Expand Down Expand Up @@ -100,7 +106,7 @@ repositories {
}

////////////////////////////////////////////////////////////////////////////////////////////
// GeckoView Release (60.0.2)
// GeckoView Release
////////////////////////////////////////////////////////////////////////////////////////////

// ARM
Expand Down Expand Up @@ -140,12 +146,14 @@ dependencies {
implementation "org.mozilla.components:engine:${rootProject.ext.dependencies['mozillaComponents']}"
implementation "org.mozilla.components:search:${rootProject.ext.dependencies['mozillaComponents']}"
implementation "org.mozilla.components:session:${rootProject.ext.dependencies['mozillaComponents']}"

implementation "org.mozilla.components:tabstray:${rootProject.ext.dependencies['mozillaComponents']}"
implementation "org.mozilla.components:abstract-toolbar:${rootProject.ext.dependencies['mozillaComponents']}"
implementation "org.mozilla.components:toolbar:${rootProject.ext.dependencies['mozillaComponents']}"
implementation "org.mozilla.photon:icons:${rootProject.ext.dependencies['mozillaComponents']}"

implementation "org.mozilla.components:feature-search:${rootProject.ext.dependencies['mozillaComponents']}"
implementation "org.mozilla.components:feature-session:${rootProject.ext.dependencies['mozillaComponents']}"
implementation "org.mozilla.components:feature-tabs:${rootProject.ext.dependencies['mozillaComponents']}"
implementation "org.mozilla.components:feature-toolbar:${rootProject.ext.dependencies['mozillaComponents']}"

implementation "org.mozilla.components:autocomplete:${rootProject.ext.dependencies['mozillaComponents']}"
Expand All @@ -171,6 +179,8 @@ dependencies {
productionAarch64Implementation "org.mozilla:geckoview-release-arm64-v8a:${rootProject.ext.geckoRelease['version']}"

implementation "com.android.support:appcompat-v7:${rootProject.ext.dependencies['supportLibraries']}"
implementation "com.android.support.constraint:constraint-layout:1.1.2"

implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${rootProject.ext.dependencies['kotlin']}"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:${rootProject.ext.dependencies['coroutines']}"
implementation "com.android.support.constraint:constraint-layout:${rootProject.ext.dependencies['constraintLayout']}"
Expand Down
17 changes: 0 additions & 17 deletions app/src/beta/java/org/mozilla/samples/browser/EngineProvider.kt

This file was deleted.

53 changes: 20 additions & 33 deletions app/src/main/java/mozilla/fenix/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,53 +9,40 @@ import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.util.AttributeSet
import android.view.View
import kotlinx.android.synthetic.main.activity_main.*
import mozilla.components.browser.tabstray.BrowserTabsTray
import mozilla.components.concept.engine.EngineView
import mozilla.components.feature.session.SessionFeature
import mozilla.components.feature.toolbar.ToolbarFeature
import mozilla.fenix.components.FeatureLifecycleObserver
import mozilla.components.concept.tabstray.TabsTray
import mozilla.fenix.ext.components
import mozilla.fenix.fragment.BackHandler
import mozilla.fenix.fragment.BrowserFragment

class MainActivity : AppCompatActivity() {
private lateinit var toolbarFeature: ToolbarFeature
private lateinit var sessionFeature: SessionFeature

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

toolbar.setMenuBuilder(components.menuBuilder)

toolbarFeature = ToolbarFeature(
toolbar,
components.sessionManager,
components.sessionUseCases.loadUrl,
components.defaultSearchUseCase)

sessionFeature = SessionFeature(
components.sessionManager,
components.sessionUseCases,
engineView,
components.sessionStorage)

lifecycle.addObserver(FeatureLifecycleObserver(sessionFeature, toolbarFeature))
if (savedInstanceState == null) {
supportFragmentManager?.beginTransaction()?.apply {
replace(R.id.container, BrowserFragment.create())
commit()
}
}
}

override fun onBackPressed() {
if (toolbarFeature.handleBackPressed())
return

if (sessionFeature.handleBackPressed())
return
supportFragmentManager.fragments.forEach {
if (it is BackHandler && it.onBackPressed()) {
return
}
}

super.onBackPressed()
}

override fun onCreateView(parent: View?, name: String?, context: Context?, attrs: AttributeSet?): View? {
if (name == EngineView::class.java.name) {
return components.engine.createView(context!!, attrs).asView()
override fun onCreateView(parent: View?, name: String?, context: Context, attrs: AttributeSet?): View? =
when (name) {
EngineView::class.java.name -> components.engine.createView(context, attrs).asView()
TabsTray::class.java.name -> BrowserTabsTray(context, attrs)
else -> super.onCreateView(parent, name, context, attrs)
}

return super.onCreateView(parent, name, context, attrs)
}
}
18 changes: 13 additions & 5 deletions app/src/main/java/mozilla/fenix/components/Components.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
package mozilla.fenix.components

import android.content.Context
import kotlinx.coroutines.experimental.async
import kotlinx.coroutines.experimental.launch
import mozilla.components.browser.engine.gecko.GeckoEngine
import mozilla.components.browser.menu.BrowserMenuBuilder
import mozilla.components.browser.menu.item.BrowserMenuItemToolbar
import mozilla.components.browser.search.SearchEngineManager
Expand All @@ -15,22 +16,26 @@ import mozilla.components.browser.session.storage.DefaultSessionStorage
import mozilla.components.concept.engine.Engine
import mozilla.components.feature.search.SearchUseCases
import mozilla.components.feature.session.SessionUseCases
import mozilla.components.feature.tabs.TabsUseCases
import mozilla.fenix.R
import org.mozilla.samples.browser.EngineProvider
import org.mozilla.geckoview.GeckoRuntime

/**
* Helper class for lazily instantiating components needed by the application.
*/
class Components(private val applicationContext: Context) {
// Engine
val engine: Engine by lazy { EngineProvider.createEngine(applicationContext) }
val engine: Engine by lazy {
val runtime = GeckoRuntime.getDefault(applicationContext)
GeckoEngine(runtime)
}

// Session
val sessionStorage by lazy { DefaultSessionStorage(applicationContext) }

val sessionManager by lazy {
SessionManager(engine).apply {
sessionStorage.restore(engine, this)
sessionStorage.restore(this)

if (size == 0) {
val initialSession = Session("https://www.mozilla.org")
Expand All @@ -44,7 +49,7 @@ class Components(private val applicationContext: Context) {
// Search
private val searchEngineManager by lazy {
SearchEngineManager().apply {
async { load(applicationContext) }
launch { load(applicationContext) }
}
}
private val searchUseCases = SearchUseCases(applicationContext, searchEngineManager, sessionManager)
Expand Down Expand Up @@ -75,4 +80,7 @@ class Components(private val applicationContext: Context) {

BrowserMenuItemToolbar(listOf(forward, refresh))
}

// Tabs
val tabsUseCases: TabsUseCases by lazy { TabsUseCases(sessionManager) }
}
14 changes: 14 additions & 0 deletions app/src/main/java/mozilla/fenix/ext/Fragment.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* 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 mozilla.fenix.ext

import android.support.v4.app.Fragment
import mozilla.fenix.components.Components

/**
* Get the components of this application.
*/
val Fragment.components: Components
get() = activity!!.components
12 changes: 12 additions & 0 deletions app/src/main/java/mozilla/fenix/fragment/BackHandler.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* 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 mozilla.fenix.fragment

/**
* Interface for fragments that want to handle 'back' button presses.
*/
interface BackHandler {
fun onBackPressed(): Boolean
}
97 changes: 97 additions & 0 deletions app/src/main/java/mozilla/fenix/fragment/BrowserFragment.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/* 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 mozilla.fenix.fragment

import android.os.Bundle
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import kotlinx.android.synthetic.main.fragment_browser.*
import mozilla.components.feature.session.SessionFeature
import mozilla.components.feature.tabs.toolbar.TabsToolbarFeature
import mozilla.components.feature.toolbar.ToolbarFeature
import mozilla.fenix.ext.components
import mozilla.fenix.R

class BrowserFragment : Fragment(), BackHandler {
private lateinit var sessionFeature: SessionFeature
private lateinit var toolbarFeature: ToolbarFeature
private lateinit var tabsToolbarFeature: TabsToolbarFeature

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_browser, container, false)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

toolbar.setMenuBuilder(components.menuBuilder)

val sessionId = arguments?.getString(SESSION_ID)

sessionFeature = SessionFeature(
components.sessionManager,
components.sessionUseCases,
engineView,
components.sessionStorage,
sessionId)

toolbarFeature = ToolbarFeature(
toolbar,
components.sessionManager,
components.sessionUseCases.loadUrl,
components.defaultSearchUseCase,
sessionId)

tabsToolbarFeature = TabsToolbarFeature(context!!, toolbar, ::showTabs)
}

private fun showTabs() {
// For now we are performing manual fragment transactions here. Once we can use the new
// navigation support library we may want to pass navigation graphs around.
activity?.supportFragmentManager?.beginTransaction()?.apply {
replace(R.id.container, TabsTrayFragment())
commit()
}
}

override fun onStart() {
super.onStart()

sessionFeature.start()
toolbarFeature.start()
}

override fun onStop() {
super.onStop()

sessionFeature.stop()
toolbarFeature.stop()
}

@Suppress("ReturnCount")
override fun onBackPressed(): Boolean {
if (toolbarFeature.handleBackPressed()) {
return true
}

if (sessionFeature.handleBackPressed()) {
return true
}

return false
}

companion object {
private const val SESSION_ID = "session_id"

fun create(sessionId: String? = null): BrowserFragment = BrowserFragment().apply {
arguments = Bundle().apply {
putString(SESSION_ID, sessionId)
}
}
}
}
71 changes: 71 additions & 0 deletions app/src/main/java/mozilla/fenix/fragment/TabsTrayFragment.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/* 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 mozilla.fenix.fragment

import android.os.Bundle
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import kotlinx.android.synthetic.main.fragment_tabstray.*
import mozilla.components.feature.tabs.tabstray.TabsFeature
import mozilla.fenix.R
import mozilla.fenix.ext.components

/**
* A fragment for displaying the tabs tray.
*/
class TabsTrayFragment : Fragment(), BackHandler {
private var tabsFeature: TabsFeature? = null

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
inflater.inflate(R.layout.fragment_tabstray, container, false)

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

toolbar.setNavigationIcon(R.drawable.mozac_ic_back)
toolbar.setNavigationOnClickListener {
closeTabsTray()
}

toolbar.inflateMenu(R.menu.menu_tabstray)
toolbar.setOnMenuItemClickListener {
when (it.itemId) {
R.id.newTab -> {
components.tabsUseCases.addSession.invoke("about:blank", selectTab = true)
closeTabsTray()
}
}
true
}

tabsFeature = TabsFeature(tabsTray, components.sessionManager, components.tabsUseCases, ::closeTabsTray)
}

override fun onStart() {
super.onStart()

tabsFeature?.start()
}

override fun onStop() {
super.onStop()

tabsFeature?.stop()
}

override fun onBackPressed(): Boolean {
closeTabsTray()
return true
}

private fun closeTabsTray() {
activity?.supportFragmentManager?.beginTransaction()?.apply {
replace(R.id.container, BrowserFragment.create())
commit()
}
}
}
Loading