From bbe238e9c6fbaeaead6c6fbd471179ef7a692283 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Fri, 2 Sep 2022 10:02:54 +0200 Subject: [PATCH] Adding last seen details + fix observation of wrong deviceId in ViewModel --- .../src/main/res/values/strings.xml | 1 + .../v2/VectorSettingsDevicesFragment.kt | 9 +++-- .../v2/VectorSettingsDevicesViewNavigator.kt | 4 +-- .../devices/v2/list/SessionInfoView.kt | 36 +++++++++++++++++-- .../devices/v2/list/SessionInfoViewState.kt | 3 +- .../v2/overview/SessionOverviewActivity.kt | 4 +-- .../v2/overview/SessionOverviewArgs.kt | 2 +- .../v2/overview/SessionOverviewFragment.kt | 9 +++-- .../v2/overview/SessionOverviewViewModel.kt | 4 +-- .../v2/overview/SessionOverviewViewState.kt | 4 +-- .../src/main/res/layout/view_session_info.xml | 31 +++++++++++++++- .../overview/SessionOverviewViewModelTest.kt | 4 +-- 12 files changed, 91 insertions(+), 20 deletions(-) diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index 15dd579386..892c31ecf8 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -3247,5 +3247,6 @@ Current Session Session + Last activity %1$s diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt index f7f6ca6db4..2262f083da 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt @@ -31,6 +31,7 @@ import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R +import im.vector.app.core.date.VectorDateFormatter import im.vector.app.core.dialogs.ManuallyVerifyDialog import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentSettingsDevicesBinding @@ -55,6 +56,8 @@ class VectorSettingsDevicesFragment : @Inject lateinit var viewNavigator: VectorSettingsDevicesViewNavigator + @Inject lateinit var dateFormatter: VectorDateFormatter + private val viewModel: DevicesViewModel by fragmentViewModel() override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSettingsDevicesBinding { @@ -214,7 +217,7 @@ class VectorSettingsDevicesFragment : isCurrentSession = true, deviceFullInfo = it ) - views.deviceListCurrentSession.render(viewState) + views.deviceListCurrentSession.render(viewState, dateFormatter) views.deviceListCurrentSession.debouncedClicks { currentDeviceInfo.deviceInfo.deviceId?.let { deviceId -> navigateToSessionOverview(deviceId) } } @@ -226,10 +229,10 @@ class VectorSettingsDevicesFragment : } } - private fun navigateToSessionOverview(sessionId: String) { + private fun navigateToSessionOverview(deviceId: String) { viewNavigator.navigateToSessionOverview( context = requireActivity(), - sessionId = sessionId + deviceId = deviceId ) } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesViewNavigator.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesViewNavigator.kt index 25c971aacb..54eed3bc14 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesViewNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesViewNavigator.kt @@ -22,7 +22,7 @@ import javax.inject.Inject class VectorSettingsDevicesViewNavigator @Inject constructor() { - fun navigateToSessionOverview(context: Context, sessionId: String) { - context.startActivity(SessionOverviewActivity.newIntent(context, sessionId)) + fun navigateToSessionOverview(context: Context, deviceId: String) { + context.startActivity(SessionOverviewActivity.newIntent(context, deviceId)) } } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoView.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoView.kt index 536184faec..df50666b3b 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoView.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoView.kt @@ -19,11 +19,15 @@ package im.vector.app.features.settings.devices.v2.list import android.content.Context import android.util.AttributeSet import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.view.isGone import androidx.core.view.isVisible import im.vector.app.R +import im.vector.app.core.date.DateFormatKind +import im.vector.app.core.date.VectorDateFormatter import im.vector.app.core.extensions.setTextWithColoredPart import im.vector.app.databinding.ViewSessionInfoBinding import im.vector.app.features.themes.ThemeUtils +import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel class SessionInfoView @JvmOverloads constructor( @@ -43,13 +47,14 @@ class SessionInfoView @JvmOverloads constructor( val viewDetailsButton = views.sessionInfoViewDetailsButton - fun render(sessionInfoViewState: SessionInfoViewState) { + fun render(sessionInfoViewState: SessionInfoViewState, dateFormatter: VectorDateFormatter) { renderDeviceInfo(sessionInfoViewState.deviceFullInfo.deviceInfo.displayName.orEmpty()) renderVerificationStatus( sessionInfoViewState.deviceFullInfo.trustLevelForShield, sessionInfoViewState.isCurrentSession, - sessionInfoViewState.hasLearnMoreLink + sessionInfoViewState.isLearnMoreLinkVisible ) + renderDeviceLastSeenDetails(sessionInfoViewState.deviceFullInfo.deviceInfo, dateFormatter, sessionInfoViewState.isLastSeenDetailsVisible) renderDetailsButton(sessionInfoViewState.isDetailsButtonVisible) } @@ -117,6 +122,33 @@ class SessionInfoView @JvmOverloads constructor( views.sessionInfoNameTextView.text = sessionName } + private fun renderDeviceLastSeenDetails( + deviceInfo: DeviceInfo, + dateFormatter: VectorDateFormatter, + isLastSeenDetailsVisible: Boolean, + ) { + deviceInfo.lastSeenTs + ?.takeIf { isLastSeenDetailsVisible } + ?.let { timestamp -> + views.sessionInfoLastActivityTextView.isVisible = true + val formattedTs = dateFormatter.format(timestamp, DateFormatKind.DEFAULT_DATE_AND_TIME) + views.sessionInfoLastActivityTextView.text = context.getString(R.string.device_manager_session_last_activity, formattedTs) + } + ?: run { + views.sessionInfoLastActivityTextView.isGone = true + } + + deviceInfo.lastSeenIp + ?.takeIf { isLastSeenDetailsVisible } + ?.let { ipAddress -> + views.sessionInfoLastIPAddressTextView.isVisible = true + views.sessionInfoLastIPAddressTextView.text = ipAddress + } + ?: run { + views.sessionInfoLastIPAddressTextView.isGone = true + } + } + private fun renderDetailsButton(isDetailsButtonVisible: Boolean) { views.sessionInfoViewDetailsButton.isVisible = isDetailsButtonVisible } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoViewState.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoViewState.kt index cf7c6f0ae8..22ad710676 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoViewState.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoViewState.kt @@ -22,5 +22,6 @@ data class SessionInfoViewState( val isCurrentSession: Boolean, val deviceFullInfo: DeviceFullInfo, val isDetailsButtonVisible: Boolean = true, - val hasLearnMoreLink: Boolean = false + val isLearnMoreLinkVisible: Boolean = false, + val isLastSeenDetailsVisible: Boolean = false, ) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewActivity.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewActivity.kt index a663c0ff2a..015fcccf51 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewActivity.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewActivity.kt @@ -43,9 +43,9 @@ class SessionOverviewActivity : SimpleFragmentActivity() { } companion object { - fun newIntent(context: Context, sessionId: String): Intent { + fun newIntent(context: Context, deviceId: String): Intent { return Intent(context, SessionOverviewActivity::class.java).apply { - putExtra(Mavericks.KEY_ARG, SessionOverviewArgs(sessionId)) + putExtra(Mavericks.KEY_ARG, SessionOverviewArgs(deviceId)) } } } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewArgs.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewArgs.kt index 87ea883362..27c8d6fb2e 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewArgs.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewArgs.kt @@ -21,5 +21,5 @@ import kotlinx.parcelize.Parcelize @Parcelize data class SessionOverviewArgs( - val sessionId: String + val deviceId: String ) : Parcelable diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt index eb2a3aa93f..dbe75c94cc 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt @@ -29,10 +29,12 @@ import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R +import im.vector.app.core.date.VectorDateFormatter import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentSessionOverviewBinding import im.vector.app.features.settings.devices.DeviceFullInfo import im.vector.app.features.settings.devices.v2.list.SessionInfoViewState +import javax.inject.Inject /** * Display the overview info about a Session. @@ -41,6 +43,8 @@ import im.vector.app.features.settings.devices.v2.list.SessionInfoViewState class SessionOverviewFragment : VectorBaseFragment() { + @Inject lateinit var dateFormatter: VectorDateFormatter + private val viewModel: SessionOverviewViewModel by fragmentViewModel() override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSessionOverviewBinding { @@ -89,9 +93,10 @@ class SessionOverviewFragment : isCurrentSession = isCurrentSession, deviceFullInfo = deviceFullInfo, isDetailsButtonVisible = false, - hasLearnMoreLink = true + isLearnMoreLinkVisible = true, + isLastSeenDetailsVisible = true, ) - views.sessionOverviewInfo.render(viewState) + views.sessionOverviewInfo.render(viewState, dateFormatter) } private fun hideSessionInfo() { diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt index 9c40480270..1a1d3640a2 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt @@ -46,10 +46,10 @@ class SessionOverviewViewModel @AssistedInject constructor( init { val currentDeviceId = session.sessionParams.deviceId.orEmpty() setState { - copy(isCurrentSession = sessionId.isNotEmpty() && sessionId == currentDeviceId) + copy(isCurrentSession = deviceId.isNotEmpty() && deviceId == currentDeviceId) } - observeSessionInfo(currentDeviceId) + observeSessionInfo(initialState.deviceId) } private fun observeSessionInfo(deviceId: String) { diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewState.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewState.kt index 8fa19a6eee..c9f5635cbd 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewState.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewState.kt @@ -22,11 +22,11 @@ import com.airbnb.mvrx.Uninitialized import im.vector.app.features.settings.devices.DeviceFullInfo data class SessionOverviewViewState( - val sessionId: String, + val deviceId: String, val isCurrentSession: Boolean = false, val deviceInfo: Async = Uninitialized, ) : MavericksState { constructor(args: SessionOverviewArgs) : this( - sessionId = args.sessionId + deviceId = args.deviceId ) } diff --git a/vector/src/main/res/layout/view_session_info.xml b/vector/src/main/res/layout/view_session_info.xml index 02aad7b19d..49e1ebbb77 100644 --- a/vector/src/main/res/layout/view_session_info.xml +++ b/vector/src/main/res/layout/view_session_info.xml @@ -72,6 +72,35 @@ app:layout_constraintTop_toBottomOf="@id/sessionInfoVerificationStatusContainer" tools:text="@string/device_manager_verification_status_detail_current_session_verified" /> + + + +