diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml
index 63c1f8a8bb..0b17b64c4a 100644
--- a/library/ui-strings/src/main/res/values/strings.xml
+++ b/library/ui-strings/src/main/res/values/strings.xml
@@ -3309,6 +3309,10 @@
Session name
Session ID
Last activity
+ Application
+ Name
+ Version
+ URL
IP address
Rename session
Session name
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/CheckIfSectionApplicationIsVisibleUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/CheckIfSectionApplicationIsVisibleUseCase.kt
new file mode 100644
index 0000000000..cd93cb73db
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/CheckIfSectionApplicationIsVisibleUseCase.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.details
+
+import im.vector.app.core.session.clientinfo.MatrixClientInfoContent
+import org.matrix.android.sdk.api.extensions.orFalse
+import javax.inject.Inject
+
+class CheckIfSectionApplicationIsVisibleUseCase @Inject constructor() {
+
+ // TODO add unit tests
+ fun execute(matrixClientInfoContent: MatrixClientInfoContent?): Boolean {
+ return matrixClientInfoContent?.name?.isNotEmpty().orFalse() ||
+ matrixClientInfoContent?.version?.isNotEmpty().orFalse() ||
+ matrixClientInfoContent?.url?.isNotEmpty().orFalse()
+ }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsController.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsController.kt
index 1fb5be4d78..eb4f823889 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsController.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsController.kt
@@ -23,17 +23,20 @@ import im.vector.app.R
import im.vector.app.core.date.DateFormatKind
import im.vector.app.core.date.VectorDateFormatter
import im.vector.app.core.resources.StringProvider
+import im.vector.app.core.session.clientinfo.MatrixClientInfoContent
import im.vector.app.core.utils.DimensionConverter
+import im.vector.app.features.settings.devices.v2.DeviceFullInfo
import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
import javax.inject.Inject
class SessionDetailsController @Inject constructor(
private val checkIfSectionSessionIsVisibleUseCase: CheckIfSectionSessionIsVisibleUseCase,
private val checkIfSectionDeviceIsVisibleUseCase: CheckIfSectionDeviceIsVisibleUseCase,
+ private val checkIfSectionApplicationIsVisibleUseCase: CheckIfSectionApplicationIsVisibleUseCase,
private val stringProvider: StringProvider,
private val dateFormatter: VectorDateFormatter,
private val dimensionConverter: DimensionConverter,
-) : TypedEpoxyController() {
+) : TypedEpoxyController() {
var callback: Callback? = null
@@ -41,15 +44,22 @@ class SessionDetailsController @Inject constructor(
fun onItemLongClicked(content: String)
}
- override fun buildModels(data: DeviceInfo?) {
- data?.let { info ->
- val hasSectionSession = hasSectionSession(data)
+ override fun buildModels(data: DeviceFullInfo?) {
+ data?.let { fullInfo ->
+ val deviceInfo = fullInfo.deviceInfo
+ val matrixClientInfo = fullInfo.matrixClientInfo
+ val hasSectionSession = hasSectionSession(deviceInfo)
if (hasSectionSession) {
- buildSectionSession(info)
+ buildSectionSession(deviceInfo)
}
- if (hasSectionDevice(data)) {
- buildSectionDevice(info, addExtraTopMargin = hasSectionSession)
+ val hasApplicationSection = hasSectionApplication(matrixClientInfo)
+ if (hasApplicationSection && matrixClientInfo != null) {
+ buildSectionApplication(matrixClientInfo, addExtraTopMargin = hasSectionSession)
+ }
+
+ if (hasSectionDevice(deviceInfo)) {
+ buildSectionDevice(deviceInfo, addExtraTopMargin = hasSectionSession || hasApplicationSection)
}
}
}
@@ -83,39 +93,64 @@ class SessionDetailsController @Inject constructor(
}
private fun buildSectionSession(data: DeviceInfo) {
- val sessionName = data.displayName
- val sessionId = data.deviceId
- val sessionLastSeenTs = data.lastSeenTs
+ val sessionName = data.displayName.orEmpty()
+ val sessionId = data.deviceId.orEmpty()
+ val sessionLastSeenTs = data.lastSeenTs ?: -1
buildHeaderItem(R.string.device_manager_session_title)
- sessionName?.let {
- val hasDivider = sessionId != null || sessionLastSeenTs != null
- buildContentItem(R.string.device_manager_session_details_session_name, it, hasDivider)
+ if (sessionName.isNotEmpty()) {
+ val hasDivider = sessionId.isNotEmpty() || sessionLastSeenTs > 0
+ buildContentItem(R.string.device_manager_session_details_session_name, sessionName, hasDivider)
}
- sessionId?.let {
- val hasDivider = sessionLastSeenTs != null
- buildContentItem(R.string.device_manager_session_details_session_id, it, hasDivider)
+ if (sessionId.isNotEmpty()) {
+ val hasDivider = sessionLastSeenTs > 0
+ buildContentItem(R.string.device_manager_session_details_session_id, sessionId, hasDivider)
}
- sessionLastSeenTs?.let {
- val formattedDate = dateFormatter.format(it, DateFormatKind.MESSAGE_DETAIL)
+ if (sessionLastSeenTs > 0) {
+ val formattedDate = dateFormatter.format(sessionLastSeenTs, DateFormatKind.MESSAGE_DETAIL)
val hasDivider = false
buildContentItem(R.string.device_manager_session_details_session_last_activity, formattedDate, hasDivider)
}
}
+ private fun hasSectionApplication(matrixClientInfoContent: MatrixClientInfoContent?): Boolean {
+ return checkIfSectionApplicationIsVisibleUseCase.execute(matrixClientInfoContent)
+ }
+
+ private fun buildSectionApplication(matrixClientInfoContent: MatrixClientInfoContent, addExtraTopMargin: Boolean) {
+ val name = matrixClientInfoContent.name.orEmpty()
+ val version = matrixClientInfoContent.version.orEmpty()
+ val url = matrixClientInfoContent.url.orEmpty()
+
+ buildHeaderItem(R.string.device_manager_session_details_application, addExtraTopMargin)
+
+ if (name.isNotEmpty()) {
+ val hasDivider = version.isNotEmpty() || url.isNotEmpty()
+ buildContentItem(R.string.device_manager_session_details_application_name, name, hasDivider)
+ }
+ if (version.isNotEmpty()) {
+ val hasDivider = url.isNotEmpty()
+ buildContentItem(R.string.device_manager_session_details_application_version, version, hasDivider)
+ }
+ if (url.isNotEmpty()) {
+ val hasDivider = false
+ buildContentItem(R.string.device_manager_session_details_application_url, url, hasDivider)
+ }
+ }
+
private fun hasSectionDevice(data: DeviceInfo): Boolean {
return checkIfSectionDeviceIsVisibleUseCase.execute(data)
}
private fun buildSectionDevice(data: DeviceInfo, addExtraTopMargin: Boolean) {
- val lastSeenIp = data.lastSeenIp
+ val lastSeenIp = data.lastSeenIp.orEmpty()
buildHeaderItem(R.string.device_manager_device_title, addExtraTopMargin)
- lastSeenIp?.let {
+ if (lastSeenIp.isNotEmpty()) {
val hasDivider = false
- buildContentItem(R.string.device_manager_session_details_device_ip_address, it, hasDivider)
+ buildContentItem(R.string.device_manager_session_details_device_ip_address, lastSeenIp, hasDivider)
}
}
}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsFragment.kt
index 5d7717e5f7..f518ab9382 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsFragment.kt
@@ -33,6 +33,7 @@ import im.vector.app.core.extensions.configureWith
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.platform.showOptimizedSnackbar
import im.vector.app.databinding.FragmentSessionDetailsBinding
+import im.vector.app.features.settings.devices.v2.DeviceFullInfo
import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
import javax.inject.Inject
@@ -92,16 +93,16 @@ class SessionDetailsFragment :
}
override fun invalidate() = withState(viewModel) { state ->
- if (state.deviceInfo is Success) {
- renderSessionDetails(state.deviceInfo.invoke())
+ if (state.deviceFullInfo is Success) {
+ renderSessionDetails(state.deviceFullInfo.invoke())
} else {
hideSessionDetails()
}
}
- private fun renderSessionDetails(deviceInfo: DeviceInfo) {
+ private fun renderSessionDetails(deviceFullInfo: DeviceFullInfo) {
views.sessionDetails.isVisible = true
- sessionDetailsController.setData(deviceInfo)
+ sessionDetailsController.setData(deviceFullInfo)
}
private fun hideSessionDetails() {
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewModel.kt
index c37858cc54..44e10701a0 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewModel.kt
@@ -48,7 +48,7 @@ class SessionDetailsViewModel @AssistedInject constructor(
private fun observeSessionInfo(deviceId: String) {
getDeviceFullInfoUseCase.execute(deviceId)
- .onEach { setState { copy(deviceInfo = Success(it.deviceInfo)) } }
+ .onEach { setState { copy(deviceFullInfo = Success(it)) } }
.launchIn(viewModelScope)
}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewState.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewState.kt
index 15868d3110..d216bbda51 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewState.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewState.kt
@@ -19,11 +19,11 @@ package im.vector.app.features.settings.devices.v2.details
import com.airbnb.mvrx.Async
import com.airbnb.mvrx.MavericksState
import com.airbnb.mvrx.Uninitialized
-import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
+import im.vector.app.features.settings.devices.v2.DeviceFullInfo
data class SessionDetailsViewState(
val deviceId: String,
- val deviceInfo: Async = Uninitialized,
+ val deviceFullInfo: Async = Uninitialized,
) : MavericksState {
constructor(args: SessionDetailsArgs) : this(
deviceId = args.deviceId
diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewModelTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewModelTest.kt
index 572f39af31..5fdd219226 100644
--- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewModelTest.kt
+++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewModelTest.kt
@@ -57,12 +57,10 @@ class SessionDetailsViewModelTest {
fun `given the viewModel has been initialized then viewState is updated with session info`() {
// Given
val deviceFullInfo = mockk()
- val deviceInfo = mockk()
- every { deviceFullInfo.deviceInfo } returns deviceInfo
every { getDeviceFullInfoUseCase.execute(A_SESSION_ID) } returns flowOf(deviceFullInfo)
val expectedState = SessionDetailsViewState(
deviceId = A_SESSION_ID,
- deviceInfo = Success(deviceInfo)
+ deviceFullInfo = Success(deviceFullInfo)
)
// When