Merge pull request #6436 from vector-im/feature/bma/activity_fragment_1_5_0

Upgrade androidx activity and fragment to 1.5.0
This commit is contained in:
Benoit Marty 2022-07-06 11:44:22 +02:00 committed by GitHub
commit 7616912411
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 459 additions and 342 deletions

1
changelog.d/6436.misc Normal file
View File

@ -0,0 +1 @@
Let your Activity or Fragment implement `VectorMenuProvider` if they provide a menu.

View File

@ -29,7 +29,7 @@ def bigImageViewer = "1.8.1"
def jjwt = "0.11.5" def jjwt = "0.11.5"
def vanniktechEmoji = "0.15.0" def vanniktechEmoji = "0.15.0"
def fragment = "1.4.1" def fragment = "1.5.0"
// Testing // Testing
def mockk = "1.12.3" // We need to use 1.12.3 to have mocking in androidTest until a new version is released: https://github.com/mockk/mockk/issues/819 def mockk = "1.12.3" // We need to use 1.12.3 to have mocking in androidTest until a new version is released: https://github.com/mockk/mockk/issues/819
@ -50,7 +50,7 @@ ext.libs = [
], ],
androidx : [ androidx : [
'annotation' : "androidx.annotation:annotation:1.4.0", 'annotation' : "androidx.annotation:annotation:1.4.0",
'activity' : "androidx.activity:activity:1.4.0", 'activity' : "androidx.activity:activity:1.5.0",
'annotations' : "androidx.annotation:annotation:1.3.0", 'annotations' : "androidx.annotation:annotation:1.3.0",
'appCompat' : "androidx.appcompat:appcompat:1.4.2", 'appCompat' : "androidx.appcompat:appcompat:1.4.2",
'biometric' : "androidx.biometric:biometric:1.1.0", 'biometric' : "androidx.biometric:biometric:1.1.0",

View File

@ -53,6 +53,7 @@ android {
dependencies { dependencies {
implementation libs.androidx.appCompat implementation libs.androidx.appCompat
implementation libs.androidx.fragmentKtx
implementation libs.google.material implementation libs.google.material
// Pref theme // Pref theme
implementation libs.androidx.preferenceKtx implementation libs.androidx.preferenceKtx

View File

@ -18,8 +18,12 @@ package im.vector.lib.ui.styles.debug
import android.os.Bundle import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.MenuProvider
import androidx.lifecycle.Lifecycle
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import im.vector.lib.ui.styles.R import im.vector.lib.ui.styles.R
@ -31,6 +35,7 @@ abstract class DebugMaterialThemeActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setupMenu()
val views = ActivityDebugMaterialThemeBinding.inflate(layoutInflater) val views = ActivityDebugMaterialThemeBinding.inflate(layoutInflater)
setContentView(views.root) setContentView(views.root)
@ -72,6 +77,27 @@ abstract class DebugMaterialThemeActivity : AppCompatActivity() {
} }
} }
private fun setupMenu() {
addMenuProvider(
object : MenuProvider {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.menu_debug, menu)
}
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
Toast.makeText(
this@DebugMaterialThemeActivity,
"Menu ${menuItem.title} clicked!",
Toast.LENGTH_SHORT
).show()
return true
}
},
this,
Lifecycle.State.RESUMED
)
}
private fun showTestDialog(theme: Int) { private fun showTestDialog(theme: Int) {
MaterialAlertDialogBuilder(this, theme) MaterialAlertDialogBuilder(this, theme)
.setTitle("Dialog title") .setTitle("Dialog title")
@ -82,9 +108,4 @@ abstract class DebugMaterialThemeActivity : AppCompatActivity() {
.setNeutralButton("Neutral", null) .setNeutralButton("Neutral", null)
.show() .show()
} }
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_debug, menu)
return true
}
} }

View File

@ -180,3 +180,8 @@ System\.currentTimeMillis\(\)===2
### Remove extra space between the name and the description ### Remove extra space between the name and the description
\* @\w+ \w+ + \* @\w+ \w+ +
### Please use the MenuProvider interface now
onCreateOptionsMenu
onOptionsItemSelected
onPrepareOptionsMenu

View File

@ -19,11 +19,11 @@ package im.vector.app.core.platform
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.content.Context import android.content.Context
import android.content.res.Configuration
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Parcelable import android.os.Parcelable
import android.view.Menu import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.WindowInsetsController import android.view.WindowInsetsController
@ -31,15 +31,18 @@ import android.view.WindowManager
import android.widget.TextView import android.widget.TextView
import androidx.annotation.CallSuper import androidx.annotation.CallSuper
import androidx.annotation.MainThread import androidx.annotation.MainThread
import androidx.annotation.MenuRes
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.app.MultiWindowModeChangedInfo
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.util.Consumer
import androidx.core.view.MenuProvider
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentFactory import androidx.fragment.app.FragmentFactory
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
@ -86,6 +89,7 @@ import im.vector.app.features.themes.ThemeUtils
import im.vector.app.receivers.DebugReceiver import im.vector.app.receivers.DebugReceiver
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import org.matrix.android.sdk.api.extensions.orFalse
import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.failure.GlobalError import org.matrix.android.sdk.api.failure.GlobalError
import org.matrix.android.sdk.api.failure.InitialSyncRequestReason import org.matrix.android.sdk.api.failure.InitialSyncRequestReason
@ -199,6 +203,8 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), Maver
supportFragmentManager.fragmentFactory = fragmentFactory supportFragmentManager.fragmentFactory = fragmentFactory
viewModelFactory = activityEntryPoint.viewModelFactory() viewModelFactory = activityEntryPoint.viewModelFactory()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
addOnMultiWindowModeChangedListener(onMultiWindowModeChangedListener)
setupMenu()
configurationViewModel = viewModelProvider.get(ConfigurationViewModel::class.java) configurationViewModel = viewModelProvider.get(ConfigurationViewModel::class.java)
bugReporter = singletonEntryPoint.bugReporter() bugReporter = singletonEntryPoint.bugReporter()
pinLocker = singletonEntryPoint.pinLocker() pinLocker = singletonEntryPoint.pinLocker()
@ -249,6 +255,32 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), Maver
} }
} }
private fun setupMenu() {
// Always add a MenuProvider to handle the back action from the Toolbar
val vectorMenuProvider = this as? VectorMenuProvider
addMenuProvider(
object : MenuProvider {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
vectorMenuProvider?.let {
menuInflater.inflate(it.getMenuRes(), menu)
it.handlePostCreateMenu(menu)
}
}
override fun onPrepareMenu(menu: Menu) {
vectorMenuProvider?.handlePrepareMenu(menu)
}
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
return vectorMenuProvider?.handleMenuItemSelected(menuItem).orFalse() ||
handleMenuItemHome(menuItem)
}
},
this,
Lifecycle.State.RESUMED
)
}
/** /**
* This method has to be called for the font size setting be supported correctly. * This method has to be called for the font size setting be supported correctly.
*/ */
@ -332,6 +364,7 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), Maver
} }
override fun onDestroy() { override fun onDestroy() {
removeOnMultiWindowModeChangedListener(onMultiWindowModeChangedListener)
super.onDestroy() super.onDestroy()
Timber.i("onDestroy Activity ${javaClass.simpleName}") Timber.i("onDestroy Activity ${javaClass.simpleName}")
} }
@ -417,11 +450,9 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), Maver
} }
} }
override fun onMultiWindowModeChanged(isInMultiWindowMode: Boolean, newConfig: Configuration?) { private val onMultiWindowModeChangedListener = Consumer<MultiWindowModeChangedInfo> {
super.onMultiWindowModeChanged(isInMultiWindowMode, newConfig) Timber.w("onMultiWindowModeChanged. isInMultiWindowMode: ${it.isInMultiWindowMode}")
bugReporter.inMultiWindowMode = it.isInMultiWindowMode
Timber.w("onMultiWindowModeChanged. isInMultiWindowMode: $isInMultiWindowMode")
bugReporter.inMultiWindowMode = isInMultiWindowMode
} }
protected fun createFragment(fragmentClass: Class<out Fragment>, argsParcelable: Parcelable? = null): Fragment { protected fun createFragment(fragmentClass: Class<out Fragment>, argsParcelable: Parcelable? = null): Fragment {
@ -463,28 +494,14 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), Maver
} }
} }
/* ========================================================================================== private fun handleMenuItemHome(item: MenuItem): Boolean {
* MENU MANAGEMENT return when (item.itemId) {
* ========================================================================================== */ android.R.id.home -> {
onBackPressed(true)
override fun onCreateOptionsMenu(menu: Menu): Boolean { true
val menuRes = getMenuRes() }
else -> false
if (menuRes != -1) {
menuInflater.inflate(menuRes, menu)
return true
} }
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
onBackPressed(true)
return true
}
return super.onOptionsItemSelected(item)
} }
override fun onBackPressed() { override fun onBackPressed() {
@ -587,9 +604,6 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), Maver
@StringRes @StringRes
open fun getTitleRes() = -1 open fun getTitleRes() = -1
@MenuRes
open fun getMenuRes() = -1
/** /**
* Return a object containing other themes for this activity. * Return a object containing other themes for this activity.
*/ */

View File

@ -22,12 +22,16 @@ import android.os.Parcelable
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.annotation.CallSuper import androidx.annotation.CallSuper
import androidx.annotation.MainThread import androidx.annotation.MainThread
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.core.view.MenuHost
import androidx.core.view.MenuProvider
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
@ -126,9 +130,7 @@ abstract class VectorBaseFragment<VB : ViewBinding> : Fragment(), MavericksView
@CallSuper @CallSuper
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
if (getMenuRes() != -1) { Timber.i("onCreate Fragment ${javaClass.simpleName}")
setHasOptionsMenu(true)
}
} }
final override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { final override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@ -158,6 +160,31 @@ abstract class VectorBaseFragment<VB : ViewBinding> : Fragment(), MavericksView
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
Timber.i("onViewCreated Fragment ${javaClass.simpleName}") Timber.i("onViewCreated Fragment ${javaClass.simpleName}")
setupMenu()
}
private fun setupMenu() {
if (this !is VectorMenuProvider) return
if (getMenuRes() == -1) return
val menuHost: MenuHost = requireActivity()
menuHost.addMenuProvider(
object : MenuProvider {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(getMenuRes(), menu)
handlePostCreateMenu(menu)
}
override fun onPrepareMenu(menu: Menu) {
handlePrepareMenu(menu)
}
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
return handleMenuItemSelected(menuItem)
}
},
viewLifecycleOwner,
Lifecycle.State.RESUMED
)
} }
open fun showLoading(message: CharSequence?) { open fun showLoading(message: CharSequence?) {
@ -270,16 +297,6 @@ abstract class VectorBaseFragment<VB : ViewBinding> : Fragment(), MavericksView
* MENU MANAGEMENT * MENU MANAGEMENT
* ========================================================================================== */ * ========================================================================================== */
open fun getMenuRes() = -1
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
val menuRes = getMenuRes()
if (menuRes != -1) {
inflater.inflate(menuRes, menu)
}
}
// This should be provided by the framework // This should be provided by the framework
protected fun invalidateOptionsMenu() = requireActivity().invalidateOptionsMenu() protected fun invalidateOptionsMenu() = requireActivity().invalidateOptionsMenu()

View File

@ -0,0 +1,37 @@
/*
* 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.platform
import android.view.Menu
import android.view.MenuItem
import androidx.annotation.MenuRes
/**
* Let your Activity of Fragment implement this interface if they provide a Menu.
*/
interface VectorMenuProvider {
@MenuRes
fun getMenuRes(): Int
// No op by default
fun handlePostCreateMenu(menu: Menu) {}
// No op by default
fun handlePrepareMenu(menu: Menu) {}
fun handleMenuItemSelected(item: MenuItem): Boolean
}

View File

@ -44,6 +44,7 @@ import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.insertBeforeLast import im.vector.app.core.extensions.insertBeforeLast
import im.vector.app.core.extensions.registerStartForActivityResult import im.vector.app.core.extensions.registerStartForActivityResult
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.resources.ColorProvider import im.vector.app.core.resources.ColorProvider
import im.vector.app.core.time.Clock import im.vector.app.core.time.Clock
import im.vector.app.core.utils.OnSnapPositionChangeListener import im.vector.app.core.utils.OnSnapPositionChangeListener
@ -67,7 +68,9 @@ class AttachmentsPreviewFragment @Inject constructor(
private val attachmentBigPreviewController: AttachmentBigPreviewController, private val attachmentBigPreviewController: AttachmentBigPreviewController,
private val colorProvider: ColorProvider, private val colorProvider: ColorProvider,
private val clock: Clock, private val clock: Clock,
) : VectorBaseFragment<FragmentAttachmentsPreviewBinding>(), AttachmentMiniaturePreviewController.Callback { ) : VectorBaseFragment<FragmentAttachmentsPreviewBinding>(),
AttachmentMiniaturePreviewController.Callback,
VectorMenuProvider {
private val fragmentArgs: AttachmentsPreviewArgs by args() private val fragmentArgs: AttachmentsPreviewArgs by args()
private val viewModel: AttachmentsPreviewViewModel by fragmentViewModel() private val viewModel: AttachmentsPreviewViewModel by fragmentViewModel()
@ -97,7 +100,7 @@ class AttachmentsPreviewFragment @Inject constructor(
} }
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) { return when (item.itemId) {
R.id.attachmentsPreviewRemoveAction -> { R.id.attachmentsPreviewRemoveAction -> {
handleRemoveAction() handleRemoveAction()
@ -107,20 +110,16 @@ class AttachmentsPreviewFragment @Inject constructor(
handleEditAction() handleEditAction()
true true
} }
else -> { else -> false
super.onOptionsItemSelected(item)
}
} }
} }
override fun onPrepareOptionsMenu(menu: Menu) { override fun handlePrepareMenu(menu: Menu) {
withState(viewModel) { state -> withState(viewModel) { state ->
val editMenuItem = menu.findItem(R.id.attachmentsPreviewEditAction) val editMenuItem = menu.findItem(R.id.attachmentsPreviewEditAction)
val showEditMenuItem = state.attachments.getOrNull(state.currentAttachmentIndex)?.isEditable().orFalse() val showEditMenuItem = state.attachments.getOrNull(state.currentAttachmentIndex)?.isEditable().orFalse()
editMenuItem.setVisible(showEditMenuItem) editMenuItem.setVisible(showEditMenuItem)
} }
super.onPrepareOptionsMenu(menu)
} }
override fun getMenuRes() = R.menu.vector_attachments_preview override fun getMenuRes() = R.menu.vector_attachments_preview

