Toggling of selectMode using menu i OtherSessionsFragment

This commit is contained in:
Maxime NATUREL 2022-10-18 16:24:04 +02:00
parent b532112f58
commit 2e155b1acc
6 changed files with 106 additions and 1 deletions

View file

@ -3328,6 +3328,13 @@
<string name="device_manager_other_sessions_no_unverified_sessions_found">No unverified sessions found.</string> <string name="device_manager_other_sessions_no_unverified_sessions_found">No unverified sessions found.</string>
<string name="device_manager_other_sessions_no_inactive_sessions_found">No inactive sessions found.</string> <string name="device_manager_other_sessions_no_inactive_sessions_found">No inactive sessions found.</string>
<string name="device_manager_other_sessions_clear_filter">Clear Filter</string> <string name="device_manager_other_sessions_clear_filter">Clear Filter</string>
<string name="device_manager_other_sessions_select">Select sessions</string>
<string name="device_manager_other_sessions_select_all">Select all</string>
<string name="device_manager_other_sessions_deselect_all">Deselect all</string>
<plurals name="device_manager_other_sessions_selected">
<item quantity="one">%1$d selected</item>
<item quantity="other">%1$d selected</item>
</plurals>
<string name="device_manager_session_overview_signout">Sign out of this session</string> <string name="device_manager_session_overview_signout">Sign out of this session</string>
<string name="device_manager_session_details_title">Session details</string> <string name="device_manager_session_details_title">Session details</string>
<string name="device_manager_session_details_description">Application, device, and activity information.</string> <string name="device_manager_session_details_description">Application, device, and activity information.</string>

View file

@ -21,4 +21,6 @@ import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterType
sealed class OtherSessionsAction : VectorViewModelAction { sealed class OtherSessionsAction : VectorViewModelAction {
data class FilterDevices(val filterType: DeviceManagerFilterType) : OtherSessionsAction() data class FilterDevices(val filterType: DeviceManagerFilterType) : OtherSessionsAction()
object EnableSelectMode : OtherSessionsAction()
object DisableSelectMode : OtherSessionsAction()
} }

View file

