diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index 89a7c466fd..523496e317 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -7,15 +7,6 @@
-
diff --git a/CHANGES.md b/CHANGES.md
index 569467b156..89121bdf54 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -11,6 +11,7 @@ Improvements 🙌:
- Improve file too big error detection (#3245)
- User can now select video when selecting Gallery to send attachments to a room
- Add option to record a video from the camera
+ - Add the public icon on the rooms in the room list (#3292)
Bugfix 🐛:
- Message states cosmetic changes (#3007)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomSummary.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomSummary.kt
index d324cff246..cae4775e71 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomSummary.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomSummary.kt
@@ -26,7 +26,7 @@ import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
* This class holds some data of a room.
* It can be retrieved by [org.matrix.android.sdk.api.session.room.Room] and [org.matrix.android.sdk.api.session.room.RoomService]
*/
-data class RoomSummary constructor(
+data class RoomSummary(
val roomId: String,
// Computed display name
val displayName: String = "",
@@ -35,6 +35,7 @@ data class RoomSummary constructor(
val avatarUrl: String = "",
val canonicalAlias: String? = null,
val aliases: List = emptyList(),
+ val joinRules: RoomJoinRules? = null,
val isDirect: Boolean = false,
val directUserId: String? = null,
val joinedMembersCount: Int? = 0,
@@ -74,6 +75,9 @@ data class RoomSummary constructor(
val isFavorite: Boolean
get() = hasTag(RoomTag.ROOM_TAG_FAVOURITE)
+ val isPublic: Boolean
+ get() = joinRules == RoomJoinRules.PUBLIC
+
fun hasTag(tag: String) = tags.any { it.name == tag }
val canStartCall: Boolean
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt
index 8770dc8b33..906a6d14d6 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt
@@ -20,6 +20,7 @@ import io.realm.DynamicRealm
import io.realm.FieldAttribute
import io.realm.RealmMigration
import org.matrix.android.sdk.api.session.events.model.EventType
+import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesContent
import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent
import org.matrix.android.sdk.api.session.room.model.tag.RoomTag
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFields
@@ -33,9 +34,9 @@ import org.matrix.android.sdk.internal.database.model.RoomEntityFields
import org.matrix.android.sdk.internal.database.model.RoomMembersLoadStatusType
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
import org.matrix.android.sdk.internal.database.model.RoomTagEntityFields
-import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
import org.matrix.android.sdk.internal.database.model.SpaceChildSummaryEntityFields
import org.matrix.android.sdk.internal.database.model.SpaceParentSummaryEntityFields
+import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
import org.matrix.android.sdk.internal.di.MoshiProvider
import timber.log.Timber
import javax.inject.Inject
@@ -43,7 +44,7 @@ import javax.inject.Inject
class RealmSessionStoreMigration @Inject constructor() : RealmMigration {
companion object {
- const val SESSION_STORE_SCHEMA_VERSION = 11L
+ const val SESSION_STORE_SCHEMA_VERSION = 12L
}
override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) {
@@ -60,6 +61,7 @@ class RealmSessionStoreMigration @Inject constructor() : RealmMigration {
if (oldVersion <= 8) migrateTo9(realm)
if (oldVersion <= 9) migrateTo10(realm)
if (oldVersion <= 10) migrateTo11(realm)
+ if (oldVersion <= 11) migrateTo12(realm)
}
private fun migrateTo1(realm: DynamicRealm) {
@@ -247,4 +249,25 @@ class RealmSessionStoreMigration @Inject constructor() : RealmMigration {
realm.schema.get("EventEntity")
?.addField(EventEntityFields.SEND_STATE_DETAILS, String::class.java)
}
+
+ private fun migrateTo12(realm: DynamicRealm) {
+ Timber.d("Step 11 -> 12")
+
+ val joinRulesContentAdapter = MoshiProvider.providesMoshi().adapter(RoomJoinRulesContent::class.java)
+ realm.schema.get("RoomSummaryEntity")
+ ?.addField(RoomSummaryEntityFields.JOIN_RULES_STR, String::class.java)
+ ?.transform { obj ->
+ val joinRulesEvent = realm.where("CurrentStateEventEntity")
+ .equalTo(CurrentStateEventEntityFields.ROOM_ID, obj.getString(RoomSummaryEntityFields.ROOM_ID))
+ .equalTo(CurrentStateEventEntityFields.TYPE, EventType.STATE_ROOM_JOIN_RULES)
+ .findFirst()
+
+ val roomJoinRules = joinRulesEvent?.getObject(CurrentStateEventEntityFields.ROOT.`$`)
+ ?.getString(EventEntityFields.CONTENT)?.let {
+ joinRulesContentAdapter.fromJson(it)?.joinRules
+ }
+
+ obj.setString(RoomSummaryEntityFields.JOIN_RULES_STR, roomJoinRules?.name)
+ }
+ }
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/RoomSummaryMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/RoomSummaryMapper.kt
index 92aff0a140..0b057ec6fc 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/RoomSummaryMapper.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/RoomSummaryMapper.kt
@@ -44,6 +44,7 @@ internal class RoomSummaryMapper @Inject constructor(private val timelineEventMa
name = roomSummaryEntity.name ?: "",
topic = roomSummaryEntity.topic ?: "",
avatarUrl = roomSummaryEntity.avatarUrl ?: "",
+ joinRules = roomSummaryEntity.joinRules,
isDirect = roomSummaryEntity.isDirect,
directUserId = roomSummaryEntity.directUserId,
latestPreviewableEvent = latestEvent,
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt
index 4f47032c4d..1001f9cd66 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt
@@ -21,7 +21,9 @@ import io.realm.RealmObject
import io.realm.annotations.Index
import io.realm.annotations.PrimaryKey
import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel
+import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.session.room.model.Membership
+import org.matrix.android.sdk.api.session.room.model.RoomJoinRules
import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.api.session.room.model.VersioningState
import org.matrix.android.sdk.api.session.room.model.tag.RoomTag
@@ -242,6 +244,19 @@ internal open class RoomSummaryEntity(
}
}
+ private var joinRulesStr: String? = null
+ var joinRules: RoomJoinRules?
+ get() {
+ return joinRulesStr?.let {
+ tryOrNull { RoomJoinRules.valueOf(it) }
+ }
+ }
+ set(value) {
+ if (value?.name != joinRulesStr) {
+ joinRulesStr = value?.name
+ }
+ }
+
var roomEncryptionTrustLevel: RoomEncryptionTrustLevel?
get() {
return roomEncryptionTrustLevelStr?.let {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt
index f580a7f354..63fcb557a8 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt
@@ -24,6 +24,7 @@ import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.api.session.room.model.RoomAliasesContent
import org.matrix.android.sdk.api.session.room.model.RoomCanonicalAliasContent
+import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesContent
import org.matrix.android.sdk.api.session.room.model.RoomNameContent
import org.matrix.android.sdk.api.session.room.model.RoomTopicContent
import org.matrix.android.sdk.api.session.room.model.RoomType
@@ -104,6 +105,7 @@ internal class RoomSummaryUpdater @Inject constructor(
val lastCanonicalAliasEvent = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_CANONICAL_ALIAS, stateKey = "")?.root
val lastAliasesEvent = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_ALIASES, stateKey = "")?.root
val roomCreateEvent = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_CREATE, stateKey = "")?.root
+ val joinRulesEvent = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_JOIN_RULES, stateKey = "")?.root
val roomType = ContentMapper.map(roomCreateEvent?.content).toModel()?.type
roomSummaryEntity.roomType = roomType
@@ -130,6 +132,7 @@ internal class RoomSummaryUpdater @Inject constructor(
roomSummaryEntity.avatarUrl = roomAvatarResolver.resolve(realm, roomId)
roomSummaryEntity.name = ContentMapper.map(lastNameEvent?.content).toModel()?.name
roomSummaryEntity.topic = ContentMapper.map(lastTopicEvent?.content).toModel()?.topic
+ roomSummaryEntity.joinRules = ContentMapper.map(joinRulesEvent?.content).toModel()?.joinRules
roomSummaryEntity.latestPreviewableEvent = latestPreviewableEvent
roomSummaryEntity.canonicalAlias = ContentMapper.map(lastCanonicalAliasEvent?.content).toModel()
?.canonicalAlias
diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt
index 06f55d3952..d099ac16b7 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt
@@ -50,6 +50,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel() {
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) lateinit var lastFormattedEvent: CharSequence
@EpoxyAttribute lateinit var lastEventTime: CharSequence
@EpoxyAttribute var encryptionTrustLevel: RoomEncryptionTrustLevel? = null
+ @EpoxyAttribute var izPublic: Boolean = false
@EpoxyAttribute var unreadNotificationCount: Int = 0
@EpoxyAttribute var hasUnreadMessage: Boolean = false
@EpoxyAttribute var hasDraft: Boolean = false
@@ -74,6 +75,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel() {
holder.draftView.isVisible = hasDraft
avatarRenderer.render(matrixItem, holder.avatarImageView)
holder.roomAvatarDecorationImageView.render(encryptionTrustLevel)
+ holder.roomAvatarPublicDecorationImageView.isVisible = izPublic
holder.roomAvatarFailSendingImageView.isVisible = hasFailedSending
renderSelection(holder, showSelected)
holder.typingView.setTextOrHide(typingMessage)
@@ -110,6 +112,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel() {
val avatarCheckedImageView by bind(R.id.roomAvatarCheckedImageView)
val avatarImageView by bind(R.id.roomAvatarImageView)
val roomAvatarDecorationImageView by bind(R.id.roomAvatarDecorationImageView)
+ val roomAvatarPublicDecorationImageView by bind(R.id.roomAvatarPublicDecorationImageView)
val roomAvatarFailSendingImageView by bind(R.id.roomAvatarFailSendingImageView)
val rootView by bind(R.id.itemRoomLayout)
}
diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt
index 283ed0ac85..e4826af04c 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt
@@ -112,6 +112,7 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor
.avatarRenderer(avatarRenderer)
// We do not display shield in the room list anymore
// .encryptionTrustLevel(roomSummary.roomEncryptionTrustLevel)
+ .izPublic(roomSummary.isPublic)
.matrixItem(roomSummary.toMatrixItem())
.lastEventTime(latestEventTime)
.typingMessage(typingMessage)
diff --git a/vector/src/main/res/drawable/background_circle.xml b/vector/src/main/res/drawable/background_circle.xml
new file mode 100644
index 0000000000..5e20ad45ce
--- /dev/null
+++ b/vector/src/main/res/drawable/background_circle.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/vector/src/main/res/drawable/ic_public_room.xml b/vector/src/main/res/drawable/ic_public_room.xml
index 1520898831..d6602cc59c 100644
--- a/vector/src/main/res/drawable/ic_public_room.xml
+++ b/vector/src/main/res/drawable/ic_public_room.xml
@@ -1,13 +1,11 @@
-
-
+ android:width="21dp"
+ android:height="20dp"
+ android:viewportWidth="21"
+ android:viewportHeight="20">
+
+
diff --git a/vector/src/main/res/layout/item_room.xml b/vector/src/main/res/layout/item_room.xml
index 4e20d270cd..872cf3e400 100644
--- a/vector/src/main/res/layout/item_room.xml
+++ b/vector/src/main/res/layout/item_room.xml
@@ -60,6 +60,7 @@
app:layout_constraintCircleRadius="30dp"
tools:ignore="MissingConstraints" />
+
+ tools:ignore="MissingConstraints"
+ tools:visibility="gone" />
+
+
Notify without sound
Do not notify
View read receipts
+ This room is public
Dev Tools
Explore Room State