View File

@ -22,7 +22,6 @@ import android.app.PictureInPictureParams
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP import android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP
import android.content.res.Configuration
import android.graphics.Color import android.graphics.Color
import android.media.projection.MediaProjection import android.media.projection.MediaProjection
import android.media.projection.MediaProjectionManager import android.media.projection.MediaProjectionManager
@ -35,8 +34,10 @@ import android.view.View
import android.view.WindowManager import android.view.WindowManager
import androidx.activity.result.ActivityResult import androidx.activity.result.ActivityResult
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.core.app.PictureInPictureModeChangedInfo
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import androidx.core.util.Consumer
import androidx.core.view.isInvisible import androidx.core.view.isInvisible
import androidx.core.view.isVisible import androidx.core.view.isVisible
import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Fail
@ -50,6 +51,7 @@ import im.vector.app.R
import im.vector.app.core.extensions.registerStartForActivityResult import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.core.platform.VectorMenuProvider
import im.vector.app.core.utils.PERMISSIONS_FOR_AUDIO_IP_CALL import im.vector.app.core.utils.PERMISSIONS_FOR_AUDIO_IP_CALL
import im.vector.app.core.utils.PERMISSIONS_FOR_VIDEO_IP_CALL import im.vector.app.core.utils.PERMISSIONS_FOR_VIDEO_IP_CALL
import im.vector.app.core.utils.checkPermissions import im.vector.app.core.utils.checkPermissions
@ -94,7 +96,10 @@ data class CallArgs(
private val loggerTag = LoggerTag("VectorCallActivity", LoggerTag.VOIP) private val loggerTag = LoggerTag("VectorCallActivity", LoggerTag.VOIP)
@AndroidEntryPoint @AndroidEntryPoint
class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallControlsView.InteractionListener { class VectorCallActivity :
VectorBaseActivity<ActivityCallBinding>(),
CallControlsView.InteractionListener,
VectorMenuProvider {
override fun getBinding() = ActivityCallBinding.inflate(layoutInflater) override fun getBinding() = ActivityCallBinding.inflate(layoutInflater)
@ -128,6 +133,7 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
window.statusBarColor = Color.TRANSPARENT window.statusBarColor = Color.TRANSPARENT
window.navigationBarColor = Color.BLACK window.navigationBarColor = Color.BLACK
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
addOnPictureInPictureModeChangedListener(pictureInPictureModeChangedInfoConsumer)
Timber.tag(loggerTag.value).v("EXTRA_MODE is ${intent.getStringExtra(EXTRA_MODE)}") Timber.tag(loggerTag.value).v("EXTRA_MODE is ${intent.getStringExtra(EXTRA_MODE)}")
if (intent.getStringExtra(EXTRA_MODE) == INCOMING_RINGING) { if (intent.getStringExtra(EXTRA_MODE) == INCOMING_RINGING) {
@ -210,25 +216,31 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && isInPictureInPictureMode return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && isInPictureInPictureMode
} }
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean, newConfig: Configuration) = withState(callViewModel) { private val pictureInPictureModeChangedInfoConsumer = Consumer<PictureInPictureModeChangedInfo> {
renderState(it) withState(callViewModel) {
renderState(it)
}
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun handleMenuItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.menu_call_open_chat) { return when (item.itemId) {
returnToChat() R.id.menu_call_open_chat -> {
return true returnToChat()
} else if (item.itemId == android.R.id.home) { true
// We check here as we want PiP in some cases }
onBackPressed() android.R.id.home -> {
return true // We check here as we want PiP in some cases
onBackPressed()
true
}
else -> false
} }
return super.onOptionsItemSelected(item)
} }
override fun onDestroy() { override fun onDestroy() {
detachRenderersIfNeeded() detachRenderersIfNeeded()
turnScreenOffAndKeyguardOn() turnScreenOffAndKeyguardOn()
removeOnPictureInPictureModeChangedListener(pictureInPictureModeChangedInfoConsumer)
super.onDestroy() super.onDestroy()
} }

View File

@ -19,12 +19,13 @@ package im.vector.app.features.call.conference
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.content.res.Configuration
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Parcelable import android.os.Parcelable
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.Toast import android.widget.Toast
import androidx.core.app.PictureInPictureModeChangedInfo
import androidx.core.util.Consumer
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Fail
@ -66,6 +67,7 @@ class VectorJitsiActivity : VectorBaseActivity<ActivityJitsiBinding>(), JitsiMee
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
addOnPictureInPictureModeChangedListener(pictureInPictureModeChangedInfoConsumer)
jitsiViewModel.onEach { jitsiViewModel.onEach {
renderState(it) renderState(it)
@ -109,6 +111,7 @@ class VectorJitsiActivity : VectorBaseActivity<ActivityJitsiBinding>(), JitsiMee
ConferenceEventEmitter(this).emitConferenceEnded() ConferenceEventEmitter(this).emitConferenceEnded()
} }
JitsiMeetActivityDelegate.onHostDestroy(this) JitsiMeetActivityDelegate.onHostDestroy(this)
removeOnPictureInPictureModeChangedListener(pictureInPictureModeChangedInfoConsumer)
super.onDestroy() super.onDestroy()
} }
@ -138,13 +141,9 @@ class VectorJitsiActivity : VectorBaseActivity<ActivityJitsiBinding>(), JitsiMee
.show() .show()
} }
override fun onPictureInPictureModeChanged( private val pictureInPictureModeChangedInfoConsumer = Consumer<PictureInPictureModeChangedInfo> {
isInPictureInPictureMode: Boolean,
newConfig: Configuration
) {
super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
checkIfActivityShouldBeFinished() checkIfActivityShouldBeFinished()
Timber.w("onPictureInPictureModeChanged($isInPictureInPictureMode)") Timber.w("onPictureInPictureModeChanged(${it.isInPictureInPictureMode})")
} }
private fun checkIfActivityShouldBeFinished() { private fun checkIfActivityShouldBeFinished() {

View File

@ -49,6 +49,7 @@ class CallTransferPagerAdapter(
fragment.arguments = UserListFragmentArgs( fragment.arguments = UserListFragmentArgs(
title = "", title = "",
menuResId = -1, menuResId = -1,
submitMenuItemId = -1,
singleSelection = true, singleSelection = true,
showInviteActions = false, showInviteActions = false,
showToolbar = false, showToolbar = false,

View File

@ -81,7 +81,7 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() {
when (action) { when (action) {
UserListSharedAction.Close -> finish() UserListSharedAction.Close -> finish()
UserListSharedAction.GoBack -> onBackPressed() UserListSharedAction.GoBack -> onBackPressed()
is UserListSharedAction.OnMenuItemSelected -> onMenuItemSelected(action) is UserListSharedAction.OnMenuItemSubmitClick -> handleOnMenuItemSubmitClick(action)
UserListSharedAction.OpenPhoneBook -> openPhoneBook() UserListSharedAction.OpenPhoneBook -> openPhoneBook()
UserListSharedAction.AddByQrCode -> openAddByQrCode() UserListSharedAction.AddByQrCode -> openAddByQrCode()
} }
@ -93,7 +93,8 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() {
UserListFragment::class.java, UserListFragment::class.java,
UserListFragmentArgs( UserListFragmentArgs(
title = getString(R.string.fab_menu_create_chat), title = getString(R.string.fab_menu_create_chat),
menuResId = R.menu.vector_create_direct_room menuResId = R.menu.vector_create_direct_room,
submitMenuItemId = R.id.action_create_direct_room,
) )
) )
} }
@ -159,10 +160,8 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() {
} }
} }
private fun onMenuItemSelected(action: UserListSharedAction.OnMenuItemSelected) { private fun handleOnMenuItemSubmitClick(action: UserListSharedAction.OnMenuItemSubmitClick) {
if (action.itemId == R.id.action_create_direct_room) { viewModel.handle(CreateDirectRoomAction.CreateRoomAndInviteSelectedUsers(action.selections))
viewModel.handle(CreateDirectRoomAction.CreateRoomAndInviteSelectedUsers(action.selections))
}
} }
private fun renderCreateAndInviteState(state: Async<String>) { private fun renderCreateAndInviteState(state: Async<String>) {

View File

@ -187,16 +187,6 @@ class KeysBackupSetupActivity : SimpleFragmentActivity() {
} }
} }
// I think this code is useful, but it violates the code quality rules
// override fun onOptionsItemSelected(item: MenuItem): Boolean {
// if (item.itemId == android .R. id. home) {
// onBackPressed()
// return true
// }
//
// return super.onOptionsItemSelected(item)
// }
companion object { companion object {
const val KEYS_VERSION = "KEYS_VERSION" const val KEYS_VERSION = "KEYS_VERSION"
const val MANUAL_EXPORT = "MANUAL_EXPORT" const val MANUAL_EXPORT = "MANUAL_EXPORT"

View File

@ -21,7 +21,6 @@ import android.content.Intent
import android.os.Parcelable import android.os.Parcelable
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import androidx.core.view.forEach
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Fail
@ -36,6 +35,7 @@ import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.extensions.replaceFragment
import im.vector.app.core.platform.SimpleFragmentActivity import im.vector.app.core.platform.SimpleFragmentActivity
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.utils.createJSonViewerStyleProvider import im.vector.app.core.utils.createJSonViewerStyleProvider
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ -43,7 +43,10 @@ import org.billcarsonfr.jsonviewer.JSonViewerFragment
import javax.inject.Inject import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
class RoomDevToolActivity : SimpleFragmentActivity(), FragmentManager.OnBackStackChangedListener { class RoomDevToolActivity :
SimpleFragmentActivity(),
FragmentManager.OnBackStackChangedListener,
VectorMenuProvider {
@Inject lateinit var colorProvider: ColorProvider @Inject lateinit var colorProvider: ColorProvider
@ -133,16 +136,18 @@ class RoomDevToolActivity : SimpleFragmentActivity(), FragmentManager.OnBackStac
} }
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun handleMenuItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.menuItemEdit) { return when (item.itemId) {
viewModel.handle(RoomDevToolAction.MenuEdit) R.id.menuItemEdit -> {
return true viewModel.handle(RoomDevToolAction.MenuEdit)
true
}
R.id.menuItemSend -> {
viewModel.handle(RoomDevToolAction.MenuItemSend)
true
}
else -> false
} }
if (item.itemId == R.id.menuItemSend) {
viewModel.handle(RoomDevToolAction.MenuItemSend)
return true
}
return super.onOptionsItemSelected(item)
} }
override fun onBackPressed() { override fun onBackPressed() {
@ -174,21 +179,12 @@ class RoomDevToolActivity : SimpleFragmentActivity(), FragmentManager.OnBackStac
super.onDestroy() super.onDestroy()
} }
override fun onPrepareOptionsMenu(menu: Menu?): Boolean = withState(viewModel) { state -> override fun handlePrepareMenu(menu: Menu) {
menu?.forEach { withState(viewModel) { state ->
val isVisible = when (it.itemId) { menu.findItem(R.id.menuItemEdit).isVisible = state.displayMode == RoomDevToolViewState.Mode.StateEventDetail
R.id.menuItemEdit -> { menu.findItem(R.id.menuItemSend).isVisible = state.displayMode == RoomDevToolViewState.Mode.EditEventContent ||
state.displayMode is RoomDevToolViewState.Mode.StateEventDetail state.displayMode is RoomDevToolViewState.Mode.SendEventForm
}
R.id.menuItemSend -> {
state.displayMode is RoomDevToolViewState.Mode.EditEventContent ||
state.displayMode is RoomDevToolViewState.Mode.SendEventForm
}
else -> true
}
it.isVisible = isVisible
} }
return@withState true
} }
companion object { companion object {

View File

@ -43,6 +43,7 @@ import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.extensions.replaceFragment
import im.vector.app.core.extensions.validateBackPressed import im.vector.app.core.extensions.validateBackPressed
import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.core.platform.VectorMenuProvider
import im.vector.app.core.pushers.PushersManager import im.vector.app.core.pushers.PushersManager
import im.vector.app.core.pushers.UnifiedPushHelper import im.vector.app.core.pushers.UnifiedPushHelper
import im.vector.app.databinding.ActivityHomeBinding import im.vector.app.databinding.ActivityHomeBinding
@ -103,7 +104,8 @@ class HomeActivity :
VectorBaseActivity<ActivityHomeBinding>(), VectorBaseActivity<ActivityHomeBinding>(),
NavigationInterceptor, NavigationInterceptor,
SpaceInviteBottomSheet.InteractionListener, SpaceInviteBottomSheet.InteractionListener,
MatrixToBottomSheet.InteractionListener { MatrixToBottomSheet.InteractionListener,
VectorMenuProvider {
private lateinit var sharedActionViewModel: HomeSharedActionViewModel private lateinit var sharedActionViewModel: HomeSharedActionViewModel
@ -547,47 +549,45 @@ class HomeActivity :
override fun getMenuRes() = R.menu.home override fun getMenuRes() = R.menu.home
override fun onPrepareOptionsMenu(menu: Menu): Boolean { override fun handlePrepareMenu(menu: Menu) {
menu.findItem(R.id.menu_home_init_sync_legacy).isVisible = vectorPreferences.developerMode() menu.findItem(R.id.menu_home_init_sync_legacy).isVisible = vectorPreferences.developerMode()
menu.findItem(R.id.menu_home_init_sync_optimized).isVisible = vectorPreferences.developerMode() menu.findItem(R.id.menu_home_init_sync_optimized).isVisible = vectorPreferences.developerMode()
return super.onPrepareOptionsMenu(menu)
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun handleMenuItemSelected(item: MenuItem): Boolean {
when (item.itemId) { return when (item.itemId) {
R.id.menu_home_suggestion -> { R.id.menu_home_suggestion -> {
bugReporter.openBugReportScreen(this, ReportType.SUGGESTION) bugReporter.openBugReportScreen(this, ReportType.SUGGESTION)
return true true
} }
R.id.menu_home_report_bug -> { R.id.menu_home_report_bug -> {
bugReporter.openBugReportScreen(this, ReportType.BUG_REPORT) bugReporter.openBugReportScreen(this, ReportType.BUG_REPORT)
return true true
} }
R.id.menu_home_init_sync_legacy -> { R.id.menu_home_init_sync_legacy -> {
// Configure the SDK // Configure the SDK
initialSyncStrategy = InitialSyncStrategy.Legacy initialSyncStrategy = InitialSyncStrategy.Legacy
// And clear cache // And clear cache
MainActivity.restartApp(this, MainActivityArgs(clearCache = true)) MainActivity.restartApp(this, MainActivityArgs(clearCache = true))
return true true
} }
R.id.menu_home_init_sync_optimized -> { R.id.menu_home_init_sync_optimized -> {
// Configure the SDK // Configure the SDK
initialSyncStrategy = InitialSyncStrategy.Optimized() initialSyncStrategy = InitialSyncStrategy.Optimized()
// And clear cache // And clear cache
MainActivity.restartApp(this, MainActivityArgs(clearCache = true)) MainActivity.restartApp(this, MainActivityArgs(clearCache = true))
return true true
} }
R.id.menu_home_filter -> { R.id.menu_home_filter -> {
navigator.openRoomsFiltering(this) navigator.openRoomsFiltering(this)
return true true
} }
R.id.menu_home_setting -> { R.id.menu_home_setting -> {
navigator.openSettings(this) navigator.openSettings(this)
return true true
} }
else -> false
} }
return super.onOptionsItemSelected(item)
} }
override fun onBackPressed() { override fun onBackPressed() {

View File

@ -36,6 +36,7 @@ import im.vector.app.core.extensions.toMvRxBundle
import im.vector.app.core.platform.OnBackPressed import im.vector.app.core.platform.OnBackPressed
import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseActivity
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.resources.ColorProvider import im.vector.app.core.resources.ColorProvider
import im.vector.app.core.ui.views.CurrentCallsView import im.vector.app.core.ui.views.CurrentCallsView
import im.vector.app.core.ui.views.CurrentCallsViewPresenter import im.vector.app.core.ui.views.CurrentCallsViewPresenter
@ -71,7 +72,8 @@ class HomeDetailFragment @Inject constructor(
) : VectorBaseFragment<FragmentHomeDetailBinding>(), ) : VectorBaseFragment<FragmentHomeDetailBinding>(),
KeysBackupBanner.Delegate, KeysBackupBanner.Delegate,
CurrentCallsView.Callback, CurrentCallsView.Callback,
OnBackPressed { OnBackPressed,
VectorMenuProvider {
private val viewModel: HomeDetailViewModel by fragmentViewModel() private val viewModel: HomeDetailViewModel by fragmentViewModel()
private val unknownDeviceDetectorSharedViewModel: UnknownDeviceDetectorSharedViewModel by activityViewModel() private val unknownDeviceDetectorSharedViewModel: UnknownDeviceDetectorSharedViewModel by activityViewModel()
@ -91,23 +93,21 @@ class HomeDetailFragment @Inject constructor(
override fun getMenuRes() = R.menu.room_list override fun getMenuRes() = R.menu.room_list
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun handleMenuItemSelected(item: MenuItem): Boolean {
when (item.itemId) { return when (item.itemId) {
R.id.menu_home_mark_all_as_read -> { R.id.menu_home_mark_all_as_read -> {
viewModel.handle(HomeDetailAction.MarkAllRoomsRead) viewModel.handle(HomeDetailAction.MarkAllRoomsRead)
return true true
} }
else -> false
} }
return super.onOptionsItemSelected(item)
} }
override fun onPrepareOptionsMenu(menu: Menu) { override fun handlePrepareMenu(menu: Menu) {
withState(viewModel) { state -> withState(viewModel) { state ->
val isRoomList = state.currentTab is HomeTab.RoomList val isRoomList = state.currentTab is HomeTab.RoomList
menu.findItem(R.id.menu_home_mark_all_as_read).isVisible = isRoomList && hasUnreadRooms menu.findItem(R.id.menu_home_mark_all_as_read).isVisible = isRoomList && hasUnreadRooms
} }
super.onPrepareOptionsMenu(menu)
} }
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentHomeDetailBinding { override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentHomeDetailBinding {

View File

@ -30,7 +30,6 @@ import android.view.HapticFeedbackConstants
import android.view.KeyEvent import android.view.KeyEvent
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -89,6 +88,7 @@ import im.vector.app.core.hardware.vibrate
import im.vector.app.core.intent.getFilenameFromUri import im.vector.app.core.intent.getFilenameFromUri
import im.vector.app.core.intent.getMimeTypeFromUri import im.vector.app.core.intent.getMimeTypeFromUri
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.lifecycleAwareLazy import im.vector.app.core.platform.lifecycleAwareLazy
import im.vector.app.core.platform.showOptimizedSnackbar import im.vector.app.core.platform.showOptimizedSnackbar
import im.vector.app.core.resources.ColorProvider import im.vector.app.core.resources.ColorProvider
@ -280,7 +280,8 @@ class TimelineFragment @Inject constructor(
AttachmentTypeSelectorView.Callback, AttachmentTypeSelectorView.Callback,
AttachmentsHelper.Callback, AttachmentsHelper.Callback,
GalleryOrCameraDialogHelper.Listener, GalleryOrCameraDialogHelper.Listener,
CurrentCallsView.Callback { CurrentCallsView.Callback,
VectorMenuProvider {
companion object { companion object {
@ -1055,15 +1056,14 @@ class TimelineFragment @Inject constructor(
} }
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { override fun handlePostCreateMenu(menu: Menu) {
if (isThreadTimeLine()) { if (isThreadTimeLine()) {
if (menu is MenuBuilder) menu.setOptionalIconsVisible(true) if (menu is MenuBuilder) menu.setOptionalIconsVisible(true)
} }
super.onCreateOptionsMenu(menu, inflater)
// We use a custom layout for this menu item, so we need to set a ClickListener // We use a custom layout for this menu item, so we need to set a ClickListener
menu.findItem(R.id.open_matrix_apps)?.let { menuItem -> menu.findItem(R.id.open_matrix_apps)?.let { menuItem ->
menuItem.actionView.debouncedClicks { menuItem.actionView.debouncedClicks {
onOptionsItemSelected(menuItem) handleMenuItemSelected(menuItem)
} }
} }
val joinConfItem = menu.findItem(R.id.join_conference) val joinConfItem = menu.findItem(R.id.join_conference)
@ -1073,13 +1073,13 @@ class TimelineFragment @Inject constructor(
// Custom thread notification menu item // Custom thread notification menu item
menu.findItem(R.id.menu_timeline_thread_list)?.let { menuItem -> menu.findItem(R.id.menu_timeline_thread_list)?.let { menuItem ->
menuItem.actionView.setOnClickListener { menuItem.actionView.debouncedClicks {
onOptionsItemSelected(menuItem) handleMenuItemSelected(menuItem)
} }
} }
} }
override fun onPrepareOptionsMenu(menu: Menu) { override fun handlePrepareMenu(menu: Menu) {
menu.forEach { menu.forEach {
it.isVisible = timelineViewModel.isMenuItemVisible(it.itemId) it.isVisible = timelineViewModel.isMenuItemVisible(it.itemId)
} }
@ -1121,7 +1121,7 @@ class TimelineFragment @Inject constructor(
} }
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) { return when (item.itemId) {
R.id.invite -> { R.id.invite -> {
navigator.openInviteUsersToRoom(requireActivity(), timelineArgs.roomId) navigator.openInviteUsersToRoom(requireActivity(), timelineArgs.roomId)
@ -1174,7 +1174,7 @@ class TimelineFragment @Inject constructor(
} }
true true
} }
else -> super.onOptionsItemSelected(item) else -> false
} }
} }

View File

@ -19,7 +19,6 @@ package im.vector.app.features.home.room.threads.list.views
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -31,6 +30,7 @@ import im.vector.app.R
import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.configureWith
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.databinding.FragmentThreadListBinding import im.vector.app.databinding.FragmentThreadListBinding
import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.analytics.plan.MobileScreen
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
@ -54,7 +54,8 @@ class ThreadListFragment @Inject constructor(
private val threadListController: ThreadListController, private val threadListController: ThreadListController,
val threadListViewModelFactory: ThreadListViewModel.Factory val threadListViewModelFactory: ThreadListViewModel.Factory
) : VectorBaseFragment<FragmentThreadListBinding>(), ) : VectorBaseFragment<FragmentThreadListBinding>(),
ThreadListController.Listener { ThreadListController.Listener,
VectorMenuProvider {
private val threadListViewModel: ThreadListViewModel by fragmentViewModel() private val threadListViewModel: ThreadListViewModel by fragmentViewModel()
@ -71,27 +72,26 @@ class ThreadListFragment @Inject constructor(
analyticsScreenName = MobileScreen.ScreenName.ThreadList analyticsScreenName = MobileScreen.ScreenName.ThreadList
} }
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { override fun handlePostCreateMenu(menu: Menu) {
super.onCreateOptionsMenu(menu, inflater) // We use a custom layout for this menu item, so we need to set a ClickListener
menu.findItem(R.id.menu_thread_list_filter)?.let { menuItem -> menu.findItem(R.id.menu_thread_list_filter)?.let { menuItem ->
menuItem.actionView.setOnClickListener { menuItem.actionView.debouncedClicks {
onOptionsItemSelected(menuItem) handleMenuItemSelected(menuItem)
} }
} }
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) { return when (item.itemId) {
R.id.menu_thread_list_filter -> { R.id.menu_thread_list_filter -> {
ThreadListBottomSheet().show(childFragmentManager, "Filtering") ThreadListBottomSheet().show(childFragmentManager, "Filtering")
true true
} }
else -> super.onOptionsItemSelected(item) else -> false
} }
} }
override fun onPrepareOptionsMenu(menu: Menu) { override fun handlePrepareMenu(menu: Menu) {
withState(threadListViewModel) { state -> withState(threadListViewModel) { state ->
val filterIcon = menu.findItem(R.id.menu_thread_list_filter).actionView val filterIcon = menu.findItem(R.id.menu_thread_list_filter).actionView
val filterBadge = filterIcon.findViewById<View>(R.id.threadListFilterBadge) val filterBadge = filterIcon.findViewById<View>(R.id.threadListFilterBadge)

View File

@ -71,7 +71,7 @@ class InviteUsersToRoomActivity : SimpleFragmentActivity() {
when (sharedAction) { when (sharedAction) {
UserListSharedAction.Close -> finish() UserListSharedAction.Close -> finish()
UserListSharedAction.GoBack -> onBackPressed() UserListSharedAction.GoBack -> onBackPressed()
is UserListSharedAction.OnMenuItemSelected -> onMenuItemSelected(sharedAction) is UserListSharedAction.OnMenuItemSubmitClick -> handleOnMenuItemSubmitClick(sharedAction)
UserListSharedAction.OpenPhoneBook -> openPhoneBook() UserListSharedAction.OpenPhoneBook -> openPhoneBook()
// not exhaustive because it's a sharedAction // not exhaustive because it's a sharedAction
else -> Unit else -> Unit
@ -85,6 +85,7 @@ class InviteUsersToRoomActivity : SimpleFragmentActivity() {
UserListFragmentArgs( UserListFragmentArgs(
title = getString(R.string.invite_users_to_room_title), title = getString(R.string.invite_users_to_room_title),
menuResId = R.menu.vector_invite_users_to_room, menuResId = R.menu.vector_invite_users_to_room,
submitMenuItemId = R.id.action_invite_users_to_room_invite,
excludedUserIds = viewModel.getUserIdsOfRoomMembers(), excludedUserIds = viewModel.getUserIdsOfRoomMembers(),
showInviteActions = false showInviteActions = false
) )
@ -94,10 +95,8 @@ class InviteUsersToRoomActivity : SimpleFragmentActivity() {
viewModel.observeViewEvents { renderInviteEvents(it) } viewModel.observeViewEvents { renderInviteEvents(it) }
} }
private fun onMenuItemSelected(action: UserListSharedAction.OnMenuItemSelected) { private fun handleOnMenuItemSubmitClick(action: UserListSharedAction.OnMenuItemSubmitClick) {
if (action.itemId == R.id.action_invite_users_to_room_invite) { viewModel.handle(InviteUsersToRoomAction.InviteSelectedUsers(action.selections))
viewModel.handle(InviteUsersToRoomAction.InviteSelectedUsers(action.selections))
}
} }
private fun openPhoneBook() { private fun openPhoneBook() {

View File

@ -26,6 +26,7 @@ import com.airbnb.mvrx.args
import com.mapbox.mapboxsdk.maps.MapView import com.mapbox.mapboxsdk.maps.MapView
import im.vector.app.R import im.vector.app.R
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.utils.openLocation import im.vector.app.core.utils.openLocation
import im.vector.app.databinding.FragmentLocationPreviewBinding import im.vector.app.databinding.FragmentLocationPreviewBinding
import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider
@ -38,7 +39,8 @@ import javax.inject.Inject
class LocationPreviewFragment @Inject constructor( class LocationPreviewFragment @Inject constructor(
private val urlMapProvider: UrlMapProvider, private val urlMapProvider: UrlMapProvider,
private val locationPinProvider: LocationPinProvider private val locationPinProvider: LocationPinProvider
) : VectorBaseFragment<FragmentLocationPreviewBinding>() { ) : VectorBaseFragment<FragmentLocationPreviewBinding>(),
VectorMenuProvider {
private val args: LocationSharingArgs by args() private val args: LocationSharingArgs by args()
@ -99,14 +101,14 @@ class LocationPreviewFragment @Inject constructor(
override fun getMenuRes() = R.menu.menu_location_preview override fun getMenuRes() = R.menu.menu_location_preview
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun handleMenuItemSelected(item: MenuItem): Boolean {
when (item.itemId) { return when (item.itemId) {
R.id.share_external -> { R.id.share_external -> {
onShareLocationExternal() onShareLocationExternal()
return true true
} }
else -> false
} }
return super.onOptionsItemSelected(item)
} }
private fun onShareLocationExternal() { private fun onShareLocationExternal() {

View File

@ -28,6 +28,7 @@ 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.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.core.platform.VectorMenuProvider
import im.vector.app.databinding.ActivityBugReportBinding import im.vector.app.databinding.ActivityBugReportBinding
import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.extensions.tryOrNull
import timber.log.Timber import timber.log.Timber
@ -36,7 +37,9 @@ import timber.log.Timber
* Form to send a bug report. * Form to send a bug report.
*/ */
@AndroidEntryPoint @AndroidEntryPoint
class BugReportActivity : VectorBaseActivity<ActivityBugReportBinding>() { class BugReportActivity :
VectorBaseActivity<ActivityBugReportBinding>(),
VectorMenuProvider {
override fun getBinding() = ActivityBugReportBinding.inflate(layoutInflater) override fun getBinding() = ActivityBugReportBinding.inflate(layoutInflater)
@ -120,29 +123,27 @@ class BugReportActivity : VectorBaseActivity<ActivityBugReportBinding>() {
override fun getMenuRes() = R.menu.bug_report override fun getMenuRes() = R.menu.bug_report
override fun onPrepareOptionsMenu(menu: Menu): Boolean { override fun handlePrepareMenu(menu: Menu) {
menu.findItem(R.id.ic_action_send_bug_report)?.let { menu.findItem(R.id.ic_action_send_bug_report)?.let {
val isValid = !views.bugReportMaskView.isVisible val isValid = !views.bugReportMaskView.isVisible
it.isEnabled = isValid it.isEnabled = isValid
it.icon.alpha = if (isValid) 255 else 100 it.icon.alpha = if (isValid) 255 else 100
} }
return super.onPrepareOptionsMenu(menu)
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun handleMenuItemSelected(item: MenuItem): Boolean {
when (item.itemId) { return when (item.itemId) {
R.id.ic_action_send_bug_report -> { R.id.ic_action_send_bug_report -> {
if (views.bugReportEditText.text.toString().trim().length >= 10) { if (views.bugReportEditText.text.toString().trim().length >= 10) {
sendBugReport() sendBugReport()
} else { } else {
views.bugReportTextInputLayout.error = getString(R.string.bug_report_error_too_short) views.bugReportTextInputLayout.error = getString(R.string.bug_report_error_too_short)
} }
return true true
} }
else -> false
} }
return super.onOptionsItemSelected(item)
} }
/** /**

View File

@ -21,7 +21,6 @@ import android.content.Intent
import android.graphics.Typeface import android.graphics.Typeface
import android.util.TypedValue import android.util.TypedValue
import android.view.Menu import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem import android.view.MenuItem
import android.widget.SearchView import android.widget.SearchView
import androidx.core.view.isVisible import androidx.core.view.isVisible
@ -33,6 +32,7 @@ import im.vector.app.EmojiCompatFontProvider
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.extensions.observeEvent import im.vector.app.core.extensions.observeEvent
import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.core.platform.VectorMenuProvider
import im.vector.app.databinding.ActivityEmojiReactionPickerBinding import im.vector.app.databinding.ActivityEmojiReactionPickerBinding
import im.vector.app.features.reactions.data.EmojiDataSource import im.vector.app.features.reactions.data.EmojiDataSource
import im.vector.lib.core.utils.flow.throttleFirst import im.vector.lib.core.utils.flow.throttleFirst
@ -48,13 +48,17 @@ import javax.inject.Inject
* TODO Finish Refactor to vector base activity * TODO Finish Refactor to vector base activity
*/ */
@AndroidEntryPoint @AndroidEntryPoint
class EmojiReactionPickerActivity : VectorBaseActivity<ActivityEmojiReactionPickerBinding>(), class EmojiReactionPickerActivity :
EmojiCompatFontProvider.FontProviderListener { VectorBaseActivity<ActivityEmojiReactionPickerBinding>(),
EmojiCompatFontProvider.FontProviderListener,
VectorMenuProvider {
lateinit var viewModel: EmojiChooserViewModel lateinit var viewModel: EmojiChooserViewModel
override fun getMenuRes() = R.menu.menu_emoji_reaction_picker override fun getMenuRes() = R.menu.menu_emoji_reaction_picker
override fun handleMenuItemSelected(item: MenuItem) = false
override fun getBinding() = ActivityEmojiReactionPickerBinding.inflate(layoutInflater) override fun getBinding() = ActivityEmojiReactionPickerBinding.inflate(layoutInflater)
override fun getCoordinatorLayout() = views.coordinatorLayout override fun getCoordinatorLayout() = views.coordinatorLayout
@ -138,10 +142,7 @@ class EmojiReactionPickerActivity : VectorBaseActivity<ActivityEmojiReactionPick
super.onDestroy() super.onDestroy()
} }
override fun onCreateOptionsMenu(menu: Menu): Boolean { override fun handlePostCreateMenu(menu: Menu) {
val inflater: MenuInflater = menuInflater
inflater.inflate(getMenuRes(), menu)
val searchItem = menu.findItem(R.id.search) val searchItem = menu.findItem(R.id.search)
(searchItem.actionView as? SearchView)?.let { searchView -> (searchItem.actionView as? SearchView)?.let { searchView ->
searchItem.setOnActionExpandListener(object : MenuItem.OnActionExpandListener { searchItem.setOnActionExpandListener(object : MenuItem.OnActionExpandListener {
@ -175,7 +176,6 @@ class EmojiReactionPickerActivity : VectorBaseActivity<ActivityEmojiReactionPick
.launchIn(lifecycleScope) .launchIn(lifecycleScope)
} }
searchItem.expandActionView() searchItem.expandActionView()
return true
} }
// TODO move to ThemeUtils when core module is created // TODO move to ThemeUtils when core module is created

View File

@ -30,6 +30,7 @@ import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.configureWith
import im.vector.app.core.extensions.trackItemsVisibilityChange import im.vector.app.core.extensions.trackItemsVisibilityChange
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.showOptimizedSnackbar import im.vector.app.core.platform.showOptimizedSnackbar
import im.vector.app.core.utils.toast import im.vector.app.core.utils.toast
import im.vector.app.databinding.FragmentPublicRoomsBinding import im.vector.app.databinding.FragmentPublicRoomsBinding
@ -55,7 +56,8 @@ class PublicRoomsFragment @Inject constructor(
private val permalinkHandler: PermalinkHandler, private val permalinkHandler: PermalinkHandler,
private val session: Session private val session: Session
) : VectorBaseFragment<FragmentPublicRoomsBinding>(), ) : VectorBaseFragment<FragmentPublicRoomsBinding>(),
PublicRoomsController.Callback { PublicRoomsController.Callback,
VectorMenuProvider {
private val viewModel: RoomDirectoryViewModel by activityViewModel() private val viewModel: RoomDirectoryViewModel by activityViewModel()
private lateinit var sharedActionViewModel: RoomDirectorySharedActionViewModel private lateinit var sharedActionViewModel: RoomDirectorySharedActionViewModel
@ -105,14 +107,13 @@ class PublicRoomsFragment @Inject constructor(
super.onDestroyView() super.onDestroyView()
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) { return when (item.itemId) {
R.id.menu_room_directory_change_protocol -> { R.id.menu_room_directory_change_protocol -> {
sharedActionViewModel.post(RoomDirectorySharedAction.ChangeProtocol) sharedActionViewModel.post(RoomDirectorySharedAction.ChangeProtocol)
true true
} }
else -> else -> false
super.onOptionsItemSelected(item)
} }
} }

View File

@ -42,6 +42,7 @@ import im.vector.app.core.extensions.copyOnLongClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.core.platform.StateView import im.vector.app.core.platform.StateView
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.utils.startSharePlainTextIntent import im.vector.app.core.utils.startSharePlainTextIntent
import im.vector.app.databinding.DialogBaseEditTextBinding import im.vector.app.databinding.DialogBaseEditTextBinding
import im.vector.app.databinding.DialogShareQrCodeBinding import im.vector.app.databinding.DialogShareQrCodeBinding
@ -74,7 +75,8 @@ class RoomMemberProfileFragment @Inject constructor(
private val roomDetailPendingActionStore: RoomDetailPendingActionStore, private val roomDetailPendingActionStore: RoomDetailPendingActionStore,
private val matrixItemColorProvider: MatrixItemColorProvider private val matrixItemColorProvider: MatrixItemColorProvider
) : VectorBaseFragment<FragmentMatrixProfileBinding>(), ) : VectorBaseFragment<FragmentMatrixProfileBinding>(),
RoomMemberProfileController.Callback { RoomMemberProfileController.Callback,
VectorMenuProvider {
private lateinit var headerViews: ViewStubRoomMemberProfileHeaderBinding private lateinit var headerViews: ViewStubRoomMemberProfileHeaderBinding
@ -160,14 +162,14 @@ class RoomMemberProfileFragment @Inject constructor(
} }
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun handleMenuItemSelected(item: MenuItem): Boolean {
when (item.itemId) { return when (item.itemId) {
R.id.roomMemberProfileShareAction -> { R.id.roomMemberProfileShareAction -> {
viewModel.handle(RoomMemberProfileAction.ShareRoomMemberProfile) viewModel.handle(RoomMemberProfileAction.ShareRoomMemberProfile)
return true true
} }
else -> false
} }
return super.onOptionsItemSelected(item)
} }
private fun handleStartVerification(startVerification: RoomMemberProfileViewEvents.StartVerification) { private fun handleStartVerification(startVerification: RoomMemberProfileViewEvents.StartVerification) {

View File

@ -39,6 +39,7 @@ import im.vector.app.core.extensions.configureWith
import im.vector.app.core.extensions.copyOnLongClick import im.vector.app.core.extensions.copyOnLongClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
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.utils.copyToClipboard import im.vector.app.core.utils.copyToClipboard
import im.vector.app.core.utils.startSharePlainTextIntent import im.vector.app.core.utils.startSharePlainTextIntent
import im.vector.app.databinding.FragmentMatrixProfileBinding import im.vector.app.databinding.FragmentMatrixProfileBinding
@ -70,7 +71,8 @@ class RoomProfileFragment @Inject constructor(
private val roomDetailPendingActionStore: RoomDetailPendingActionStore, private val roomDetailPendingActionStore: RoomDetailPendingActionStore,
) : ) :
VectorBaseFragment<FragmentMatrixProfileBinding>(), VectorBaseFragment<FragmentMatrixProfileBinding>(),
RoomProfileController.Callback { RoomProfileController.Callback,
VectorMenuProvider {
private lateinit var headerViews: ViewStubRoomProfileHeaderBinding private lateinit var headerViews: ViewStubRoomProfileHeaderBinding
@ -170,14 +172,14 @@ class RoomProfileFragment @Inject constructor(
headerViews.roomProfileAliasView.copyOnLongClick() headerViews.roomProfileAliasView.copyOnLongClick()
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun handleMenuItemSelected(item: MenuItem): Boolean {
when (item.itemId) { return when (item.itemId) {
R.id.roomProfileShareAction -> { R.id.roomProfileShareAction -> {
roomProfileViewModel.handle(RoomProfileAction.ShareRoomProfile) roomProfileViewModel.handle(RoomProfileAction.ShareRoomProfile)
return true true
} }
else -> false
} }
return super.onOptionsItemSelected(item)
} }
private fun handleQuickActions(action: RoomListQuickActionsSharedAction) = when (action) { private fun handleQuickActions(action: RoomListQuickActionsSharedAction) = when (action) {

View File

@ -36,6 +36,7 @@ import im.vector.app.core.extensions.configureWith
import im.vector.app.core.intent.getFilenameFromUri import im.vector.app.core.intent.getFilenameFromUri
import im.vector.app.core.platform.OnBackPressed import im.vector.app.core.platform.OnBackPressed
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.resources.ColorProvider import im.vector.app.core.resources.ColorProvider
import im.vector.app.core.time.Clock import im.vector.app.core.time.Clock
import im.vector.app.core.utils.toast import im.vector.app.core.utils.toast
@ -64,7 +65,8 @@ class RoomSettingsFragment @Inject constructor(
VectorBaseFragment<FragmentRoomSettingGenericBinding>(), VectorBaseFragment<FragmentRoomSettingGenericBinding>(),
RoomSettingsController.Callback, RoomSettingsController.Callback,
OnBackPressed, OnBackPressed,
GalleryOrCameraDialogHelper.Listener { GalleryOrCameraDialogHelper.Listener,
VectorMenuProvider {
private val viewModel: RoomSettingsViewModel by fragmentViewModel() private val viewModel: RoomSettingsViewModel by fragmentViewModel()
private lateinit var roomProfileSharedActionViewModel: RoomProfileSharedActionViewModel private lateinit var roomProfileSharedActionViewModel: RoomProfileSharedActionViewModel
@ -139,18 +141,20 @@ class RoomSettingsFragment @Inject constructor(
super.onDestroyView() super.onDestroyView()
} }
override fun onPrepareOptionsMenu(menu: Menu) { override fun handlePrepareMenu(menu: Menu) {
withState(viewModel) { state -> withState(viewModel) { state ->
menu.findItem(R.id.roomSettingsSaveAction).isVisible = state.showSaveAction menu.findItem(R.id.roomSettingsSaveAction).isVisible = state.showSaveAction
} }
super.onPrepareOptionsMenu(menu)
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun handleMenuItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.roomSettingsSaveAction) { return when (item.itemId) {
viewModel.handle(RoomSettingsAction.Save) R.id.roomSettingsSaveAction -> {
viewModel.handle(RoomSettingsAction.Save)
true
}
else -> false
} }
return super.onOptionsItemSelected(item)
} }
override fun invalidate() = withState(viewModel) { viewState -> override fun invalidate() = withState(viewModel) { viewState ->

View File

@ -26,8 +26,6 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_IDLE
import com.airbnb.mvrx.Loading import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState import com.airbnb.mvrx.withState
@ -36,6 +34,7 @@ import im.vector.app.R
import im.vector.app.core.extensions.registerStartForActivityResult import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.extensions.safeOpenOutputStream import im.vector.app.core.extensions.safeOpenOutputStream
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.time.Clock import im.vector.app.core.time.Clock
import im.vector.app.core.utils.selectTxtFileToWrite import im.vector.app.core.utils.selectTxtFileToWrite
import im.vector.app.databinding.FragmentDevtoolKeyrequestsBinding import im.vector.app.databinding.FragmentDevtoolKeyrequestsBinding
@ -44,7 +43,8 @@ import javax.inject.Inject
class KeyRequestsFragment @Inject constructor( class KeyRequestsFragment @Inject constructor(
private val clock: Clock, private val clock: Clock,
) : VectorBaseFragment<FragmentDevtoolKeyrequestsBinding>() { ) : VectorBaseFragment<FragmentDevtoolKeyrequestsBinding>(),
VectorMenuProvider {
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentDevtoolKeyrequestsBinding { override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentDevtoolKeyrequestsBinding {
return FragmentDevtoolKeyrequestsBinding.inflate(inflater, container, false) return FragmentDevtoolKeyrequestsBinding.inflate(inflater, container, false)
@ -61,19 +61,6 @@ class KeyRequestsFragment @Inject constructor(
override fun getMenuRes(): Int = R.menu.menu_audit override fun getMenuRes(): Int = R.menu.menu_audit
private val pageAdapterListener = object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
invalidateOptionsMenu()
}
override fun onPageScrollStateChanged(state: Int) {
childFragmentManager.fragments.forEach {
it.setHasOptionsMenu(state == SCROLL_STATE_IDLE)
}
invalidateOptionsMenu()
}
}
override fun invalidate() = withState(viewModel) { override fun invalidate() = withState(viewModel) {
when (it.exporting) { when (it.exporting) {
is Loading -> views.exportWaitingView.isVisible = true is Loading -> views.exportWaitingView.isVisible = true
@ -81,16 +68,10 @@ class KeyRequestsFragment @Inject constructor(
} }
} }
override fun onDestroy() {
invalidateOptionsMenu()
super.onDestroy()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
mPagerAdapter = KeyReqPagerAdapter(this) mPagerAdapter = KeyReqPagerAdapter(this)
views.devToolKeyRequestPager.adapter = mPagerAdapter views.devToolKeyRequestPager.adapter = mPagerAdapter
views.devToolKeyRequestPager.registerOnPageChangeCallback(pageAdapterListener)
TabLayoutMediator(views.devToolKeyRequestTabs, views.devToolKeyRequestPager) { tab, position -> TabLayoutMediator(views.devToolKeyRequestTabs, views.devToolKeyRequestPager) { tab, position ->
when (position) { when (position) {
@ -119,25 +100,26 @@ class KeyRequestsFragment @Inject constructor(
} }
override fun onDestroyView() { override fun onDestroyView() {
views.devToolKeyRequestPager.unregisterOnPageChangeCallback(pageAdapterListener)
mPagerAdapter = null mPagerAdapter = null
super.onDestroyView() super.onDestroyView()
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun handleMenuItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.audit_export) { return when (item.itemId) {
selectTxtFileToWrite( R.id.audit_export -> {
activity = requireActivity(), selectTxtFileToWrite(
activityResultLauncher = epxortAuditForActivityResult, activity = requireActivity(),
defaultFileName = "audit-export_${clock.epochMillis()}.txt", activityResultLauncher = exportAuditForActivityResult,
chooserHint = "Export Audit" defaultFileName = "audit-export_${clock.epochMillis()}.txt",
) chooserHint = "Export Audit"
return true )
true
}
else -> false
} }
return super.onOptionsItemSelected(item)
} }
private val epxortAuditForActivityResult = registerStartForActivityResult { activityResult -> private val exportAuditForActivityResult = registerStartForActivityResult { activityResult ->
if (activityResult.resultCode == Activity.RESULT_OK) { if (activityResult.resultCode == Activity.RESULT_OK) {
val uri = activityResult.data?.data val uri = activityResult.data?.data
if (uri != null) { if (uri != null) {

View File

@ -29,6 +29,7 @@ import im.vector.app.R
import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.configureWith
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.databinding.FragmentGenericRecyclerBinding import im.vector.app.databinding.FragmentGenericRecyclerBinding
import org.matrix.android.sdk.api.session.pushers.Pusher import org.matrix.android.sdk.api.session.pushers.Pusher
import javax.inject.Inject import javax.inject.Inject
@ -36,7 +37,8 @@ import javax.inject.Inject
// Referenced in vector_settings_notifications.xml // Referenced in vector_settings_notifications.xml
class PushGatewaysFragment @Inject constructor( class PushGatewaysFragment @Inject constructor(
private val epoxyController: PushGateWayController private val epoxyController: PushGateWayController
) : VectorBaseFragment<FragmentGenericRecyclerBinding>() { ) : VectorBaseFragment<FragmentGenericRecyclerBinding>(),
VectorMenuProvider {
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentGenericRecyclerBinding { override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentGenericRecyclerBinding {
return FragmentGenericRecyclerBinding.inflate(inflater, container, false) return FragmentGenericRecyclerBinding.inflate(inflater, container, false)
@ -46,14 +48,13 @@ class PushGatewaysFragment @Inject constructor(
override fun getMenuRes() = R.menu.menu_push_gateways override fun getMenuRes() = R.menu.menu_push_gateways
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) { return when (item.itemId) {
R.id.refresh -> { R.id.refresh -> {
viewModel.handle(PushGatewayAction.Refresh) viewModel.handle(PushGatewayAction.Refresh)
true true
} }
else -> else -> false
super.onOptionsItemSelected(item)
} }
} }

View File

@ -38,6 +38,7 @@ import im.vector.app.core.extensions.configureWith
import im.vector.app.core.extensions.registerStartForActivityResult import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.platform.OnBackPressed import im.vector.app.core.platform.OnBackPressed
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.resources.ColorProvider import im.vector.app.core.resources.ColorProvider
import im.vector.app.core.utils.colorizeMatchingText import im.vector.app.core.utils.colorizeMatchingText
import im.vector.app.core.utils.isValidUrl import im.vector.app.core.utils.isValidUrl
@ -67,7 +68,8 @@ class SpaceDirectoryFragment @Inject constructor(
) : VectorBaseFragment<FragmentSpaceDirectoryBinding>(), ) : VectorBaseFragment<FragmentSpaceDirectoryBinding>(),
SpaceDirectoryController.InteractionListener, SpaceDirectoryController.InteractionListener,
TimelineEventController.UrlClickCallback, TimelineEventController.UrlClickCallback,
OnBackPressed { OnBackPressed,
VectorMenuProvider {
override fun getMenuRes() = R.menu.menu_space_directory override fun getMenuRes() = R.menu.menu_space_directory
@ -177,40 +179,41 @@ class SpaceDirectoryFragment @Inject constructor(
views.addOrCreateChatRoomButton.isVisible = state.canAddRooms views.addOrCreateChatRoomButton.isVisible = state.canAddRooms
} }
override fun onPrepareOptionsMenu(menu: Menu) = withState(viewModel) { state -> override fun handlePrepareMenu(menu: Menu) {
menu.findItem(R.id.spaceAddRoom)?.isVisible = state.canAddRooms withState(viewModel) { state ->
menu.findItem(R.id.spaceCreateRoom)?.isVisible = false // Not yet implemented menu.findItem(R.id.spaceAddRoom)?.isVisible = state.canAddRooms
menu.findItem(R.id.spaceCreateRoom)?.isVisible = false // Not yet implemented
menu.findItem(R.id.spaceSearch)?.let { searchItem -> menu.findItem(R.id.spaceSearch)?.let { searchItem ->
val searchView = searchItem.actionView as SearchView val searchView = searchItem.actionView as SearchView
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean { override fun onQueryTextSubmit(query: String?): Boolean {
return true return true
} }
override fun onQueryTextChange(newText: String?): Boolean { override fun onQueryTextChange(newText: String?): Boolean {
onFilterQueryChanged(newText) onFilterQueryChanged(newText)
return true return true
} }
}) })
}
} }
super.onPrepareOptionsMenu(menu)
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun handleMenuItemSelected(item: MenuItem): Boolean {
when (item.itemId) { return when (item.itemId) {
R.id.spaceAddRoom -> { R.id.spaceAddRoom -> {
withState(viewModel) { state -> withState(viewModel) { state ->
addExistingRooms(state.spaceId) addExistingRooms(state.spaceId)
} }
return true true
} }
R.id.spaceCreateRoom -> { R.id.spaceCreateRoom -> {
// not implemented yet // not implemented yet
return true true
} }
else -> false
} }
return super.onOptionsItemSelected(item)
} }
override fun onFilterQueryChanged(query: String?) { override fun onFilterQueryChanged(query: String?) {

View File

@ -32,6 +32,7 @@ import im.vector.app.R
import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.configureWith
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.utils.ToggleableAppBarLayoutBehavior import im.vector.app.core.utils.ToggleableAppBarLayoutBehavior
import im.vector.app.databinding.FragmentSpaceLeaveAdvancedBinding import im.vector.app.databinding.FragmentSpaceLeaveAdvancedBinding
import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary
@ -40,7 +41,8 @@ import javax.inject.Inject
class SpaceLeaveAdvancedFragment @Inject constructor( class SpaceLeaveAdvancedFragment @Inject constructor(
val controller: SelectChildrenController val controller: SelectChildrenController
) : VectorBaseFragment<FragmentSpaceLeaveAdvancedBinding>(), ) : VectorBaseFragment<FragmentSpaceLeaveAdvancedBinding>(),
SelectChildrenController.Listener { SelectChildrenController.Listener,
VectorMenuProvider {
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?) = override fun getBinding(inflater: LayoutInflater, container: ViewGroup?) =
FragmentSpaceLeaveAdvancedBinding.inflate(layoutInflater, container, false) FragmentSpaceLeaveAdvancedBinding.inflate(layoutInflater, container, false)
@ -49,6 +51,8 @@ class SpaceLeaveAdvancedFragment @Inject constructor(
override fun getMenuRes() = R.menu.menu_space_leave override fun getMenuRes() = R.menu.menu_space_leave
override fun handleMenuItemSelected(item: MenuItem) = false
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
@ -89,7 +93,7 @@ class SpaceLeaveAdvancedFragment @Inject constructor(
} }
} }
override fun onPrepareOptionsMenu(menu: Menu) { override fun handlePrepareMenu(menu: Menu) {
menu.findItem(R.id.menu_space_leave_search)?.let { searchItem -> menu.findItem(R.id.menu_space_leave_search)?.let { searchItem ->
searchItem.bind( searchItem.bind(
onExpanded = { viewModel.handle(SpaceLeaveAdvanceViewAction.SetFilteringEnabled(isEnabled = true)) }, onExpanded = { viewModel.handle(SpaceLeaveAdvanceViewAction.SetFilteringEnabled(isEnabled = true)) },
@ -97,7 +101,6 @@ class SpaceLeaveAdvancedFragment @Inject constructor(
onTextChanged = { viewModel.handle(SpaceLeaveAdvanceViewAction.UpdateFilter(it)) } onTextChanged = { viewModel.handle(SpaceLeaveAdvanceViewAction.UpdateFilter(it)) }
) )
} }
super.onPrepareOptionsMenu(menu)
} }
override fun onDestroyView() { override fun onDestroyView() {

View File

@ -36,6 +36,7 @@ import im.vector.app.R
import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.cleanup
import im.vector.app.core.platform.OnBackPressed import im.vector.app.core.platform.OnBackPressed
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.databinding.FragmentSpaceAddRoomsBinding import im.vector.app.databinding.FragmentSpaceAddRoomsBinding
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.debounce
@ -51,7 +52,9 @@ class SpaceAddRoomFragment @Inject constructor(
private val roomEpoxyController: AddRoomListController, private val roomEpoxyController: AddRoomListController,
private val dmEpoxyController: AddRoomListController, private val dmEpoxyController: AddRoomListController,
) : VectorBaseFragment<FragmentSpaceAddRoomsBinding>(), ) : VectorBaseFragment<FragmentSpaceAddRoomsBinding>(),
OnBackPressed, AddRoomListController.Listener { OnBackPressed,
AddRoomListController.Listener,
VectorMenuProvider {
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?) = override fun getBinding(inflater: LayoutInflater, container: ViewGroup?) =
FragmentSpaceAddRoomsBinding.inflate(layoutInflater, container, false) FragmentSpaceAddRoomsBinding.inflate(layoutInflater, container, false)
@ -151,17 +154,18 @@ class SpaceAddRoomFragment @Inject constructor(
} }
} }
override fun onPrepareOptionsMenu(menu: Menu) { override fun handlePrepareMenu(menu: Menu) {
super.onPrepareOptionsMenu(menu)
menu.findItem(R.id.spaceAddRoomSaveItem).isVisible = saveNeeded menu.findItem(R.id.spaceAddRoomSaveItem).isVisible = saveNeeded
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun handleMenuItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.spaceAddRoomSaveItem) { return when (item.itemId) {
viewModel.handle(SpaceAddRoomActions.Save) R.id.spaceAddRoomSaveItem -> {
return true viewModel.handle(SpaceAddRoomActions.Save)
true
}
else -> false
} }
return super.onOptionsItemSelected(item)
} }
override fun onDestroyView() { override fun onDestroyView() {

View File

@ -37,6 +37,7 @@ import im.vector.app.core.extensions.configureWith
import im.vector.app.core.intent.getFilenameFromUri import im.vector.app.core.intent.getFilenameFromUri
import im.vector.app.core.platform.OnBackPressed import im.vector.app.core.platform.OnBackPressed
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.resources.ColorProvider import im.vector.app.core.resources.ColorProvider
import im.vector.app.core.time.Clock import im.vector.app.core.time.Clock
import im.vector.app.core.utils.toast import im.vector.app.core.utils.toast
@ -66,7 +67,8 @@ class SpaceSettingsFragment @Inject constructor(
) : VectorBaseFragment<FragmentRoomSettingGenericBinding>(), ) : VectorBaseFragment<FragmentRoomSettingGenericBinding>(),
SpaceSettingsController.Callback, SpaceSettingsController.Callback,
GalleryOrCameraDialogHelper.Listener, GalleryOrCameraDialogHelper.Listener,
OnBackPressed { OnBackPressed,
VectorMenuProvider {
private val viewModel: RoomSettingsViewModel by fragmentViewModel() private val viewModel: RoomSettingsViewModel by fragmentViewModel()
private val sharedViewModel: SpaceManageSharedViewModel by activityViewModel() private val sharedViewModel: SpaceManageSharedViewModel by activityViewModel()
@ -111,18 +113,20 @@ class SpaceSettingsFragment @Inject constructor(
super.onDestroyView() super.onDestroyView()
} }
override fun onPrepareOptionsMenu(menu: Menu) { override fun handlePrepareMenu(menu: Menu) {
withState(viewModel) { state -> withState(viewModel) { state ->
menu.findItem(R.id.roomSettingsSaveAction).isVisible = state.showSaveAction menu.findItem(R.id.roomSettingsSaveAction).isVisible = state.showSaveAction
} }
super.onPrepareOptionsMenu(menu)
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun handleMenuItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.roomSettingsSaveAction) { return when (item.itemId) {
viewModel.handle(RoomSettingsAction.Save) R.id.roomSettingsSaveAction -> {
viewModel.handle(RoomSettingsAction.Save)
true
}
else -> false
} }
return super.onOptionsItemSelected(item)
} }
private fun renderRoomSummary(state: RoomSettingsViewState) { private fun renderRoomSummary(state: RoomSettingsViewState) {

View File

@ -23,7 +23,6 @@ import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ScrollView import android.widget.ScrollView
import androidx.core.view.forEach
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.activityViewModel
@ -37,6 +36,7 @@ import im.vector.app.core.extensions.configureWith
import im.vector.app.core.extensions.hideKeyboard import im.vector.app.core.extensions.hideKeyboard
import im.vector.app.core.extensions.setupAsSearch import im.vector.app.core.extensions.setupAsSearch
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.utils.DimensionConverter import im.vector.app.core.utils.DimensionConverter
import im.vector.app.core.utils.showIdentityServerConsentDialog import im.vector.app.core.utils.showIdentityServerConsentDialog
import im.vector.app.core.utils.startSharePlainTextIntent import im.vector.app.core.utils.startSharePlainTextIntent
@ -55,7 +55,8 @@ class UserListFragment @Inject constructor(
private val userListController: UserListController, private val userListController: UserListController,
private val dimensionConverter: DimensionConverter, private val dimensionConverter: DimensionConverter,
) : VectorBaseFragment<FragmentUserListBinding>(), ) : VectorBaseFragment<FragmentUserListBinding>(),
UserListController.Callback { UserListController.Callback,
VectorMenuProvider {
private val args: UserListFragmentArgs by args() private val args: UserListFragmentArgs by args()
private val viewModel: UserListViewModel by activityViewModel() private val viewModel: UserListViewModel by activityViewModel()
@ -113,19 +114,24 @@ class UserListFragment @Inject constructor(
super.onDestroyView() super.onDestroyView()
} }
override fun onPrepareOptionsMenu(menu: Menu) { override fun handlePrepareMenu(menu: Menu) {
if (args.submitMenuItemId == -1) return
withState(viewModel) { withState(viewModel) {
val showMenuItem = it.pendingSelections.isNotEmpty() val showMenuItem = it.pendingSelections.isNotEmpty()
menu.forEach { menuItem -> menu.findItem(args.submitMenuItemId).isVisible = showMenuItem
menuItem.isVisible = showMenuItem
}
} }
super.onPrepareOptionsMenu(menu)
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean = withState(viewModel) { override fun handleMenuItemSelected(item: MenuItem): Boolean {
sharedActionViewModel.post(UserListSharedAction.OnMenuItemSelected(item.itemId, it.pendingSelections)) return when (item.itemId) {
return@withState true args.submitMenuItemId -> {
withState(viewModel) {
sharedActionViewModel.post(UserListSharedAction.OnMenuItemSubmitClick(it.pendingSelections))
}
true
}
else -> false
}
} }
private fun setupRecyclerView() { private fun setupRecyclerView() {

View File

@ -23,6 +23,7 @@ import kotlinx.parcelize.Parcelize
data class UserListFragmentArgs( data class UserListFragmentArgs(
val title: String, val title: String,
val menuResId: Int, val menuResId: Int,
val submitMenuItemId: Int,
val excludedUserIds: Set<String>? = null, val excludedUserIds: Set<String>? = null,
val singleSelection: Boolean = false, val singleSelection: Boolean = false,
val showInviteActions: Boolean = true, val showInviteActions: Boolean = true,

View File

@ -21,7 +21,7 @@ import im.vector.app.core.platform.VectorSharedAction
sealed class UserListSharedAction : VectorSharedAction { sealed class UserListSharedAction : VectorSharedAction {
object Close : UserListSharedAction() object Close : UserListSharedAction()
object GoBack : UserListSharedAction() object GoBack : UserListSharedAction()
data class OnMenuItemSelected(val itemId: Int, val selections: Set<PendingSelection>) : UserListSharedAction() data class OnMenuItemSubmitClick(val selections: Set<PendingSelection>) : UserListSharedAction()
object OpenPhoneBook : UserListSharedAction() object OpenPhoneBook : UserListSharedAction()
object AddByQrCode : UserListSharedAction() object AddByQrCode : UserListSharedAction()
} }

View File

@ -64,8 +64,6 @@ class WidgetActivity : VectorBaseActivity<ActivityWidgetBinding>() {
override fun getBinding() = ActivityWidgetBinding.inflate(layoutInflater) override fun getBinding() = ActivityWidgetBinding.inflate(layoutInflater)
override fun getMenuRes() = R.menu.menu_widget
override fun getTitleRes() = R.string.room_widget_activity_title override fun getTitleRes() = R.string.room_widget_activity_title
override fun initUiAndData() { override fun initUiAndData() {

View File

@ -42,6 +42,7 @@ import im.vector.app.R
import im.vector.app.core.extensions.registerStartForActivityResult import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.platform.OnBackPressed import im.vector.app.core.platform.OnBackPressed
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.utils.openUrlInExternalBrowser import im.vector.app.core.utils.openUrlInExternalBrowser
import im.vector.app.databinding.FragmentRoomWidgetBinding import im.vector.app.databinding.FragmentRoomWidgetBinding
import im.vector.app.features.webview.WebEventListener import im.vector.app.features.webview.WebEventListener
@ -68,7 +69,8 @@ class WidgetFragment @Inject constructor(
) : ) :
VectorBaseFragment<FragmentRoomWidgetBinding>(), VectorBaseFragment<FragmentRoomWidgetBinding>(),
WebEventListener, WebEventListener,
OnBackPressed { OnBackPressed,
VectorMenuProvider {
private val fragmentArgs: WidgetArgs by args() private val fragmentArgs: WidgetArgs by args()
private val viewModel: WidgetViewModel by activityViewModel() private val viewModel: WidgetViewModel by activityViewModel()
@ -79,7 +81,6 @@ class WidgetFragment @Inject constructor(
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setHasOptionsMenu(true)
views.widgetWebView.setupForWidget(this) views.widgetWebView.setupForWidget(this)
if (fragmentArgs.kind.isAdmin()) { if (fragmentArgs.kind.isAdmin()) {
viewModel.getPostAPIMediator().setWebView(views.widgetWebView) viewModel.getPostAPIMediator().setWebView(views.widgetWebView)
@ -136,53 +137,64 @@ class WidgetFragment @Inject constructor(
} }
} }
override fun onPrepareOptionsMenu(menu: Menu) = withState(viewModel) { state -> override fun getMenuRes() = R.menu.menu_widget
val widget = state.asyncWidget()
menu.findItem(R.id.action_edit)?.isVisible = state.widgetKind != WidgetKind.INTEGRATION_MANAGER override fun handlePrepareMenu(menu: Menu) {
if (widget == null) { withState(viewModel) { state ->
menu.findItem(R.id.action_refresh)?.isVisible = false val widget = state.asyncWidget()
menu.findItem(R.id.action_widget_open_ext)?.isVisible = false menu.findItem(R.id.action_edit)?.isVisible = state.widgetKind != WidgetKind.INTEGRATION_MANAGER
menu.findItem(R.id.action_delete)?.isVisible = false if (widget == null) {
menu.findItem(R.id.action_revoke)?.isVisible = false menu.findItem(R.id.action_refresh)?.isVisible = false
} else { menu.findItem(R.id.action_widget_open_ext)?.isVisible = false
menu.findItem(R.id.action_refresh)?.isVisible = true menu.findItem(R.id.action_delete)?.isVisible = false
menu.findItem(R.id.action_widget_open_ext)?.isVisible = true menu.findItem(R.id.action_revoke)?.isVisible = false
menu.findItem(R.id.action_delete)?.isVisible = state.canManageWidgets && widget.isAddedByMe } else {
menu.findItem(R.id.action_revoke)?.isVisible = state.status == WidgetStatus.WIDGET_ALLOWED && !widget.isAddedByMe menu.findItem(R.id.action_refresh)?.isVisible = true
menu.findItem(R.id.action_widget_open_ext)?.isVisible = true
menu.findItem(R.id.action_delete)?.isVisible = state.canManageWidgets && widget.isAddedByMe
menu.findItem(R.id.action_revoke)?.isVisible = state.status == WidgetStatus.WIDGET_ALLOWED && !widget.isAddedByMe
}
} }
super.onPrepareOptionsMenu(menu)
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean = withState(viewModel) { state -> override fun handleMenuItemSelected(item: MenuItem): Boolean {
when (item.itemId) { return withState(viewModel) { state ->
R.id.action_edit -> { return@withState when (item.itemId) {
navigator.openIntegrationManager( R.id.action_edit -> {
requireContext(), navigator.openIntegrationManager(
integrationManagerActivityResultLauncher, requireContext(),
state.roomId, integrationManagerActivityResultLauncher,
state.widgetId, state.roomId,
state.widgetKind.screenId state.widgetId,
) state.widgetKind.screenId
return@withState true )
} true
R.id.action_delete -> { }
deleteWidget() R.id.action_delete -> {
return@withState true deleteWidget()
} true
R.id.action_refresh -> if (state.formattedURL.complete) { }
views.widgetWebView.reload() R.id.action_refresh -> {
return@withState true if (state.formattedURL.complete) {
} views.widgetWebView.reload()
R.id.action_widget_open_ext -> if (state.formattedURL.complete) { }
openUrlInExternalBrowser(requireContext(), state.formattedURL.invoke()) true
return@withState true }
} R.id.action_widget_open_ext -> {
R.id.action_revoke -> if (state.status == WidgetStatus.WIDGET_ALLOWED) { if (state.formattedURL.complete) {
revokeWidget() openUrlInExternalBrowser(requireContext(), state.formattedURL.invoke())
return@withState true }
true
}
R.id.action_revoke -> {
if (state.status == WidgetStatus.WIDGET_ALLOWED) {
revokeWidget()
}
true
}
else -> false
} }
} }
return@withState super.onOptionsItemSelected(item)
} }
override fun onBackPressed(toolbarButton: Boolean): Boolean = withState(viewModel) { state -> override fun onBackPressed(toolbarButton: Boolean): Boolean = withState(viewModel) { state ->