@ -18,8 +18,12 @@ package im.vector.app.features.settings.devices.v2.othersessions
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.activity.OnBackPressedCallback
import androidx.activity.addCallback
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.core.view.isVisible import androidx.core.view.isVisible
import com.airbnb.mvrx.Success import com.airbnb.mvrx.Success
@ -31,7 +35,9 @@ import im.vector.app.R
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment.ResultListener.Companion.RESULT_OK import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment.ResultListener.Companion.RESULT_OK
import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.platform.VectorMenuProvider
import im.vector.app.core.resources.ColorProvider import im.vector.app.core.resources.ColorProvider
import im.vector.app.core.resources.StringProvider
import im.vector.app.databinding.FragmentOtherSessionsBinding import im.vector.app.databinding.FragmentOtherSessionsBinding
import im.vector.app.features.settings.devices.v2.DeviceFullInfo import im.vector.app.features.settings.devices.v2.DeviceFullInfo
import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterBottomSheet import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterBottomSheet
@ -46,19 +52,65 @@ import javax.inject.Inject
class OtherSessionsFragment : class OtherSessionsFragment :
VectorBaseFragment<FragmentOtherSessionsBinding>(), VectorBaseFragment<FragmentOtherSessionsBinding>(),
VectorBaseBottomSheetDialogFragment.ResultListener, VectorBaseBottomSheetDialogFragment.ResultListener,
OtherSessionsView.Callback { OtherSessionsView.Callback,
VectorMenuProvider {
private val viewModel: OtherSessionsViewModel by fragmentViewModel() private val viewModel: OtherSessionsViewModel by fragmentViewModel()
private val args: OtherSessionsArgs by args() private val args: OtherSessionsArgs by args()
@Inject lateinit var colorProvider: ColorProvider @Inject lateinit var colorProvider: ColorProvider
@Inject lateinit var stringProvider: StringProvider
@Inject lateinit var viewNavigator: OtherSessionsViewNavigator @Inject lateinit var viewNavigator: OtherSessionsViewNavigator
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentOtherSessionsBinding { override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentOtherSessionsBinding {
return FragmentOtherSessionsBinding.inflate(layoutInflater, container, false) return FragmentOtherSessionsBinding.inflate(layoutInflater, container, false)
} }
override fun getMenuRes() = R.menu.menu_other_sessions
override fun handlePrepareMenu(menu: Menu) {
withState(viewModel) { state ->
val isSelectModeEnabled = state.isSelectModeEnabled
menu.findItem(R.id.otherSessionsSelectAll).isVisible = isSelectModeEnabled
menu.findItem(R.id.otherSessionsDeselectAll).isVisible = isSelectModeEnabled
menu.findItem(R.id.otherSessionsSelect).isVisible = !isSelectModeEnabled
}
}
override fun handleMenuItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.otherSessionsSelect -> {
enableSelectMode(true)
true
}
else -> false
}
}
// TODO call enableSelectMode(true) on long press of an item when disabled
private fun enableSelectMode(isEnabled: Boolean) {
val action = if (isEnabled) OtherSessionsAction.EnableSelectMode else OtherSessionsAction.DisableSelectMode
viewModel.handle(action)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activity?.onBackPressedDispatcher?.addCallback(owner = this) {
handleBackPress(this)
}
}
private fun handleBackPress(onBackPressedCallback: OnBackPressedCallback) = withState(viewModel) { state ->
if (state.isSelectModeEnabled) {
enableSelectMode(false)
} else {
onBackPressedCallback.isEnabled = false
activity?.onBackPressedDispatcher?.onBackPressed()
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setupToolbar(views.otherSessionsToolbar).setTitle(args.titleResourceId).allowBack() setupToolbar(views.otherSessionsToolbar).setTitle(args.titleResourceId).allowBack()
@ -102,11 +154,22 @@ class OtherSessionsFragment :
} }
override fun invalidate() = withState(viewModel) { state -> override fun invalidate() = withState(viewModel) { state ->
updateToolbar(state.isSelectModeEnabled)
if (state.devices is Success) { if (state.devices is Success) {
renderDevices(state.devices(), state.currentFilter) renderDevices(state.devices(), state.currentFilter)
} }
} }
private fun updateToolbar(isSelectModeEnabled: Boolean) {
invalidateOptionsMenu()
val title = if (isSelectModeEnabled) {
stringProvider.getQuantityString(R.plurals.device_manager_other_sessions_selected, 0, 0)
} else {
getString(args.titleResourceId)
}
toolbar?.title = title
}
private fun renderDevices(devices: List<DeviceFullInfo>?, currentFilter: DeviceManagerFilterType) { private fun renderDevices(devices: List<DeviceFullInfo>?, currentFilter: DeviceManagerFilterType) {
views.otherSessionsFilterBadgeImageView.isVisible = currentFilter != DeviceManagerFilterType.ALL_SESSIONS views.otherSessionsFilterBadgeImageView.isVisible = currentFilter != DeviceManagerFilterType.ALL_SESSIONS
views.otherSessionsSecurityRecommendationView.isVisible = currentFilter != DeviceManagerFilterType.ALL_SESSIONS views.otherSessionsSecurityRecommendationView.isVisible = currentFilter != DeviceManagerFilterType.ALL_SESSIONS

View file

@ -64,9 +64,12 @@ class OtherSessionsViewModel @AssistedInject constructor(
} }
} }
// TODO update unit tests
override fun handle(action: OtherSessionsAction) { override fun handle(action: OtherSessionsAction) {
when (action) { when (action) {
is OtherSessionsAction.FilterDevices -> handleFilterDevices(action) is OtherSessionsAction.FilterDevices -> handleFilterDevices(action)
OtherSessionsAction.DisableSelectMode -> handleDisableSelectMode()
OtherSessionsAction.EnableSelectMode -> handleEnableSelectMode()
} }
} }
@ -78,4 +81,12 @@ class OtherSessionsViewModel @AssistedInject constructor(
} }
observeDevices(action.filterType) observeDevices(action.filterType)
} }
private fun handleDisableSelectMode() {
setState { copy(isSelectModeEnabled = false) }
}
private fun handleEnableSelectMode() {
setState { copy(isSelectModeEnabled = true) }
}
} }

View file

@ -26,6 +26,7 @@ data class OtherSessionsViewState(
val devices: Async<List<DeviceFullInfo>> = Uninitialized, val devices: Async<List<DeviceFullInfo>> = Uninitialized,
val currentFilter: DeviceManagerFilterType = DeviceManagerFilterType.ALL_SESSIONS, val currentFilter: DeviceManagerFilterType = DeviceManagerFilterType.ALL_SESSIONS,
val excludeCurrentDevice: Boolean = false, val excludeCurrentDevice: Boolean = false,
val isSelectModeEnabled: Boolean = false,
) : MavericksState { ) : MavericksState {
constructor(args: OtherSessionsArgs) : this(excludeCurrentDevice = args.excludeCurrentDevice) constructor(args: OtherSessionsArgs) : this(excludeCurrentDevice = args.excludeCurrentDevice)

View file

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="AlwaysShowAction">
<item
android:id="@+id/otherSessionsSelect"
android:title="@string/device_manager_other_sessions_select"
app:showAsAction="withText|never" />
<item
android:id="@+id/otherSessionsSelectAll"
android:title="@string/device_manager_other_sessions_select_all"
app:showAsAction="withText|never" />
<item
android:id="@+id/otherSessionsDeselectAll"
android:title="@string/device_manager_other_sessions_deselect_all"
app:showAsAction="withText|never" />
</menu>