Better understanding of the model: server / protocol
Iso Element Web on this part.
This commit is contained in:
parent
64222ff704
commit
4641f77842
|
@ -17,10 +17,9 @@
|
|||
package im.vector.app.features.roomdirectory
|
||||
|
||||
/**
|
||||
* This class describes a rooms directory server.
|
||||
* This class describes a rooms directory server protocol.
|
||||
*/
|
||||
data class RoomDirectoryData(
|
||||
|
||||
/**
|
||||
* The server name (might be null)
|
||||
* Set null when the server is the current user's home server.
|
||||
|
@ -30,7 +29,12 @@ data class RoomDirectoryData(
|
|||
/**
|
||||
* The display name (the server description)
|
||||
*/
|
||||
val displayName: String = DEFAULT_HOME_SERVER_NAME,
|
||||
val displayName: String = MATRIX_PROTOCOL_NAME,
|
||||
|
||||
/**
|
||||
* the avatar url
|
||||
*/
|
||||
val avatarUrl: String? = null,
|
||||
|
||||
/**
|
||||
* The third party server identifier
|
||||
|
@ -40,15 +44,10 @@ data class RoomDirectoryData(
|
|||
/**
|
||||
* Tell if all the federated servers must be included
|
||||
*/
|
||||
val includeAllNetworks: Boolean = false,
|
||||
|
||||
/**
|
||||
* the avatar url
|
||||
*/
|
||||
val avatarUrl: String? = null
|
||||
val includeAllNetworks: Boolean = false
|
||||
) {
|
||||
|
||||
companion object {
|
||||
const val DEFAULT_HOME_SERVER_NAME = "Matrix"
|
||||
const val MATRIX_PROTOCOL_NAME = "Matrix"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2021 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.roomdirectory
|
||||
|
||||
data class RoomDirectoryServer(
|
||||
val serverName: String,
|
||||
|
||||
/**
|
||||
* True if this is the current user server
|
||||
*/
|
||||
val isUserServer: Boolean,
|
||||
|
||||
/**
|
||||
* Supported protocols
|
||||
* TODO Rename RoomDirectoryData to RoomDirectoryProtocols
|
||||
*/
|
||||
val protocols: List<RoomDirectoryData>
|
||||
)
|
|
@ -229,9 +229,7 @@ class RoomDirectoryViewModel @AssistedInject constructor(
|
|||
Timber.w("Try to join an already joining room. Should not happen")
|
||||
return@withState
|
||||
}
|
||||
val viaServers = state.roomDirectoryData.homeServer
|
||||
?.let { listOf(it) }
|
||||
.orEmpty()
|
||||
val viaServers = listOfNotNull(state.roomDirectoryData.homeServer)
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
session.joinRoom(action.roomId, viaServers = viaServers)
|
||||
|
|
|
@ -19,54 +19,88 @@ package im.vector.app.features.roomdirectory.picker
|
|||
import im.vector.app.R
|
||||
import im.vector.app.core.resources.StringArrayProvider
|
||||
import im.vector.app.features.roomdirectory.RoomDirectoryData
|
||||
import im.vector.app.features.roomdirectory.RoomDirectoryServer
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol
|
||||
import javax.inject.Inject
|
||||
|
||||
class RoomDirectoryListCreator @Inject constructor(private val stringArrayProvider: StringArrayProvider,
|
||||
private val session: Session) {
|
||||
class RoomDirectoryListCreator @Inject constructor(
|
||||
private val stringArrayProvider: StringArrayProvider,
|
||||
private val session: Session
|
||||
) {
|
||||
|
||||
fun computeDirectories(thirdPartyProtocolData: Map<String, ThirdPartyProtocol>): List<RoomDirectoryData> {
|
||||
val result = ArrayList<RoomDirectoryData>()
|
||||
fun computeDirectories(thirdPartyProtocolData: Map<String, ThirdPartyProtocol>): List<RoomDirectoryServer> {
|
||||
val result = ArrayList<RoomDirectoryServer>()
|
||||
|
||||
val protocols = ArrayList<RoomDirectoryData>()
|
||||
|
||||
// Add user homeserver name
|
||||
val userHsName = session.myUserId.substringAfter(":")
|
||||
|
||||
result.add(RoomDirectoryData(
|
||||
displayName = userHsName,
|
||||
includeAllNetworks = true
|
||||
))
|
||||
|
||||
// Add user's HS but for Matrix public rooms only
|
||||
result.add(RoomDirectoryData())
|
||||
|
||||
// Add custom directory servers
|
||||
val hsNamesList = stringArrayProvider.getStringArray(R.array.room_directory_servers)
|
||||
hsNamesList.forEach {
|
||||
if (it != userHsName) {
|
||||
// Use the server name as a default display name
|
||||
result.add(RoomDirectoryData(
|
||||
homeServer = it,
|
||||
displayName = it,
|
||||
includeAllNetworks = true
|
||||
))
|
||||
}
|
||||
}
|
||||
// Add default protocol
|
||||
protocols.add(
|
||||
RoomDirectoryData(
|
||||
homeServer = null,
|
||||
displayName = RoomDirectoryData.MATRIX_PROTOCOL_NAME,
|
||||
includeAllNetworks = false
|
||||
)
|
||||
)
|
||||
|
||||
// Add result of the request
|
||||
thirdPartyProtocolData.forEach {
|
||||
it.value.instances?.forEach { thirdPartyProtocolInstance ->
|
||||
result.add(RoomDirectoryData(
|
||||
homeServer = null,
|
||||
displayName = thirdPartyProtocolInstance.desc ?: "",
|
||||
thirdPartyInstanceId = thirdPartyProtocolInstance.instanceId,
|
||||
includeAllNetworks = false,
|
||||
// Default to protocol icon
|
||||
avatarUrl = thirdPartyProtocolInstance.icon ?: it.value.icon
|
||||
))
|
||||
protocols.add(
|
||||
RoomDirectoryData(
|
||||
homeServer = null,
|
||||
displayName = thirdPartyProtocolInstance.desc ?: "",
|
||||
thirdPartyInstanceId = thirdPartyProtocolInstance.instanceId,
|
||||
includeAllNetworks = false,
|
||||
// Default to protocol icon
|
||||
avatarUrl = thirdPartyProtocolInstance.icon ?: it.value.icon
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Add all rooms
|
||||
protocols.add(
|
||||
RoomDirectoryData(
|
||||
homeServer = null,
|
||||
displayName = RoomDirectoryData.MATRIX_PROTOCOL_NAME,
|
||||
includeAllNetworks = true
|
||||
)
|
||||
)
|
||||
|
||||
result.add(
|
||||
RoomDirectoryServer(
|
||||
serverName = userHsName,
|
||||
isUserServer = true,
|
||||
protocols = protocols
|
||||
)
|
||||
)
|
||||
|
||||
// Add custom directory servers, form the config file, excluding the current user homeserver
|
||||
stringArrayProvider.getStringArray(R.array.room_directory_servers)
|
||||
.filter { it != userHsName }
|
||||
.forEach {
|
||||
// Use the server name as a default display name
|
||||
result.add(
|
||||
RoomDirectoryServer(
|
||||
serverName = it,
|
||||
isUserServer = false,
|
||||
protocols = listOf(
|
||||
RoomDirectoryData(
|
||||
homeServer = it,
|
||||
displayName = RoomDirectoryData.MATRIX_PROTOCOL_NAME,
|
||||
includeAllNetworks = false
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// TODO Add manually added server by the user
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,33 +21,38 @@ import com.airbnb.mvrx.Fail
|
|||
import com.airbnb.mvrx.Incomplete
|
||||
import com.airbnb.mvrx.Success
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.dividerItem
|
||||
import im.vector.app.core.epoxy.errorWithRetryItem
|
||||
import im.vector.app.core.epoxy.loadingItem
|
||||
import im.vector.app.core.error.ErrorFormatter
|
||||
import im.vector.app.core.extensions.join
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.features.roomdirectory.RoomDirectoryData
|
||||
import im.vector.app.features.roomdirectory.RoomDirectoryServer
|
||||
import javax.inject.Inject
|
||||
|
||||
class RoomDirectoryPickerController @Inject constructor(private val stringProvider: StringProvider,
|
||||
private val errorFormatter: ErrorFormatter,
|
||||
private val roomDirectoryListCreator: RoomDirectoryListCreator
|
||||
class RoomDirectoryPickerController @Inject constructor(
|
||||
private val stringProvider: StringProvider,
|
||||
colorProvider: ColorProvider,
|
||||
private val errorFormatter: ErrorFormatter,
|
||||
private val roomDirectoryListCreator: RoomDirectoryListCreator
|
||||
) : TypedEpoxyController<RoomDirectoryPickerViewState>() {
|
||||
|
||||
var callback: Callback? = null
|
||||
|
||||
var index = 0
|
||||
private val dividerColor = colorProvider.getColorFromAttribute(R.attr.vctr_list_divider_color)
|
||||
|
||||
override fun buildModels(viewState: RoomDirectoryPickerViewState) {
|
||||
val host = this
|
||||
val asyncThirdPartyProtocol = viewState.asyncThirdPartyRequest
|
||||
|
||||
when (asyncThirdPartyProtocol) {
|
||||
when (val asyncThirdPartyProtocol = viewState.asyncThirdPartyRequest) {
|
||||
is Success -> {
|
||||
val directories = roomDirectoryListCreator.computeDirectories(asyncThirdPartyProtocol())
|
||||
|
||||
directories.forEach {
|
||||
buildDirectory(it)
|
||||
}
|
||||
directories.join(
|
||||
each = { _, roomDirectoryServer -> buildDirectory(roomDirectoryServer) },
|
||||
between = { idx, _ -> buildDivider(idx) }
|
||||
)
|
||||
}
|
||||
is Incomplete -> {
|
||||
loadingItem {
|
||||
|
@ -64,28 +69,46 @@ class RoomDirectoryPickerController @Inject constructor(private val stringProvid
|
|||
}
|
||||
}
|
||||
|
||||
private fun buildDirectory(roomDirectoryData: RoomDirectoryData) {
|
||||
private fun buildDivider(idx: Int) {
|
||||
val host = this
|
||||
roomDirectoryItem {
|
||||
id(host.index++)
|
||||
dividerItem {
|
||||
id("divider_${idx}")
|
||||
color(host.dividerColor)
|
||||
}
|
||||
}
|
||||
|
||||
directoryName(roomDirectoryData.displayName)
|
||||
private fun buildDirectory(roomDirectoryServer: RoomDirectoryServer) {
|
||||
val host = this
|
||||
roomDirectoryServerItem {
|
||||
id("server_" + roomDirectoryServer.serverName)
|
||||
serverName(roomDirectoryServer.serverName)
|
||||
|
||||
val description = when {
|
||||
roomDirectoryData.includeAllNetworks ->
|
||||
host.stringProvider.getString(R.string.directory_server_all_rooms_on_server, roomDirectoryData.displayName)
|
||||
"Matrix" == roomDirectoryData.displayName ->
|
||||
host.stringProvider.getString(R.string.directory_server_native_rooms, roomDirectoryData.displayName)
|
||||
else ->
|
||||
null
|
||||
if (roomDirectoryServer.isUserServer) {
|
||||
serverDescription(host.stringProvider.getString(R.string.directory_your_server))
|
||||
}
|
||||
}
|
||||
|
||||
directoryDescription(description)
|
||||
directoryAvatarUrl(roomDirectoryData.avatarUrl)
|
||||
includeAllNetworks(roomDirectoryData.includeAllNetworks)
|
||||
roomDirectoryServer.protocols.forEach { roomDirectoryData ->
|
||||
roomDirectoryItem {
|
||||
id("server_" + roomDirectoryServer.serverName + "_proto_" + roomDirectoryData.displayName)
|
||||
directoryName(
|
||||
if (roomDirectoryData.includeAllNetworks) {
|
||||
host.stringProvider.getString(R.string.directory_server_all_rooms_on_server, roomDirectoryServer.serverName)
|
||||
} else {
|
||||
roomDirectoryData.displayName
|
||||
}
|
||||
)
|
||||
if (roomDirectoryData.displayName == RoomDirectoryData.MATRIX_PROTOCOL_NAME && !roomDirectoryData.includeAllNetworks) {
|
||||
directoryDescription(
|
||||
host.stringProvider.getString(R.string.directory_server_native_rooms, roomDirectoryServer.serverName)
|
||||
)
|
||||
}
|
||||
directoryAvatarUrl(roomDirectoryData.avatarUrl)
|
||||
includeAllNetworks(roomDirectoryData.includeAllNetworks)
|
||||
|
||||
globalListener {
|
||||
host.callback?.onRoomDirectoryClicked(roomDirectoryData)
|
||||
globalListener {
|
||||
host.callback?.onRoomDirectoryClicked(roomDirectoryData)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright 2021 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.roomdirectory.picker
|
||||
|
||||
import android.widget.TextView
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
|
||||
@EpoxyModelClass(layout = R.layout.item_room_directory_server)
|
||||
abstract class RoomDirectoryServerItem : VectorEpoxyModel<RoomDirectoryServerItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute
|
||||
var serverName: String? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var serverDescription: String? = null
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
holder.nameView.text = serverName
|
||||
holder.descriptionView.setTextOrHide(serverDescription)
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
val nameView by bind<TextView>(R.id.itemRoomDirectoryServerName)
|
||||
val descriptionView by bind<TextView>(R.id.itemRoomDirectoryServerDescription)
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
|
@ -15,23 +14,23 @@
|
|||
android:id="@+id/itemRoomDirectoryAvatar"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginStart="@dimen/layout_horizontal_margin"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:background="@drawable/circle"
|
||||
android:contentDescription="@string/avatar"
|
||||
android:padding="8dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/itemRoomDirectoryBottomSeparator"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
tools:src="@drawable/network_matrix" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/itemRoomDirectoryName"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="@dimen/layout_horizontal_margin"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:maxLines="2"
|
||||
|
@ -49,26 +48,19 @@
|
|||
android:id="@+id/itemRoomDirectoryDescription"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="@dimen/layout_horizontal_margin"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:maxLines="2"
|
||||
android:textColor="?riotx_text_primary"
|
||||
android:textSize="15sp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/itemRoomDirectoryBottomSeparator"
|
||||
android:textSize="14sp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/itemRoomDirectoryAvatar"
|
||||
app:layout_constraintTop_toBottomOf="@id/itemRoomDirectoryName"
|
||||
tools:text="@string/directory_server_all_rooms_on_server" />
|
||||
|
||||
<View
|
||||
android:id="@+id/itemRoomDirectoryBottomSeparator"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="1dp"
|
||||
android:background="?riotx_header_panel_border_mobile"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
tools:text="@string/directory_server_native_rooms"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,48 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?vctr_list_header_background_color"
|
||||
android:minHeight="?listPreferredItemHeight">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/itemRoomDirectoryServerName"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/layout_horizontal_margin"
|
||||
android:layout_marginEnd="@dimen/layout_horizontal_margin"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:maxLines="2"
|
||||
android:textColor="?riotx_text_primary"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toTopOf="@+id/itemRoomDirectoryServerDescription"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/itemRoomDirectoryServerDescription"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/layout_horizontal_margin"
|
||||
android:layout_marginEnd="@dimen/layout_horizontal_margin"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:maxLines="2"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
android:textSize="15sp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/itemRoomDirectoryServerName"
|
||||
tools:text="@string/directory_your_server"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
Loading…
Reference in New Issue