mirror of
https://github.com/element-hq/element-android
synced 2024-11-24 02:15:35 +03:00
Rendering Application section into session details
This commit is contained in:
parent
acd05a0233
commit
9f9f6e14be
7 changed files with 100 additions and 31 deletions
|
@ -3309,6 +3309,10 @@
|
|||
<string name="device_manager_session_details_session_name">Session name</string>
|
||||
<string name="device_manager_session_details_session_id">Session ID</string>
|
||||
<string name="device_manager_session_details_session_last_activity">Last activity</string>
|
||||
<string name="device_manager_session_details_application">Application</string>
|
||||
<string name="device_manager_session_details_application_name">Name</string>
|
||||
<string name="device_manager_session_details_application_version">Version</string>
|
||||
<string name="device_manager_session_details_application_url">URL</string>
|
||||
<string name="device_manager_session_details_device_ip_address">IP address</string>
|
||||
<string name="device_manager_session_rename">Rename session</string>
|
||||
<string name="device_manager_session_rename_edit_hint">Session name</string>
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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<DeviceInfo>() {
|
||||
) : TypedEpoxyController<DeviceFullInfo>() {
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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<DeviceInfo> = Uninitialized,
|
||||
val deviceFullInfo: Async<DeviceFullInfo> = Uninitialized,
|
||||
) : MavericksState {
|
||||
constructor(args: SessionDetailsArgs) : this(
|
||||
deviceId = args.deviceId
|
||||
|
|
|
@ -57,12 +57,10 @@ class SessionDetailsViewModelTest {
|
|||
fun `given the viewModel has been initialized then viewState is updated with session info`() {
|
||||
// Given
|
||||
val deviceFullInfo = mockk<DeviceFullInfo>()
|
||||
val deviceInfo = mockk<DeviceInfo>()
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue