Adding overflow menu capability in sessions list header view

This commit is contained in:
Maxime NATUREL 2022-10-20 16:22:29 +02:00
parent f45cc715d1
commit 1ed92e5215
8 changed files with 79 additions and 9 deletions

View File

@ -5,6 +5,7 @@
<attr name="sessionsListHeaderTitle" format="string" /> <attr name="sessionsListHeaderTitle" format="string" />
<attr name="sessionsListHeaderDescription" format="string" /> <attr name="sessionsListHeaderDescription" format="string" />
<attr name="sessionsListHeaderHasLearnMoreLink" format="boolean" /> <attr name="sessionsListHeaderHasLearnMoreLink" format="boolean" />
<attr name="sessionsListHeaderMenu" format="reference" />
</declare-styleable> </declare-styleable>
</resources> </resources>

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2022 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.app.core.extensions
import android.view.MenuItem
import androidx.annotation.ColorInt
import androidx.core.text.toSpannable
import im.vector.app.core.utils.colorizeMatchingText
fun MenuItem.setTextColor(@ColorInt color: Int) {
val currentTitle = title.orEmpty().toString()
title = currentTitle
.toSpannable()
.colorizeMatchingText(currentTitle, color)
}

View File

@ -30,6 +30,7 @@ import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.date.VectorDateFormatter import im.vector.app.core.date.VectorDateFormatter
import im.vector.app.core.dialogs.ManuallyVerifyDialog import im.vector.app.core.dialogs.ManuallyVerifyDialog
import im.vector.app.core.extensions.setTextColor
import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.resources.ColorProvider import im.vector.app.core.resources.ColorProvider
import im.vector.app.core.resources.DrawableProvider import im.vector.app.core.resources.DrawableProvider
@ -91,6 +92,7 @@ class VectorSettingsDevicesFragment :
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
initWaitingView() initWaitingView()
initOtherSessionsHeaderView()
initOtherSessionsView() initOtherSessionsView()
initSecurityRecommendationsView() initSecurityRecommendationsView()
initQrLoginView() initQrLoginView()
@ -131,6 +133,11 @@ class VectorSettingsDevicesFragment :
views.waitingView.waitingStatusText.isVisible = true views.waitingView.waitingStatusText.isVisible = true
} }
private fun initOtherSessionsHeaderView() {
val color = colorProvider.getColorFromAttribute(R.attr.colorError)
views.deviceListHeaderOtherSessions.menu.findItem(R.id.otherSessionsHeaderMultiSignout).setTextColor(color)
}
private fun initOtherSessionsView() { private fun initOtherSessionsView() {
views.deviceListOtherSessions.callback = this views.deviceListOtherSessions.callback = this
} }

View File

@ -20,6 +20,9 @@ import android.content.Context
import android.content.res.TypedArray import android.content.res.TypedArray
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import androidx.appcompat.view.menu.MenuBuilder
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.res.use import androidx.core.content.res.use
import androidx.core.view.isVisible import androidx.core.view.isVisible
@ -39,6 +42,7 @@ class SessionsListHeaderView @JvmOverloads constructor(
this this
) )
val menu: Menu = binding.sessionsListHeaderMenu.menu
var onLearnMoreClickListener: (() -> Unit)? = null var onLearnMoreClickListener: (() -> Unit)? = null
init { init {
@ -50,6 +54,7 @@ class SessionsListHeaderView @JvmOverloads constructor(
).use { ).use {
setTitle(it) setTitle(it)
setDescription(it) setDescription(it)
setMenu(it)
} }
} }
@ -90,4 +95,15 @@ class SessionsListHeaderView @JvmOverloads constructor(
onLearnMoreClickListener?.invoke() onLearnMoreClickListener?.invoke()
} }
} }
private fun setMenu(typedArray: TypedArray) {
val menuResId = typedArray.getResourceId(R.styleable.SessionsListHeaderView_sessionsListHeaderMenu, -1)
if (menuResId == -1) {
binding.sessionsListHeaderMenu.isVisible = false
} else {
binding.sessionsListHeaderMenu.showOverflowMenu()
val menuBuilder = binding.sessionsListHeaderMenu.menu as? MenuBuilder
menuBuilder?.let { MenuInflater(context).inflate(menuResId, it) }
}
}
} }

View File

