1
0
Fork 0

Fixes #354: Overflow menu for multitasking in current session

master
Colin Lee 2019-02-10 19:30:37 -06:00
parent 06890d0837
commit ee229c9709
16 changed files with 309 additions and 93 deletions

View File

@ -25,6 +25,8 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
shrinkResources false
minifyEnabled false
applicationIdSuffix ".debug"
}
}

View File

@ -17,14 +17,12 @@ 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.menu.BrowserMenu
import mozilla.components.browser.session.Session
import mozilla.components.browser.session.SessionManager
import org.mozilla.fenix.DefaultThemeManager
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
@ -92,12 +90,7 @@ class HomeFragment : Fragment() {
view.toolbar.setCompoundDrawablesWithIntrinsicBounds(searchIcon, null, null, null)
val roundToInt = (toolbarPaddingDp * Resources.getSystem().displayMetrics.density).roundToInt()
view.toolbar.compoundDrawablePadding = roundToInt
view.toolbar.setOnClickListener { it ->
val directions = HomeFragmentDirections.actionHomeFragmentToSearchFragment(null)
Navigation.findNavController(it).navigate(directions)
}
view.add_tab_button.increaseTapArea(addTabButtonIncreaseDps)
view.add_tab_button.setOnClickListener {
view.toolbar.setOnClickListener {
val directions = HomeFragmentDirections.actionHomeFragmentToSearchFragment(null)
Navigation.findNavController(it).navigate(directions)
}
@ -210,6 +203,7 @@ class HomeFragment : Fragment() {
companion object {
const val addTabButtonIncreaseDps = 8
const val overflowButtonIncreaseDps = 8
const val toolbarPaddingDp = 12f
const val firstKeyTriggerFrame = 55
const val secondKeyTriggerFrame = 90

View File

@ -0,0 +1,44 @@
/* 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.sessions
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.main.current_session_bottom_sheet.view.*
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.requireComponents
class CurrentSessionBottomSheetFragment : BottomSheetDialogFragment(), LayoutContainer {
override val containerView: View?
get() = view
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(BottomSheetDialogFragment.STYLE_NORMAL, R.style.CurrentSessionBottomSheetDialogTheme)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.current_session_bottom_sheet, container, false)
view.current_session_card_tab_list.text = requireComponents.core.sessionManager.sessions.joinToString(", ") {
if (it.title.length > maxTitleLength) it.title.substring(0, maxTitleLength) + "..." else it.title
}
view.delete_session_button.setOnClickListener {
requireComponents.core.sessionManager.removeAll()
dismiss()
}
return view
}
companion object {
const val maxTitleLength = 20
}
}

View File

@ -4,17 +4,25 @@
package org.mozilla.fenix.home.tabs
import android.app.Activity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.fragment.app.FragmentActivity
import androidx.navigation.Navigation
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import io.reactivex.Observable
import io.reactivex.Observer
import io.reactivex.functions.Consumer
import kotlinx.android.synthetic.main.tab_list_header.view.*
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.increaseTapArea
import org.mozilla.fenix.home.HomeFragment
import org.mozilla.fenix.home.HomeFragmentDirections
import org.mozilla.fenix.home.sessions.CurrentSessionBottomSheetFragment
import org.mozilla.fenix.mvi.UIView
class TabsUIView(
@ -40,10 +48,28 @@ class TabsUIView(
adapter = tabsAdapter
itemAnimator = DefaultItemAnimator()
}
header.add_tab_button.increaseTapArea(HomeFragment.addTabButtonIncreaseDps)
header.add_tab_button.setOnClickListener {
val directions = HomeFragmentDirections.actionHomeFragmentToSearchFragment(null)
Navigation.findNavController(it).navigate(directions)
}
header.tabs_overflow_button.increaseTapArea(HomeFragment.overflowButtonIncreaseDps)
header.tabs_overflow_button.setOnClickListener {
if (view.context as? Activity != null) {
CurrentSessionBottomSheetFragment().show(
(view.context as FragmentActivity).supportFragmentManager,
overflowFragmentTag
)
}
}
}
override fun updateView() = Consumer<TabsState> {
tabsAdapter.sessions = it.sessions
header.visibility = if (it.sessions.isEmpty()) View.GONE else View.VISIBLE
}
companion object {
const val overflowFragmentTag = "current session overflow"
}
}

View File

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</vector>

File diff suppressed because one or more lines are too long

View File

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M11.293,2.293c0.39,-0.39 1.024,-0.39 1.414,0l6,6c0.379,0.392 0.374,1.016 -0.012,1.402 -0.386,0.385 -1.01,0.39 -1.402,0.012L13,5.414V17c0,0.552 -0.448,1 -1,1s-1,-0.448 -1,-1V5.414L6.707,9.707c-0.392,0.379 -1.016,0.373 -1.402,-0.012 -0.386,-0.386 -0.391,-1.01 -0.012,-1.402l6,-6zM3,17c0,-0.552 0.448,-1 1,-1s1,0.448 1,1v2c0,0.552 0.448,1 1,1h13c0.552,0 1,-0.448 1,-1v-2c0,-0.552 0.448,-1 1,-1s1,0.448 1,1v2c0,1.657 -1.343,3 -3,3H6c-1.657,0 -3,-1.343 -3,-3v-2z"
android:fillColor="#202340"
android:fillType="evenOdd"/>
</vector>

View File

@ -0,0 +1,20 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportWidth="64"
android:viewportHeight="64">
<path
android:pathData="M12,8L60,8A4,4 0,0 1,64 12L64,60A4,4 0,0 1,60 64L12,64A4,4 0,0 1,8 60L8,12A4,4 0,0 1,12 8z"
android:fillColor="#024690"/>
<path
android:pathData="M8,4L56,4A4,4 0,0 1,60 8L60,56A4,4 0,0 1,56 60L8,60A4,4 0,0 1,4 56L4,8A4,4 0,0 1,8 4z"
android:fillColor="#0B68CD"/>
<path
android:pathData="M4,0L52,0A4,4 0,0 1,56 4L56,52A4,4 0,0 1,52 56L4,56A4,4 0,0 1,0 52L0,4A4,4 0,0 1,4 0z"
android:fillColor="#0390ED"/>
<path
android:pathData="M28.37,22.793L33.5,14 44,32L32.988,32c-0.26,5.567 -4.857,10 -10.488,10C16.701,42 12,37.299 12,31.5S16.701,21 22.5,21c2.175,0 4.195,0.661 5.87,1.793zM28.37,22.793L23,32h9.988c0.008,-0.166 0.012,-0.332 0.012,-0.5 0,-3.624 -1.836,-6.82 -4.63,-8.707z"
android:strokeAlpha="0.5"
android:fillColor="#024690"
android:fillAlpha="0.5"/>
</vector>

View File

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
app:layout_behavior="@string/bottom_sheet_behavior"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.cardview.widget.CardView
android:id="@+id/current_session_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:cardCornerRadius="10dp"
android:padding="10dp"
android:elevation="5dp"
android:background="?android:attr/colorBackground"
>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/current_session_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:paddingBottom="20dp"
android:src="@drawable/ic_session_thumbnail_placeholder_blue"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:contentDescription="@string/current_session_image"/>
<TextView
android:id="@+id/current_session_card_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="@string/tabs_header_title"
android:textSize="18sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/current_session_image"
/>
<TextView
android:id="@+id/current_session_card_tab_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="10dp"
android:textSize="12sp"
app:layout_constraintTop_toBottomOf="@id/current_session_card_title"
app:layout_constraintStart_toEndOf="@id/current_session_image"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_bias="0"
android:requiresFadingEdge="vertical"
android:fadingEdgeLength="48dp"
tools:text="@tools:sample/lorem/random"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/delete_session_button"
android:padding="12dp"
android:text="@string/current_session_delete"
android:textSize="18sp"
android:textColor="@color/photonRed60"
android:background="?android:attr/colorBackground"
android:drawableStart="@drawable/ic_delete"
android:drawablePadding="10dp"
android:drawableTint="@color/photonRed60" tools:targetApi="m"/>
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/archive_session_button"
android:padding="12dp"
android:text="@string/current_session_archive"
android:textSize="18sp"
android:background="?android:attr/colorBackground"
android:drawableStart="@drawable/ic_archive"
android:drawablePadding="10dp"/>
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/send_and_share_session_button"
android:padding="12dp"
android:text="@string/current_session_send_and_share"
android:textSize="18sp"
android:background="?android:attr/colorBackground"
android:drawableStart="@drawable/ic_send"
android:drawablePadding="10dp"/>
</LinearLayout>

View File

@ -2,79 +2,83 @@
<!-- 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/. -->
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/homeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/homeBackgroundGradient"
app:layoutDescription="@xml/home_scene"
tools:context=".home.HomeFragment">
android:layout_height="match_parent">
<androidx.constraintlayout.motion.widget.MotionLayout
android:id="@+id/homeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/homeBackgroundGradient"
app:layoutDescription="@xml/home_scene"
tools:context=".home.HomeFragment">
<ImageButton
android:id="@+id/menuButton"
android:layout_width="@dimen/glyph_button_height"
android:layout_height="@dimen/glyph_button_height"
android:layout_marginTop="16dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:src="@drawable/ic_menu"
android:tint="?attr/menuButtonTint"
android:contentDescription="@string/content_description_menu"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="@+id/privateBrowsingButton"
android:layout_width="@dimen/glyph_button_height"
android:layout_height="@dimen/glyph_button_height"
android:background="?attr/privateBrowsingButtonBackground"
android:src="@drawable/ic_private_browsing"
android:contentDescription="@string/content_description_private_browsing_button"
app:layout_constraintEnd_toStartOf="@id/menuButton"
app:layout_constraintTop_toTopOf="@id/menuButton" />
<ImageView
android:id="@+id/wordmark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="42dp"
android:src="?attr/fenixLogo"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/menuButton" />
<org.mozilla.fenix.home.SearchView
android:id="@+id/toolbar_wrapper"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginTop="64dp"
android:layout_marginStart="16dp"
android:elevation="@dimen/toolbar_elevation"
android:background="?attr/toolbarWrapperBackground"
<ImageButton
android:id="@+id/menuButton"
android:layout_width="@dimen/glyph_button_height"
android:layout_height="@dimen/glyph_button_height"
android:layout_marginTop="16dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:src="@drawable/ic_menu"
android:tint="?attr/menuButtonTint"
android:contentDescription="@string/content_description_menu"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="@+id/privateBrowsingButton"
android:layout_width="@dimen/glyph_button_height"
android:layout_height="@dimen/glyph_button_height"
android:background="?attr/privateBrowsingButtonBackground"
android:src="@drawable/ic_private_browsing"
android:contentDescription="@string/content_description_private_browsing_button"
app:layout_constraintEnd_toStartOf="@id/menuButton"
app:layout_constraintTop_toTopOf="@id/menuButton" />
<ImageView
android:id="@+id/wordmark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="42dp"
android:src="?attr/fenixLogo"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/wordmark">
app:layout_constraintTop_toBottomOf="@id/menuButton" />
<TextView
android:id="@+id/toolbar"
android:layout_width="match_parent"
<org.mozilla.fenix.home.SearchView
android:id="@+id/toolbar_wrapper"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingStart="12sp"
android:paddingEnd="12sp"
android:paddingTop="16sp"
android:paddingBottom="16sp"
android:drawablePadding="12sp"
android:clickable="true"
android:focusable="true"
android:gravity="center_vertical"
android:text="@string/search_hint"
android:textColor="?attr/toolbarTextColor"
android:textSize="14sp" />
</org.mozilla.fenix.home.SearchView>
android:layout_marginEnd="16dp"
android:layout_marginTop="64dp"
android:layout_marginStart="16dp"
android:elevation="@dimen/toolbar_elevation"
android:background="?attr/toolbarWrapperBackground"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/wordmark">
<View
<TextView
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="12sp"
android:paddingEnd="12sp"
android:paddingTop="16sp"
android:paddingBottom="16sp"
android:drawablePadding="12sp"
android:clickable="true"
android:focusable="true"
android:gravity="center_vertical"
android:text="@string/search_hint"
android:textColor="?attr/toolbarTextColor"
android:textSize="14sp" />
</org.mozilla.fenix.home.SearchView>
<View
android:id="@+id/homeDivider"
android:layout_width="match_parent"
android:layout_height="1dp"
@ -86,4 +90,5 @@
android:layout_marginStart="40dp"
android:layout_marginEnd="40dp"/>
</androidx.constraintlayout.motion.widget.MotionLayout>
</androidx.constraintlayout.motion.widget.MotionLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -24,7 +24,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:src="@drawable/ic_add_black_24dp"
android:src="@drawable/ic_new"
android:baselineAlignBottom="true"
app:layout_constraintBaseline_toBaselineOf="@id/header_text"
app:layout_constraintEnd_toStartOf="@id/tabs_overflow_button"/>

View File

@ -42,7 +42,7 @@
<ImageView android:id="@+id/close_tab_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_close_black_24dp"
android:src="@drawable/ic_close"
android:paddingEnd="10dp"
android:contentDescription="@string/close_tab"
app:layout_constraintBottom_toBottomOf="@id/text_url"

View File

@ -139,4 +139,10 @@
<p>%1$s puts you in control.</p>
<p>%1$s is produced by Mozilla. Our mission is to foster a healthy, open Internet.<br/>
]]></string>
<!-- Current session overflow menu -->
<string name="current_session_delete">Delete</string>
<string name="current_session_archive">Archive</string>
<string name="current_session_send_and_share">Send and Share</string>
<string name="current_session_image">Current session image</string>
</resources>

View File

@ -116,4 +116,13 @@
<item name="android:minHeight">0dp</item>
<item name="android:background">@drawable/search_pill_background</item>
</style>
<style name="CurrentSessionBottomSheetDialogTheme" parent="Theme.Design.Light.BottomSheetDialog">
<item name="bottomSheetStyle">@style/CurrentSessionBottomSheetStyle</item>
</style>
<style name="CurrentSessionBottomSheetStyle" parent="Widget.Design.BottomSheet.Modal">
<item name="android:background">@android:color/transparent</item>
<item name="android:textColor">@android:color/black</item>
</style>
</resources>