mirror of
https://github.com/element-hq/element-android
synced 2024-11-27 20:06:51 +03:00
List devices.
This commit is contained in:
parent
643f99b8e0
commit
ab4ebc7f11
8 changed files with 81 additions and 9 deletions
|
@ -19,6 +19,8 @@ package im.vector.app.features.settings.devices.v2
|
|||
import com.airbnb.mvrx.Async
|
||||
import com.airbnb.mvrx.MavericksState
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterType
|
||||
import org.matrix.android.sdk.api.extensions.orFalse
|
||||
|
||||
data class DevicesViewState(
|
||||
val currentSessionCrossSigningInfo: CurrentSessionCrossSigningInfo = CurrentSessionCrossSigningInfo(),
|
||||
|
@ -26,4 +28,17 @@ data class DevicesViewState(
|
|||
val unverifiedSessionsCount: Int = 0,
|
||||
val inactiveSessionsCount: Int = 0,
|
||||
val isLoading: Boolean = false,
|
||||
) : MavericksState
|
||||
val currentFilter: DeviceManagerFilterType = DeviceManagerFilterType.ALL_SESSIONS,
|
||||
) : MavericksState {
|
||||
|
||||
fun List<DeviceFullInfo>?.filteredDevices(): List<DeviceFullInfo>? {
|
||||
return this?.filter {
|
||||
when (currentFilter) {
|
||||
DeviceManagerFilterType.ALL_SESSIONS -> true
|
||||
DeviceManagerFilterType.VERIFIED -> it.cryptoDeviceInfo?.isVerified.orFalse()
|
||||
DeviceManagerFilterType.UNVERIFIED -> !it.cryptoDeviceInfo?.isVerified.orFalse()
|
||||
DeviceManagerFilterType.INACTIVE -> it.isInactive
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,10 +37,11 @@ import im.vector.app.core.resources.DrawableProvider
|
|||
import im.vector.app.databinding.FragmentSettingsDevicesBinding
|
||||
import im.vector.app.features.crypto.recover.SetupMode
|
||||
import im.vector.app.features.crypto.verification.VerificationBottomSheet
|
||||
import im.vector.app.features.settings.devices.v2.list.NUMBER_OF_OTHER_DEVICES_TO_RENDER
|
||||
import im.vector.app.features.settings.devices.v2.list.OtherSessionsView
|
||||
import im.vector.app.features.settings.devices.v2.list.SESSION_IS_MARKED_AS_INACTIVE_AFTER_DAYS
|
||||
import im.vector.app.features.settings.devices.v2.list.SecurityRecommendationViewState
|
||||
import im.vector.app.features.settings.devices.v2.list.SessionInfoViewState
|
||||
import im.vector.app.features.settings.devices.v2.list.OtherSessionsView
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
|
@ -198,7 +199,7 @@ class VectorSettingsDevicesFragment :
|
|||
} else {
|
||||
views.deviceListHeaderOtherSessions.isVisible = true
|
||||
views.deviceListOtherSessions.isVisible = true
|
||||
views.deviceListOtherSessions.render(otherDevices)
|
||||
views.deviceListOtherSessions.render(otherDevices.take(NUMBER_OF_OTHER_DEVICES_TO_RENDER), otherDevices.size)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ class OtherSessionsController @Inject constructor(
|
|||
text(host.stringProvider.getString(R.string.no_result_placeholder))
|
||||
}
|
||||
} else {
|
||||
data.take(NUMBER_OF_OTHER_DEVICES_TO_RENDER).forEach { device ->
|
||||
data.forEach { device ->
|
||||
val dateFormatKind = if (device.isInactive) DateFormatKind.TIMELINE_DAY_DIVIDER else DateFormatKind.DEFAULT_DATE_AND_TIME
|
||||
val formattedLastActivityDate = host.dateFormatter.format(device.deviceInfo.lastSeenTs, dateFormatKind)
|
||||
val description = if (device.isInactive) {
|
||||
|
|
|
@ -55,9 +55,9 @@ class OtherSessionsView @JvmOverloads constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun render(devices: List<DeviceFullInfo>) {
|
||||
fun render(devices: List<DeviceFullInfo>, totalNumberOfDevices: Int) {
|
||||
views.otherSessionsRecyclerView.configureWith(otherSessionsController, hasFixedSize = true)
|
||||
views.otherSessionsViewAllButton.text = context.getString(R.string.device_manager_other_sessions_view_all, devices.size)
|
||||
views.otherSessionsViewAllButton.text = context.getString(R.string.device_manager_other_sessions_view_all, totalNumberOfDevices)
|
||||
otherSessionsController.setData(devices)
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,12 @@ class SessionsListHeaderView @JvmOverloads constructor(
|
|||
|
||||
private fun setTitle(typedArray: TypedArray) {
|
||||
val title = typedArray.getString(R.styleable.SessionsListHeaderView_devicesListHeaderTitle)
|
||||
binding.sessionsListHeaderTitle.text = title
|
||||
if (title.isNullOrEmpty()) {
|
||||
binding.sessionsListHeaderTitle.isVisible = false
|
||||
} else {
|
||||
binding.sessionsListHeaderTitle.isVisible = true
|
||||
binding.sessionsListHeaderTitle.text = title
|
||||
}
|
||||
}
|
||||
|
||||
private fun setDescription(typedArray: TypedArray) {
|
||||
|
|
|
@ -21,16 +21,25 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.fragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment.ResultListener.Companion.RESULT_OK
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.databinding.FragmentOtherSessionsBinding
|
||||
import im.vector.app.features.settings.devices.v2.DeviceFullInfo
|
||||
import im.vector.app.features.settings.devices.v2.DevicesViewModel
|
||||
import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterBottomSheet
|
||||
import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterType
|
||||
|
||||
@AndroidEntryPoint
|
||||
class OtherSessionsFragment : VectorBaseFragment<FragmentOtherSessionsBinding>(), VectorBaseBottomSheetDialogFragment.ResultListener {
|
||||
|
||||
private val viewModel: DevicesViewModel by fragmentViewModel()
|
||||
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentOtherSessionsBinding {
|
||||
return FragmentOtherSessionsBinding.inflate(layoutInflater, container, false)
|
||||
}
|
||||
|
@ -54,4 +63,25 @@ class OtherSessionsFragment : VectorBaseFragment<FragmentOtherSessionsBinding>()
|
|||
Toast.makeText(requireContext(), data.toString(), Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
|
||||
override fun invalidate() = withState(viewModel) { state ->
|
||||
if (state.devices is Success) {
|
||||
with(state) {
|
||||
val devices = state.devices()
|
||||
?.filter { it.deviceInfo.deviceId != state.currentSessionCrossSigningInfo.deviceId }
|
||||
?.filteredDevices()
|
||||
renderDevices(devices, state.currentFilter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun renderDevices(devices: List<DeviceFullInfo>?, currentFilter: DeviceManagerFilterType) {
|
||||
views.otherSessionsFilterBadgeImageView.isVisible = currentFilter != DeviceManagerFilterType.ALL_SESSIONS
|
||||
|
||||
if (devices.isNullOrEmpty()) {
|
||||
// TODO. Render empty state
|
||||
} else {
|
||||
views.deviceListOtherSessions.render(devices, devices.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,4 +46,25 @@
|
|||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
|
||||
|
||||
<im.vector.app.features.settings.devices.v2.list.SessionsListHeaderView
|
||||
android:id="@+id/deviceListHeaderOtherSessions"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:devicesListHeaderDescription="@string/settings_sessions_other_description"
|
||||
app:devicesListHeaderTitle=""
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/appBarLayout"/>
|
||||
|
||||
<im.vector.app.features.settings.devices.v2.list.OtherSessionsView
|
||||
android:id="@+id/deviceListOtherSessions"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/deviceListHeaderOtherSessions" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
|
@ -23,10 +23,10 @@
|
|||
style="@style/TextAppearance.Vector.Body.DevicesManagement"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/layout_horizontal_margin"
|
||||
android:layout_marginTop="18.5dp"
|
||||
android:layout_marginEnd="40dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@id/sessions_list_header_title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/sessions_list_header_title"
|
||||
tools:text="For best security, verify your sessions and sign out from any session that you don’t recognize or use anymore. Learn More." />
|
||||
</merge>
|
||||
|
|
Loading…
Reference in a new issue