Migration to activity 1.5.0. Rework menu management

This commit is contained in:
Benoit Marty 2022-07-01 17:05:32 +02:00 committed by Benoit Marty
parent 1297ccd45c
commit aae6e20f9c
29 changed files with 320 additions and 270 deletions

View file

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

View file

@ -18,8 +18,12 @@ package im.vector.lib.ui.styles.debug
import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.widget.Toast
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.snackbar.Snackbar
import im.vector.lib.ui.styles.R
@ -31,6 +35,7 @@ abstract class DebugMaterialThemeActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setupMenu()
val views = ActivityDebugMaterialThemeBinding.inflate(layoutInflater)
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) {
MaterialAlertDialogBuilder(this, theme)
.setTitle("Dialog title")
@ -82,9 +108,4 @@ abstract class DebugMaterialThemeActivity : AppCompatActivity() {
.setNeutralButton("Neutral", null)
.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
\* @\w+ \w+ +
### Please use the MenuProvider interface now
onCreateOptionsMenu
onOptionsItemSelected
onPrepareOptionsMenu

View file

@ -24,6 +24,7 @@ import android.os.Build
import android.os.Bundle
import android.os.Parcelable
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.WindowInsetsController
@ -36,10 +37,12 @@ import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.content.ContextCompat
import androidx.core.view.MenuProvider
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentFactory
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.viewbinding.ViewBinding
@ -199,6 +202,7 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), Maver
supportFragmentManager.fragmentFactory = fragmentFactory
viewModelFactory = activityEntryPoint.viewModelFactory()
super.onCreate(savedInstanceState)
setupMenu()
configurationViewModel = viewModelProvider.get(ConfigurationViewModel::class.java)
bugReporter = singletonEntryPoint.bugReporter()
pinLocker = singletonEntryPoint.pinLocker()
@ -249,6 +253,30 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), Maver
}
}
private fun setupMenu() {
// Always add a MenuProvider to handle the back action from the Toolbar
addMenuProvider(
object : MenuProvider {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
getMenuRes()
.takeIf { it != -1 }
?.let { menuInflater.inflate(it, menu) }
handlePostCreateMenu(menu)
}
override fun onPrepareMenu(menu: Menu) {
handlePrepareMenu(menu)
}
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
return handleMenuItemSelected(menuItem)
}
},
this,
Lifecycle.State.RESUMED
)
}
/**
* This method has to be called for the font size setting be supported correctly.
*/
@ -467,24 +495,24 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), Maver
* MENU MANAGEMENT
* ========================================================================================== */
override fun onCreateOptionsMenu(menu: Menu): Boolean {
val menuRes = getMenuRes()
@MenuRes
open fun getMenuRes() = -1
if (menuRes != -1) {
menuInflater.inflate(menuRes, menu)
return true
// No op by default
open fun handlePostCreateMenu(menu: Menu) = Unit
// No op by default
open fun handlePrepareMenu(menu: Menu) = Unit
@CallSuper
open fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
android.R.id.home -> {
onBackPressed(true)
true
}
else -> false
}
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() {
@ -587,9 +615,6 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), Maver
@StringRes
open fun getTitleRes() = -1
@MenuRes
open fun getMenuRes() = -1
/**
* 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.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.annotation.CallSuper
import androidx.annotation.MainThread
import androidx.appcompat.app.AlertDialog
import androidx.core.view.MenuHost
import androidx.core.view.MenuProvider
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.viewbinding.ViewBinding
@ -126,9 +130,7 @@ abstract class VectorBaseFragment<VB : ViewBinding> : Fragment(), MavericksView
@CallSuper
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (getMenuRes() != -1) {
setHasOptionsMenu(true)
}
Timber.i("onCreate Fragment ${javaClass.simpleName}")
}
final override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@ -158,6 +160,30 @@ abstract class VectorBaseFragment<VB : ViewBinding> : Fragment(), MavericksView
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Timber.i("onViewCreated Fragment ${javaClass.simpleName}")
setupMenu()
}
private fun setupMenu() {
val menuRes = getMenuRes().takeIf { it != -1 } ?: return
val menuHost: MenuHost = requireActivity()
menuHost.addMenuProvider(
object : MenuProvider {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(menuRes, 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?) {
@ -272,12 +298,14 @@ abstract class VectorBaseFragment<VB : ViewBinding> : Fragment(), MavericksView
open fun getMenuRes() = -1
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
val menuRes = getMenuRes()
// No op by default
open fun handlePostCreateMenu(menu: Menu) = Unit
if (menuRes != -1) {
inflater.inflate(menuRes, menu)
}
// No op by default
open fun handlePrepareMenu(menu: Menu) = Unit
open fun handleMenuItemSelected(item: MenuItem): Boolean {
throw NotImplementedError("You must override this method to handle click on menu item")
}
// This should be provided by the framework

View file

@ -97,7 +97,7 @@ class AttachmentsPreviewFragment @Inject constructor(
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.attachmentsPreviewRemoveAction -> {
handleRemoveAction()
@ -107,20 +107,16 @@ class AttachmentsPreviewFragment @Inject constructor(
handleEditAction()
true
}
else -> {
super.onOptionsItemSelected(item)
}
else -> false
}
}
override fun onPrepareOptionsMenu(menu: Menu) {
override fun handlePrepareMenu(menu: Menu) {
withState(viewModel) { state ->
val editMenuItem = menu.findItem(R.id.attachmentsPreviewEditAction)
val showEditMenuItem = state.attachments.getOrNull(state.currentAttachmentIndex)?.isEditable().orFalse()
editMenuItem.setVisible(showEditMenuItem)
}
super.onPrepareOptionsMenu(menu)
}
override fun getMenuRes() = R.menu.vector_attachments_preview

View file

@ -214,16 +214,19 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
renderState(it)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.menu_call_open_chat) {
returnToChat()
return true
} else if (item.itemId == android.R.id.home) {
// We check here as we want PiP in some cases
onBackPressed()
return true
override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.menu_call_open_chat -> {
returnToChat()
true
}
android.R.id.home -> {
// We check here as we want PiP in some cases
onBackPressed()
true
}
else -> super.handleMenuItemSelected(item)
}
return super.onOptionsItemSelected(item)
}
override fun onDestroy() {

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 {
const val KEYS_VERSION = "KEYS_VERSION"
const val MANUAL_EXPORT = "MANUAL_EXPORT"

View file

@ -133,16 +133,18 @@ class RoomDevToolActivity : SimpleFragmentActivity(), FragmentManager.OnBackStac
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.menuItemEdit) {
viewModel.handle(RoomDevToolAction.MenuEdit)
return true
override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.menuItemEdit -> {
viewModel.handle(RoomDevToolAction.MenuEdit)
true
}
R.id.menuItemSend -> {
viewModel.handle(RoomDevToolAction.MenuItemSend)
true
}
else -> super.handleMenuItemSelected(item)
}
if (item.itemId == R.id.menuItemSend) {
viewModel.handle(RoomDevToolAction.MenuItemSend)
return true
}
return super.onOptionsItemSelected(item)
}
override fun onBackPressed() {
@ -174,21 +176,22 @@ class RoomDevToolActivity : SimpleFragmentActivity(), FragmentManager.OnBackStac
super.onDestroy()
}
override fun onPrepareOptionsMenu(menu: Menu): Boolean = withState(viewModel) { state ->
menu.forEach {
val isVisible = when (it.itemId) {
R.id.menuItemEdit -> {
state.displayMode is RoomDevToolViewState.Mode.StateEventDetail
override fun handlePrepareMenu(menu: Menu) {
withState(viewModel) { state ->
menu.forEach {
val isVisible = when (it.itemId) {
R.id.menuItemEdit -> {
state.displayMode is RoomDevToolViewState.Mode.StateEventDetail
}
R.id.menuItemSend -> {
state.displayMode is RoomDevToolViewState.Mode.EditEventContent ||
state.displayMode is RoomDevToolViewState.Mode.SendEventForm
}
else -> true
}
R.id.menuItemSend -> {
state.displayMode is RoomDevToolViewState.Mode.EditEventContent ||
state.displayMode is RoomDevToolViewState.Mode.SendEventForm
}
else -> true
it.isVisible = isVisible
}
it.isVisible = isVisible
}
return@withState true
}
companion object {

View file

@ -547,47 +547,45 @@ class HomeActivity :
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_optimized).isVisible = vectorPreferences.developerMode()
return super.onPrepareOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.menu_home_suggestion -> {
bugReporter.openBugReportScreen(this, ReportType.SUGGESTION)
return true
true
}
R.id.menu_home_report_bug -> {
bugReporter.openBugReportScreen(this, ReportType.BUG_REPORT)
return true
true
}
R.id.menu_home_init_sync_legacy -> {
// Configure the SDK
initialSyncStrategy = InitialSyncStrategy.Legacy
// And clear cache
MainActivity.restartApp(this, MainActivityArgs(clearCache = true))
return true
true
}
R.id.menu_home_init_sync_optimized -> {
// Configure the SDK
initialSyncStrategy = InitialSyncStrategy.Optimized()
// And clear cache
MainActivity.restartApp(this, MainActivityArgs(clearCache = true))
return true
true
}
R.id.menu_home_filter -> {
navigator.openRoomsFiltering(this)
return true
true
}
R.id.menu_home_setting -> {
navigator.openSettings(this)
return true
true
}
else -> super.handleMenuItemSelected(item)
}
return super.onOptionsItemSelected(item)
}
override fun onBackPressed() {

View file

@ -91,23 +91,21 @@ class HomeDetailFragment @Inject constructor(
override fun getMenuRes() = R.menu.room_list
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.menu_home_mark_all_as_read -> {
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 ->
val isRoomList = state.currentTab is HomeTab.RoomList
menu.findItem(R.id.menu_home_mark_all_as_read).isVisible = isRoomList && hasUnreadRooms
}
super.onPrepareOptionsMenu(menu)
}
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.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
@ -1055,15 +1054,14 @@ class TimelineFragment @Inject constructor(
}
@SuppressLint("RestrictedApi")
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
override fun handlePostCreateMenu(menu: Menu) {
if (isThreadTimeLine()) {
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
menu.findItem(R.id.open_matrix_apps)?.let { menuItem ->
menuItem.actionView.debouncedClicks {
onOptionsItemSelected(menuItem)
handleMenuItemSelected(menuItem)
}
}
val joinConfItem = menu.findItem(R.id.join_conference)
@ -1073,13 +1071,13 @@ class TimelineFragment @Inject constructor(
// Custom thread notification menu item
menu.findItem(R.id.menu_timeline_thread_list)?.let { menuItem ->
menuItem.actionView.setOnClickListener {
onOptionsItemSelected(menuItem)
menuItem.actionView.debouncedClicks {
handleMenuItemSelected(menuItem)
}
}
}
override fun onPrepareOptionsMenu(menu: Menu) {
override fun handlePrepareMenu(menu: Menu) {
menu.forEach {
it.isVisible = timelineViewModel.isMenuItemVisible(it.itemId)
}
@ -1121,7 +1119,7 @@ class TimelineFragment @Inject constructor(
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.invite -> {
navigator.openInviteUsersToRoom(requireActivity(), timelineArgs.roomId)
@ -1174,7 +1172,7 @@ class TimelineFragment @Inject constructor(
}
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.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
@ -71,27 +70,26 @@ class ThreadListFragment @Inject constructor(
analyticsScreenName = MobileScreen.ScreenName.ThreadList
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
override fun handlePostCreateMenu(menu: Menu) {
// 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 ->
menuItem.actionView.setOnClickListener {
onOptionsItemSelected(menuItem)
menuItem.actionView.debouncedClicks {
handleMenuItemSelected(menuItem)
}
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.menu_thread_list_filter -> {
ThreadListBottomSheet().show(childFragmentManager, "Filtering")
true
}
else -> super.onOptionsItemSelected(item)
else -> false
}
}
override fun onPrepareOptionsMenu(menu: Menu) {
override fun handlePrepareMenu(menu: Menu) {
withState(threadListViewModel) { state ->
val filterIcon = menu.findItem(R.id.menu_thread_list_filter).actionView
val filterBadge = filterIcon.findViewById<View>(R.id.threadListFilterBadge)

View file

@ -99,14 +99,14 @@ class LocationPreviewFragment @Inject constructor(
override fun getMenuRes() = R.menu.menu_location_preview
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.share_external -> {
onShareLocationExternal()
return true
true
}
else -> false
}
return super.onOptionsItemSelected(item)
}
private fun onShareLocationExternal() {

View file

@ -120,29 +120,27 @@ class BugReportActivity : VectorBaseActivity<ActivityBugReportBinding>() {
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 {
val isValid = !views.bugReportMaskView.isVisible
it.isEnabled = isValid
it.icon.alpha = if (isValid) 255 else 100
}
return super.onPrepareOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.ic_action_send_bug_report -> {
if (views.bugReportEditText.text.toString().trim().length >= 10) {
sendBugReport()
} else {
views.bugReportTextInputLayout.error = getString(R.string.bug_report_error_too_short)
}
return true
true
}
else -> super.handleMenuItemSelected(item)
}
return super.onOptionsItemSelected(item)
}
/**

View file

@ -138,10 +138,7 @@ class EmojiReactionPickerActivity : VectorBaseActivity<ActivityEmojiReactionPick
super.onDestroy()
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
val inflater: MenuInflater = menuInflater
inflater.inflate(getMenuRes(), menu)
override fun handlePostCreateMenu(menu: Menu) {
val searchItem = menu.findItem(R.id.search)
(searchItem.actionView as? SearchView)?.let { searchView ->
searchItem.setOnActionExpandListener(object : MenuItem.OnActionExpandListener {
@ -175,7 +172,6 @@ class EmojiReactionPickerActivity : VectorBaseActivity<ActivityEmojiReactionPick
.launchIn(lifecycleScope)
}
searchItem.expandActionView()
return true
}
// TODO move to ThemeUtils when core module is created

View file

@ -105,14 +105,13 @@ class PublicRoomsFragment @Inject constructor(
super.onDestroyView()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.menu_room_directory_change_protocol -> {
sharedActionViewModel.post(RoomDirectorySharedAction.ChangeProtocol)
true
}
else ->
super.onOptionsItemSelected(item)
else -> false
}
}

View file

@ -160,14 +160,14 @@ class RoomMemberProfileFragment @Inject constructor(
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.roomMemberProfileShareAction -> {
viewModel.handle(RoomMemberProfileAction.ShareRoomMemberProfile)
return true
true
}
else -> false
}
return super.onOptionsItemSelected(item)
}
private fun handleStartVerification(startVerification: RoomMemberProfileViewEvents.StartVerification) {

View file

@ -170,14 +170,14 @@ class RoomProfileFragment @Inject constructor(
headerViews.roomProfileAliasView.copyOnLongClick()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.roomProfileShareAction -> {
roomProfileViewModel.handle(RoomProfileAction.ShareRoomProfile)
return true
true
}
else -> false
}
return super.onOptionsItemSelected(item)
}
private fun handleQuickActions(action: RoomListQuickActionsSharedAction) = when (action) {

View file

@ -139,18 +139,20 @@ class RoomSettingsFragment @Inject constructor(
super.onDestroyView()
}
override fun onPrepareOptionsMenu(menu: Menu) {
override fun handlePrepareMenu(menu: Menu) {
withState(viewModel) { state ->
menu.findItem(R.id.roomSettingsSaveAction).isVisible = state.showSaveAction
}
super.onPrepareOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.roomSettingsSaveAction) {
viewModel.handle(RoomSettingsAction.Save)
override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.roomSettingsSaveAction -> {
viewModel.handle(RoomSettingsAction.Save)
true
}
else -> false
}
return super.onOptionsItemSelected(item)
}
override fun invalidate() = withState(viewModel) { viewState ->

View file

@ -26,8 +26,6 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
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.fragmentViewModel
import com.airbnb.mvrx.withState
@ -61,19 +59,6 @@ class KeyRequestsFragment @Inject constructor(
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) {
when (it.exporting) {
is Loading -> views.exportWaitingView.isVisible = true
@ -81,16 +66,10 @@ class KeyRequestsFragment @Inject constructor(
}
}
override fun onDestroy() {
invalidateOptionsMenu()
super.onDestroy()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mPagerAdapter = KeyReqPagerAdapter(this)
views.devToolKeyRequestPager.adapter = mPagerAdapter
views.devToolKeyRequestPager.registerOnPageChangeCallback(pageAdapterListener)
TabLayoutMediator(views.devToolKeyRequestTabs, views.devToolKeyRequestPager) { tab, position ->
when (position) {
@ -119,25 +98,26 @@ class KeyRequestsFragment @Inject constructor(
}
override fun onDestroyView() {
views.devToolKeyRequestPager.unregisterOnPageChangeCallback(pageAdapterListener)
mPagerAdapter = null
super.onDestroyView()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.audit_export) {
selectTxtFileToWrite(
activity = requireActivity(),
activityResultLauncher = epxortAuditForActivityResult,
defaultFileName = "audit-export_${clock.epochMillis()}.txt",
chooserHint = "Export Audit"
)
return true
override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.audit_export -> {
selectTxtFileToWrite(
activity = requireActivity(),
activityResultLauncher = exportAuditForActivityResult,
defaultFileName = "audit-export_${clock.epochMillis()}.txt",
chooserHint = "Export Audit"
)
true
}
else -> false
}
return super.onOptionsItemSelected(item)
}
private val epxortAuditForActivityResult = registerStartForActivityResult { activityResult ->
private val exportAuditForActivityResult = registerStartForActivityResult { activityResult ->
if (activityResult.resultCode == Activity.RESULT_OK) {
val uri = activityResult.data?.data
if (uri != null) {

View file

@ -46,14 +46,13 @@ class PushGatewaysFragment @Inject constructor(
override fun getMenuRes() = R.menu.menu_push_gateways
override fun onOptionsItemSelected(item: MenuItem): Boolean {
override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.refresh -> {
viewModel.handle(PushGatewayAction.Refresh)
true
}
else ->
super.onOptionsItemSelected(item)
else -> false
}
}

View file

@ -177,40 +177,41 @@ class SpaceDirectoryFragment @Inject constructor(
views.addOrCreateChatRoomButton.isVisible = state.canAddRooms
}
override fun onPrepareOptionsMenu(menu: Menu) = withState(viewModel) { state ->
menu.findItem(R.id.spaceAddRoom)?.isVisible = state.canAddRooms
menu.findItem(R.id.spaceCreateRoom)?.isVisible = false // Not yet implemented
override fun handlePrepareMenu(menu: Menu) {
withState(viewModel) { state ->
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 ->
val searchView = searchItem.actionView as SearchView
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
return true
}
menu.findItem(R.id.spaceSearch)?.let { searchItem ->
val searchView = searchItem.actionView as SearchView
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
return true
}
override fun onQueryTextChange(newText: String?): Boolean {
onFilterQueryChanged(newText)
return true
}
})
override fun onQueryTextChange(newText: String?): Boolean {
onFilterQueryChanged(newText)
return true
}
})
}
}
super.onPrepareOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.spaceAddRoom -> {
withState(viewModel) { state ->
addExistingRooms(state.spaceId)
}
return true
true
}
R.id.spaceCreateRoom -> {
// not implemented yet
return true
true
}
else -> false
}
return super.onOptionsItemSelected(item)
}
override fun onFilterQueryChanged(query: String?) {

View file

@ -89,7 +89,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 ->
searchItem.bind(
onExpanded = { viewModel.handle(SpaceLeaveAdvanceViewAction.SetFilteringEnabled(isEnabled = true)) },
@ -97,7 +97,6 @@ class SpaceLeaveAdvancedFragment @Inject constructor(
onTextChanged = { viewModel.handle(SpaceLeaveAdvanceViewAction.UpdateFilter(it)) }
)
}
super.onPrepareOptionsMenu(menu)
}
override fun onDestroyView() {

View file

@ -151,17 +151,18 @@ class SpaceAddRoomFragment @Inject constructor(
}
}
override fun onPrepareOptionsMenu(menu: Menu) {
super.onPrepareOptionsMenu(menu)
override fun handlePrepareMenu(menu: Menu) {
menu.findItem(R.id.spaceAddRoomSaveItem).isVisible = saveNeeded
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.spaceAddRoomSaveItem) {
viewModel.handle(SpaceAddRoomActions.Save)
return true
override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.spaceAddRoomSaveItem -> {
viewModel.handle(SpaceAddRoomActions.Save)
true
}
else -> false
}
return super.onOptionsItemSelected(item)
}
override fun onDestroyView() {

View file

@ -111,18 +111,20 @@ class SpaceSettingsFragment @Inject constructor(
super.onDestroyView()
}
override fun onPrepareOptionsMenu(menu: Menu) {
override fun handlePrepareMenu(menu: Menu) {
withState(viewModel) { state ->
menu.findItem(R.id.roomSettingsSaveAction).isVisible = state.showSaveAction
}
super.onPrepareOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.roomSettingsSaveAction) {
viewModel.handle(RoomSettingsAction.Save)
override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.roomSettingsSaveAction -> {
viewModel.handle(RoomSettingsAction.Save)
true
}
else -> false
}
return super.onOptionsItemSelected(item)
}
private fun renderRoomSummary(state: RoomSettingsViewState) {

View file

@ -113,19 +113,20 @@ class UserListFragment @Inject constructor(
super.onDestroyView()
}
override fun onPrepareOptionsMenu(menu: Menu) {
override fun handlePrepareMenu(menu: Menu) {
withState(viewModel) {
val showMenuItem = it.pendingSelections.isNotEmpty()
menu.forEach { menuItem ->
menuItem.isVisible = showMenuItem
}
}
super.onPrepareOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean = withState(viewModel) {
sharedActionViewModel.post(UserListSharedAction.OnMenuItemSelected(item.itemId, it.pendingSelections))
return@withState true
override fun handleMenuItemSelected(item: MenuItem): Boolean {
withState(viewModel) {
sharedActionViewModel.post(UserListSharedAction.OnMenuItemSelected(item.itemId, it.pendingSelections))
}
return true
}
private fun setupRecyclerView() {

View file

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

View file

@ -79,7 +79,6 @@ class WidgetFragment @Inject constructor(
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setHasOptionsMenu(true)
views.widgetWebView.setupForWidget(this)
if (fragmentArgs.kind.isAdmin()) {
viewModel.getPostAPIMediator().setWebView(views.widgetWebView)
@ -136,53 +135,64 @@ class WidgetFragment @Inject constructor(
}
}
override fun onPrepareOptionsMenu(menu: Menu) = withState(viewModel) { state ->
val widget = state.asyncWidget()
menu.findItem(R.id.action_edit)?.isVisible = state.widgetKind != WidgetKind.INTEGRATION_MANAGER
if (widget == null) {
menu.findItem(R.id.action_refresh)?.isVisible = false
menu.findItem(R.id.action_widget_open_ext)?.isVisible = false
menu.findItem(R.id.action_delete)?.isVisible = false
menu.findItem(R.id.action_revoke)?.isVisible = false
} else {
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
override fun getMenuRes() = R.menu.menu_widget
override fun handlePrepareMenu(menu: Menu) {
withState(viewModel) { state ->
val widget = state.asyncWidget()
menu.findItem(R.id.action_edit)?.isVisible = state.widgetKind != WidgetKind.INTEGRATION_MANAGER
if (widget == null) {
menu.findItem(R.id.action_refresh)?.isVisible = false
menu.findItem(R.id.action_widget_open_ext)?.isVisible = false
menu.findItem(R.id.action_delete)?.isVisible = false
menu.findItem(R.id.action_revoke)?.isVisible = false
} else {
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 ->
when (item.itemId) {
R.id.action_edit -> {
navigator.openIntegrationManager(
requireContext(),
integrationManagerActivityResultLauncher,
state.roomId,
state.widgetId,
state.widgetKind.screenId
)
return@withState true
}
R.id.action_delete -> {
deleteWidget()
return@withState true
}
R.id.action_refresh -> if (state.formattedURL.complete) {
views.widgetWebView.reload()
return@withState true
}
R.id.action_widget_open_ext -> if (state.formattedURL.complete) {
openUrlInExternalBrowser(requireContext(), state.formattedURL.invoke())
return@withState true
}
R.id.action_revoke -> if (state.status == WidgetStatus.WIDGET_ALLOWED) {
revokeWidget()
return@withState true
override fun handleMenuItemSelected(item: MenuItem): Boolean {
return withState(viewModel) { state ->
return@withState when (item.itemId) {
R.id.action_edit -> {
navigator.openIntegrationManager(
requireContext(),
integrationManagerActivityResultLauncher,
state.roomId,
state.widgetId,
state.widgetKind.screenId
)
true
}
R.id.action_delete -> {
deleteWidget()
true
}
R.id.action_refresh -> {
if (state.formattedURL.complete) {
views.widgetWebView.reload()
}
true
}
R.id.action_widget_open_ext -> {
if (state.formattedURL.complete) {
openUrlInExternalBrowser(requireContext(), state.formattedURL.invoke())
}
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 ->