For #1830 - Adds the ability to share a tab
parent
774c5c0e0c
commit
4ea54252b0
|
@ -34,6 +34,7 @@ import org.mozilla.fenix.HomeActivity
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
|
import org.mozilla.fenix.ext.share
|
||||||
import org.mozilla.fenix.ext.urlToHost
|
import org.mozilla.fenix.ext.urlToHost
|
||||||
import org.mozilla.fenix.home.sessioncontrol.Mode
|
import org.mozilla.fenix.home.sessioncontrol.Mode
|
||||||
import org.mozilla.fenix.home.sessioncontrol.SessionControlAction
|
import org.mozilla.fenix.home.sessioncontrol.SessionControlAction
|
||||||
|
@ -201,6 +202,11 @@ class HomeFragment : Fragment(), CoroutineScope {
|
||||||
requireComponents.core.sessionManager.remove(session)
|
requireComponents.core.sessionManager.remove(session)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
is TabAction.Share -> {
|
||||||
|
requireComponents.core.sessionManager.findSessionById(action.sessionId)?.let { session ->
|
||||||
|
requireContext().share(session.url)
|
||||||
|
}
|
||||||
|
}
|
||||||
is TabAction.CloseAll -> {
|
is TabAction.CloseAll -> {
|
||||||
requireComponents.useCases.tabsUseCases.removeAllTabsOfType.invoke(action.private)
|
requireComponents.useCases.tabsUseCases.removeAllTabsOfType.invoke(action.private)
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,7 @@ sealed class TabAction : Action {
|
||||||
data class CloseAll(val private: Boolean) : TabAction()
|
data class CloseAll(val private: Boolean) : TabAction()
|
||||||
data class Select(val sessionId: String) : TabAction()
|
data class Select(val sessionId: String) : TabAction()
|
||||||
data class Close(val sessionId: String) : TabAction()
|
data class Close(val sessionId: String) : TabAction()
|
||||||
|
data class Share(val sessionId: String) : TabAction()
|
||||||
object PrivateBrowsingLearnMore : TabAction()
|
object PrivateBrowsingLearnMore : TabAction()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
|
|
||||||
package org.mozilla.fenix.home.sessioncontrol.viewholders
|
package org.mozilla.fenix.home.sessioncontrol.viewholders
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import android.graphics.Outline
|
import android.graphics.Outline
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewOutlineProvider
|
import android.view.ViewOutlineProvider
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import io.reactivex.Observer
|
import io.reactivex.Observer
|
||||||
import kotlinx.android.extensions.LayoutContainer
|
import kotlinx.android.extensions.LayoutContainer
|
||||||
|
@ -17,8 +17,10 @@ import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import mozilla.components.browser.icons.IconRequest
|
import mozilla.components.browser.icons.IconRequest
|
||||||
|
import mozilla.components.browser.menu.BrowserMenu
|
||||||
|
import mozilla.components.browser.menu.BrowserMenuBuilder
|
||||||
|
import mozilla.components.browser.menu.item.SimpleBrowserMenuItem
|
||||||
import mozilla.components.support.ktx.android.content.res.pxToDp
|
import mozilla.components.support.ktx.android.content.res.pxToDp
|
||||||
import org.jetbrains.anko.image
|
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
import org.mozilla.fenix.ext.increaseTapArea
|
import org.mozilla.fenix.ext.increaseTapArea
|
||||||
|
@ -40,8 +42,15 @@ class TabViewHolder(
|
||||||
get() = Dispatchers.IO + job
|
get() = Dispatchers.IO + job
|
||||||
|
|
||||||
var tab: Tab? = null
|
var tab: Tab? = null
|
||||||
|
private lateinit var tabMenu: TabItemMenu
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
tabMenu = TabItemMenu(view.context) {
|
||||||
|
when (it) {
|
||||||
|
is TabItemMenu.Item.Share ->
|
||||||
|
actionEmitter.onNext(TabAction.Share(tab?.sessionId!!))
|
||||||
|
}
|
||||||
|
}
|
||||||
item_tab.setOnClickListener {
|
item_tab.setOnClickListener {
|
||||||
actionEmitter.onNext(TabAction.Select(tab?.sessionId!!))
|
actionEmitter.onNext(TabAction.Select(tab?.sessionId!!))
|
||||||
}
|
}
|
||||||
|
@ -65,11 +74,16 @@ class TabViewHolder(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tab_overflow_button.setOnClickListener {
|
||||||
|
tabMenu.menuBuilder
|
||||||
|
.build(view.context)
|
||||||
|
.show(anchor = it, orientation = BrowserMenu.Orientation.DOWN)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bindSession(tab: Tab, position: Int) {
|
fun bindSession(tab: Tab, position: Int) {
|
||||||
this.tab = tab
|
this.tab = tab
|
||||||
updateTabBackground(position)
|
|
||||||
updateText(tab)
|
updateText(tab)
|
||||||
updateSelected(tab.selected)
|
updateSelected(tab.selected)
|
||||||
}
|
}
|
||||||
|
@ -90,24 +104,30 @@ class TabViewHolder(
|
||||||
selected_border.visibility = if (selected) View.VISIBLE else View.GONE
|
selected_border.visibility = if (selected) View.VISIBLE else View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateTabBackground(id: Int) {
|
|
||||||
if (tab?.thumbnail != null) {
|
|
||||||
// tab_background.setImageBitmap(tab?.thumbnail)
|
|
||||||
} else {
|
|
||||||
val background = availableBackgrounds[id % availableBackgrounds.size]
|
|
||||||
favicon_image.image = ContextCompat.getDrawable(view.context, background)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val LAYOUT_ID = R.layout.tab_list_row
|
const val LAYOUT_ID = R.layout.tab_list_row
|
||||||
const val closeButtonIncreaseDps = 12
|
const val closeButtonIncreaseDps = 12
|
||||||
const val favIconBorderRadiusInPx = 8
|
const val favIconBorderRadiusInPx = 8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val availableBackgrounds = listOf(
|
class TabItemMenu(
|
||||||
R.drawable.sessions_01, R.drawable.sessions_02,
|
private val context: Context,
|
||||||
R.drawable.sessions_03, R.drawable.sessions_06,
|
private val onItemTapped: (Item) -> Unit = {}
|
||||||
R.drawable.sessions_07, R.drawable.sessions_08
|
) {
|
||||||
|
sealed class Item {
|
||||||
|
object Share : Item()
|
||||||
|
}
|
||||||
|
|
||||||
|
val menuBuilder by lazy { BrowserMenuBuilder(menuItems) }
|
||||||
|
|
||||||
|
private val menuItems by lazy {
|
||||||
|
listOf(
|
||||||
|
SimpleBrowserMenuItem(
|
||||||
|
context.getString(R.string.tab_share)
|
||||||
|
) {
|
||||||
|
onItemTapped.invoke(Item.Share)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,13 @@
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/favicon_image"
|
android:id="@+id/favicon_image"
|
||||||
android:layout_width="64dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="64dp"
|
android:layout_height="0dp"
|
||||||
android:layout_margin="8dp"
|
android:layout_margin="8dp"
|
||||||
android:adjustViewBounds="true"
|
android:adjustViewBounds="true"
|
||||||
android:importantForAccessibility="no"
|
android:importantForAccessibility="no"
|
||||||
android:scaleType="centerInside"
|
android:scaleType="fitCenter"
|
||||||
|
app:layout_constraintDimensionRatio="1:1"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
@ -49,12 +50,13 @@
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tab_title"
|
android:id="@+id/tab_title"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="4dp"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:maxLines="2"
|
android:maxLines="2"
|
||||||
|
android:minLines="2"
|
||||||
android:textColor="?primaryText"
|
android:textColor="?primaryText"
|
||||||
android:textSize="15sp"
|
android:textSize="15sp"
|
||||||
app:layout_constraintStart_toEndOf="@id/favicon_image"
|
app:layout_constraintStart_toEndOf="@id/favicon_image"
|
||||||
|
@ -81,7 +83,7 @@
|
||||||
android:contentDescription="@string/tab_menu"
|
android:contentDescription="@string/tab_menu"
|
||||||
android:src="@drawable/ic_menu"
|
android:src="@drawable/ic_menu"
|
||||||
android:translationX="4dp"
|
android:translationX="4dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="@id/tab_title"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/close_tab_button" />
|
app:layout_constraintTop_toBottomOf="@id/close_tab_button" />
|
||||||
|
|
||||||
|
|
|
@ -232,6 +232,8 @@
|
||||||
<string name="close_tab">Close tab</string>
|
<string name="close_tab">Close tab</string>
|
||||||
<!-- Content description (not visible, for screen readers etc.): Opens the tab menu when pressed -->
|
<!-- Content description (not visible, for screen readers etc.): Opens the tab menu when pressed -->
|
||||||
<string name="tab_menu">Tab menu</string>
|
<string name="tab_menu">Tab menu</string>
|
||||||
|
<!-- Tab menu item to share the tab -->
|
||||||
|
<string name="tab_share">Share tab</string>
|
||||||
<!-- Button in the current session menu. Deletes the session when pressed -->
|
<!-- Button in the current session menu. Deletes the session when pressed -->
|
||||||
<string name="current_session_delete">Delete</string>
|
<string name="current_session_delete">Delete</string>
|
||||||
<!-- Button in the current session menu. Saves the session when pressed -->
|
<!-- Button in the current session menu. Saves the session when pressed -->
|
||||||
|
|
Loading…
Reference in New Issue