@@ -18,8 +18,12 @@ package im.vector.app.features.settings.devices.v2.othersessions
18
18
19
19
import android.os.Bundle
20
20
import android.view.LayoutInflater
21
+ import android.view.Menu
22
+ import android.view.MenuItem
21
23
import android.view.View
22
24
import android.view.ViewGroup
25
+ import androidx.activity.OnBackPressedCallback
26
+ import androidx.activity.addCallback
23
27
import androidx.annotation.StringRes
24
28
import androidx.core.view.isVisible
25
29
import com.airbnb.mvrx.Success
@@ -31,7 +35,9 @@ import im.vector.app.R
31
35
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
32
36
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment.ResultListener.Companion.RESULT_OK
33
37
import im.vector.app.core.platform.VectorBaseFragment
38
+ import im.vector.app.core.platform.VectorMenuProvider
34
39
import im.vector.app.core.resources.ColorProvider
40
+ import im.vector.app.core.resources.StringProvider
35
41
import im.vector.app.databinding.FragmentOtherSessionsBinding
36
42
import im.vector.app.features.settings.devices.v2.DeviceFullInfo
37
43
import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterBottomSheet
@@ -40,25 +46,79 @@ import im.vector.app.features.settings.devices.v2.list.OtherSessionsView
40
46
import im.vector.app.features.settings.devices.v2.list.SESSION_IS_MARKED_AS_INACTIVE_AFTER_DAYS
41
47
import im.vector.app.features.settings.devices.v2.more.SessionLearnMoreBottomSheet
42
48
import im.vector.app.features.themes.ThemeUtils
49
+ import org.matrix.android.sdk.api.extensions.orFalse
43
50
import javax.inject.Inject
44
51
45
52
@AndroidEntryPoint
46
53
class OtherSessionsFragment :
47
54
VectorBaseFragment <FragmentOtherSessionsBinding >(),
48
55
VectorBaseBottomSheetDialogFragment .ResultListener ,
49
- OtherSessionsView .Callback {
56
+ OtherSessionsView .Callback ,
57
+ VectorMenuProvider {
50
58
51
59
private val viewModel: OtherSessionsViewModel by fragmentViewModel()
52
60
private val args: OtherSessionsArgs by args()
53
61
54
62
@Inject lateinit var colorProvider: ColorProvider
55
63
64
+ @Inject lateinit var stringProvider: StringProvider
65
+
56
66
@Inject lateinit var viewNavigator: OtherSessionsViewNavigator
57
67
58
68
override fun getBinding (inflater : LayoutInflater , container : ViewGroup ? ): FragmentOtherSessionsBinding {
59
69
return FragmentOtherSessionsBinding .inflate(layoutInflater, container, false )
60
70
}
61
71
72
+ override fun getMenuRes () = R .menu.menu_other_sessions
73
+
74
+ override fun handlePrepareMenu (menu : Menu ) {
75
+ withState(viewModel) { state ->
76
+ val isSelectModeEnabled = state.isSelectModeEnabled
77
+ menu.findItem(R .id.otherSessionsSelectAll).isVisible = isSelectModeEnabled
78
+ menu.findItem(R .id.otherSessionsDeselectAll).isVisible = isSelectModeEnabled
79
+ menu.findItem(R .id.otherSessionsSelect).isVisible = ! isSelectModeEnabled && state.devices()?.isNotEmpty().orFalse()
80
+ }
81
+ }
82
+
83
+ override fun handleMenuItemSelected (item : MenuItem ): Boolean {
84
+ return when (item.itemId) {
85
+ R .id.otherSessionsSelect -> {
86
+ enableSelectMode(true )
87
+ true
88
+ }
89
+ R .id.otherSessionsSelectAll -> {
90
+ viewModel.handle(OtherSessionsAction .SelectAll )
91
+ true
92
+ }
93
+ R .id.otherSessionsDeselectAll -> {
94
+ viewModel.handle(OtherSessionsAction .DeselectAll )
95
+ true
96
+ }
97
+ else -> false
98
+ }
99
+ }
100
+
101
+ private fun enableSelectMode (isEnabled : Boolean , deviceId : String? = null) {
102
+ val action = if (isEnabled) OtherSessionsAction .EnableSelectMode (deviceId) else OtherSessionsAction .DisableSelectMode
103
+ viewModel.handle(action)
104
+ }
105
+
106
+ override fun onCreate (savedInstanceState : Bundle ? ) {
107
+ super .onCreate(savedInstanceState)
108
+ activity?.onBackPressedDispatcher?.addCallback(owner = this ) {
109
+ handleBackPress(this )
110
+ }
111
+ }
112
+
113
+ private fun handleBackPress (onBackPressedCallback : OnBackPressedCallback ) = withState(viewModel) { state ->
114
+ if (state.isSelectModeEnabled) {
115
+ enableSelectMode(false )
116
+ } else {
117
+ onBackPressedCallback.isEnabled = false
118
+ activity?.onBackPressedDispatcher?.onBackPressed()
119
+ }
120
+ }
121
+
62
122
override fun onViewCreated (view : View , savedInstanceState : Bundle ? ) {
63
123
super .onViewCreated(view, savedInstanceState)
64
124
setupToolbar(views.otherSessionsToolbar).setTitle(args.titleResourceId).allowBack()
@@ -103,11 +163,24 @@ class OtherSessionsFragment :
103
163
104
164
override fun invalidate () = withState(viewModel) { state ->
105
165
if (state.devices is Success ) {
106
- renderDevices(state.devices(), state.currentFilter)
166
+ val devices = state.devices.invoke()
167
+ renderDevices(devices, state.currentFilter)
168
+ updateToolbar(devices, state.isSelectModeEnabled)
107
169
}
108
170
}
109
171
110
- private fun renderDevices (devices : List <DeviceFullInfo >? , currentFilter : DeviceManagerFilterType ) {
172
+ private fun updateToolbar (devices : List <DeviceFullInfo >, isSelectModeEnabled : Boolean ) {
173
+ invalidateOptionsMenu()
174
+ val title = if (isSelectModeEnabled) {
175
+ val selection = devices.count { it.isSelected }
176
+ stringProvider.getQuantityString(R .plurals.x_selected, selection, selection)
177
+ } else {
178
+ getString(args.titleResourceId)
179
+ }
180
+ toolbar?.title = title
181
+ }
182
+
183
+ private fun renderDevices (devices : List <DeviceFullInfo >, currentFilter : DeviceManagerFilterType ) {
111
184
views.otherSessionsFilterBadgeImageView.isVisible = currentFilter != DeviceManagerFilterType .ALL_SESSIONS
112
185
views.otherSessionsSecurityRecommendationView.isVisible = currentFilter != DeviceManagerFilterType .ALL_SESSIONS
113
186
views.deviceListHeaderOtherSessions.isVisible = currentFilter == DeviceManagerFilterType .ALL_SESSIONS
@@ -160,7 +233,7 @@ class OtherSessionsFragment :
160
233
}
161
234
}
162
235
163
- if (devices.isNullOrEmpty ()) {
236
+ if (devices.isEmpty ()) {
164
237
views.deviceListOtherSessions.isVisible = false
165
238
views.otherSessionsNotFoundLayout.isVisible = true
166
239
} else {
@@ -190,11 +263,21 @@ class OtherSessionsFragment :
190
263
SessionLearnMoreBottomSheet .show(childFragmentManager, args)
191
264
}
192
265
193
- override fun onOtherSessionClicked (deviceId : String ) {
194
- viewNavigator.navigateToSessionOverview(
195
- context = requireActivity(),
196
- deviceId = deviceId
197
- )
266
+ override fun onOtherSessionLongClicked (deviceId : String ) = withState(viewModel) { state ->
267
+ if (! state.isSelectModeEnabled) {
268
+ enableSelectMode(true , deviceId)
269
+ }
270
+ }
271
+
272
+ override fun onOtherSessionClicked (deviceId : String ) = withState(viewModel) { state ->
273
+ if (state.isSelectModeEnabled) {
274
+ viewModel.handle(OtherSessionsAction .ToggleSelectionForDevice (deviceId))
275
+ } else {
276
+ viewNavigator.navigateToSessionOverview(
277
+ context = requireActivity(),
278
+ deviceId = deviceId
279
+ )
280
+ }
198
281
}
199
282
200
283
override fun onViewAllOtherSessionsClicked () {
0 commit comments