@ -25,7 +25,6 @@ import android.view.ViewGroup
import androidx.activity.OnBackPressedCallback import androidx.activity.OnBackPressedCallback
import androidx.activity.addCallback import androidx.activity.addCallback
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.core.text.toSpannable
import androidx.core.view.isVisible import androidx.core.view.isVisible
import com.airbnb.mvrx.Success import com.airbnb.mvrx.Success
import com.airbnb.mvrx.args import com.airbnb.mvrx.args
@ -33,14 +32,13 @@ import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState import com.airbnb.mvrx.withState
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.extensions.orEmpty import im.vector.app.core.extensions.setTextColor
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment.ResultListener.Companion.RESULT_OK import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment.ResultListener.Companion.RESULT_OK
import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.platform.VectorMenuProvider import im.vector.app.core.platform.VectorMenuProvider
import im.vector.app.core.resources.ColorProvider import im.vector.app.core.resources.ColorProvider
import im.vector.app.core.resources.StringProvider import im.vector.app.core.resources.StringProvider
import im.vector.app.core.utils.colorizeMatchingText
import im.vector.app.databinding.FragmentOtherSessionsBinding import im.vector.app.databinding.FragmentOtherSessionsBinding
import im.vector.app.features.settings.devices.v2.DeviceFullInfo import im.vector.app.features.settings.devices.v2.DeviceFullInfo
import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterBottomSheet import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterBottomSheet
@ -94,10 +92,7 @@ class OtherSessionsFragment :
private fun changeTextColorOfDestructiveAction(menuItem: MenuItem) { private fun changeTextColorOfDestructiveAction(menuItem: MenuItem) {
val titleColor = colorProvider.getColorFromAttribute(R.attr.colorError) val titleColor = colorProvider.getColorFromAttribute(R.attr.colorError)
val currentTitle = menuItem.title.orEmpty().toString() menuItem.setTextColor(titleColor)
menuItem.title = currentTitle
.toSpannable()
.colorizeMatchingText(currentTitle, titleColor)
} }
override fun handleMenuItemSelected(item: MenuItem): Boolean { override fun handleMenuItemSelected(item: MenuItem): Boolean {

View File

@ -98,6 +98,7 @@
app:layout_constraintTop_toBottomOf="@id/deviceListDividerCurrentSession" app:layout_constraintTop_toBottomOf="@id/deviceListDividerCurrentSession"
app:sessionsListHeaderDescription="@string/device_manager_sessions_other_description" app:sessionsListHeaderDescription="@string/device_manager_sessions_other_description"
app:sessionsListHeaderHasLearnMoreLink="false" app:sessionsListHeaderHasLearnMoreLink="false"
app:sessionsListHeaderMenu="@menu/menu_other_sessions_header"
app:sessionsListHeaderTitle="@string/device_manager_sessions_other_title" /> app:sessionsListHeaderTitle="@string/device_manager_sessions_other_title" />
<im.vector.app.features.settings.devices.v2.list.OtherSessionsView <im.vector.app.features.settings.devices.v2.list.OtherSessionsView
@ -117,8 +118,8 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/deviceListOtherSessions" app:layout_constraintTop_toBottomOf="@id/deviceListOtherSessions"
app:sessionsListHeaderHasLearnMoreLink="false"
app:sessionsListHeaderDescription="@string/device_manager_sessions_sign_in_with_qr_code_description" app:sessionsListHeaderDescription="@string/device_manager_sessions_sign_in_with_qr_code_description"
app:sessionsListHeaderHasLearnMoreLink="false"
app:sessionsListHeaderTitle="@string/device_manager_sessions_sign_in_with_qr_code_title" app:sessionsListHeaderTitle="@string/device_manager_sessions_sign_in_with_qr_code_title"
tools:visibility="visible" /> tools:visibility="visible" />

View File

@ -13,7 +13,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/layout_horizontal_margin" android:layout_marginHorizontal="@dimen/layout_horizontal_margin"
android:layout_marginTop="20dp" android:layout_marginTop="20dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toStartOf="@id/sessionsListHeaderMenu"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:text="Other sessions" /> tools:text="Other sessions" />
@ -29,4 +29,13 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/sessions_list_header_title" app:layout_constraintTop_toBottomOf="@id/sessions_list_header_title"
tools:text="For best security, verify your sessions and sign out from any session that you dont recognize or use anymore. Learn More." /> tools:text="For best security, verify your sessions and sign out from any session that you dont recognize or use anymore. Learn More." />
<androidx.appcompat.widget.ActionMenuView
android:id="@+id/sessionsListHeaderMenu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
app:layout_constraintBottom_toBottomOf="@id/sessions_list_header_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/sessions_list_header_title" />
</merge> </merge>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<menu 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"
tools:ignore="AlwaysShowAction">
<item
android:id="@+id/otherSessionsHeaderMultiSignout"
android:title="@string/device_manager_other_sessions_multi_signout_all"
app:showAsAction="withText|never" />
</menu>