mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-21 17:05:39 +03:00
Room list : handle direct rooms
This commit is contained in:
parent
ec27951850
commit
bc8055c3cd
20 changed files with 351 additions and 43 deletions
Binary file not shown.
|
@ -1,16 +1,30 @@
|
|||
package im.vector.riotredesign.features.home.room.list
|
||||
|
||||
import android.support.annotation.DrawableRes
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import im.vector.riotredesign.R
|
||||
import im.vector.riotredesign.core.epoxy.KotlinModel
|
||||
|
||||
data class RoomCategoryItem(
|
||||
val title: CharSequence,
|
||||
@DrawableRes val expandDrawable: Int,
|
||||
val isExpanded: Boolean,
|
||||
val listener: (() -> Unit)? = null
|
||||
) : KotlinModel(R.layout.item_room_category) {
|
||||
|
||||
override fun bind() {
|
||||
private val titleView by bind<TextView>(R.id.roomCategoryTitleView)
|
||||
private val rootView by bind<ViewGroup>(R.id.roomCategoryRootView)
|
||||
|
||||
private val tintColor by lazy {
|
||||
ContextCompat.getColor(rootView.context, R.color.bluey_grey_two)
|
||||
}
|
||||
|
||||
override fun bind() {
|
||||
val expandedArrowDrawableRes = if (isExpanded) R.drawable.ic_expand_more_white else R.drawable.ic_expand_less_white
|
||||
val expandedArrowDrawable = ContextCompat.getDrawable(rootView.context, expandedArrowDrawableRes)
|
||||
expandedArrowDrawable?.setTint(tintColor)
|
||||
titleView.setCompoundDrawablesWithIntrinsicBounds(expandedArrowDrawable, null, null, null)
|
||||
titleView.text = title
|
||||
rootView.setOnClickListener { listener?.invoke() }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,15 +10,49 @@ class RoomSummaryController(private val context: Context,
|
|||
private val callback: Callback? = null
|
||||
) : Typed2EpoxyController<List<RoomSummary>, RoomSummary>() {
|
||||
|
||||
|
||||
private var directRoomsExpanded = true
|
||||
private var groupRoomsExpanded = true
|
||||
|
||||
override fun buildModels(summaries: List<RoomSummary>?, selected: RoomSummary?) {
|
||||
|
||||
val directRooms = summaries?.filter { it.isDirect } ?: emptyList()
|
||||
val groupRooms = summaries?.filter { !it.isDirect } ?: emptyList()
|
||||
|
||||
RoomCategoryItem(
|
||||
title = "DIRECT MESSAGES",
|
||||
expandDrawable = R.drawable.ic_expand_more_white
|
||||
isExpanded = directRoomsExpanded,
|
||||
listener = {
|
||||
directRoomsExpanded = !directRoomsExpanded
|
||||
setData(summaries, selected)
|
||||
}
|
||||
)
|
||||
.id("direct_messages")
|
||||
.addTo(this)
|
||||
|
||||
summaries?.forEach {
|
||||
if (directRoomsExpanded) {
|
||||
buildRoomModels(directRooms, selected)
|
||||
}
|
||||
|
||||
RoomCategoryItem(
|
||||
title = "GROUPS",
|
||||
isExpanded = groupRoomsExpanded,
|
||||
listener = {
|
||||
groupRoomsExpanded = !groupRoomsExpanded
|
||||
setData(summaries, selected)
|
||||
}
|
||||
)
|
||||
.id("group_messages")
|
||||
.addTo(this)
|
||||
|
||||
if (groupRoomsExpanded) {
|
||||
buildRoomModels(groupRooms, selected)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun buildRoomModels(summaries: List<RoomSummary>, selected: RoomSummary?) {
|
||||
summaries.forEach {
|
||||
val roomSummaryViewHelper = RoomSummaryViewHelper(it)
|
||||
RoomSummaryItem(
|
||||
title = it.displayName,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:id="@+id/roomCategoryRootView"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="24dp"
|
||||
android:padding="16dp"
|
||||
|
|
|
@ -4,5 +4,6 @@ data class RoomSummary(
|
|||
val roomId: String,
|
||||
val displayName: String = "",
|
||||
val topic: String = "",
|
||||
val avatarUrl: String = ""
|
||||
val avatarUrl: String = "",
|
||||
val isDirect: Boolean
|
||||
)
|
|
@ -11,24 +11,12 @@ object RoomSummaryMapper {
|
|||
roomSummaryEntity.roomId,
|
||||
roomSummaryEntity.displayName ?: "",
|
||||
roomSummaryEntity.topic ?: "",
|
||||
roomSummaryEntity.avatarUrl ?: ""
|
||||
)
|
||||
}
|
||||
|
||||
internal fun map(roomSummary: RoomSummary): RoomSummaryEntity {
|
||||
return RoomSummaryEntity(
|
||||
roomSummary.roomId,
|
||||
roomSummary.displayName,
|
||||
roomSummary.topic,
|
||||
roomSummary.avatarUrl
|
||||
roomSummaryEntity.avatarUrl ?: "",
|
||||
roomSummaryEntity.isDirect
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun RoomSummaryEntity.asDomain(): RoomSummary {
|
||||
return RoomSummaryMapper.map(this)
|
||||
}
|
||||
|
||||
fun RoomSummaryEntity.asEntity(): RoomSummary {
|
||||
return RoomSummaryMapper.map(this)
|
||||
}
|
|
@ -4,7 +4,6 @@ import io.realm.RealmList
|
|||
import io.realm.RealmObject
|
||||
import io.realm.annotations.PrimaryKey
|
||||
|
||||
// TODO to be completed
|
||||
open class RoomSummaryEntity(@PrimaryKey var roomId: String = "",
|
||||
var displayName: String? = "",
|
||||
var avatarUrl: String? = "",
|
||||
|
@ -13,6 +12,7 @@ open class RoomSummaryEntity(@PrimaryKey var roomId: String = "",
|
|||
var heroes: RealmList<String> = RealmList(),
|
||||
var joinedMembersCount: Int? = 0,
|
||||
var invitedMembersCount: Int? = 0,
|
||||
var isDirect: Boolean = false,
|
||||
var isLatestSelected: Boolean = false
|
||||
) : RealmObject() {
|
||||
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
package im.vector.matrix.android.internal.di
|
||||
|
||||
import com.squareup.moshi.Moshi
|
||||
import im.vector.matrix.android.internal.network.parsing.RuntimeJsonAdapterFactory
|
||||
import im.vector.matrix.android.internal.network.parsing.UriMoshiAdapter
|
||||
import im.vector.matrix.android.internal.session.sync.model.UserAccountData
|
||||
import im.vector.matrix.android.internal.session.sync.model.UserAccountDataDirectMessages
|
||||
import im.vector.matrix.android.internal.session.sync.model.UserAccountDataFallback
|
||||
|
||||
object MoshiProvider {
|
||||
|
||||
private val moshi: Moshi = Moshi.Builder()
|
||||
.add(UriMoshiAdapter())
|
||||
.add(RuntimeJsonAdapterFactory.of(UserAccountData::class.java, "type", UserAccountDataFallback::class.java)
|
||||
.registerSubtype(UserAccountDataDirectMessages::class.java, UserAccountData.TYPE_DIRECT_MESSAGES)
|
||||
)
|
||||
.build()
|
||||
|
||||
fun providesMoshi(): Moshi {
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Copyright (C) 2011 Google Inc.
|
||||
*
|
||||
* 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.matrix.android.internal.network.parsing;
|
||||
|
||||
import com.squareup.moshi.JsonAdapter;
|
||||
import com.squareup.moshi.JsonDataException;
|
||||
import com.squareup.moshi.JsonReader;
|
||||
import com.squareup.moshi.JsonWriter;
|
||||
import com.squareup.moshi.Moshi;
|
||||
import com.squareup.moshi.Types;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.CheckReturnValue;
|
||||
|
||||
/**
|
||||
* A JsonAdapter factory for polymorphic types. This is useful when the type is not known before
|
||||
* decoding the JSON. This factory's adapters expect JSON in the format of a JSON object with a
|
||||
* key whose value is a label that determines the type to which to map the JSON object.
|
||||
*/
|
||||
public final class RuntimeJsonAdapterFactory<T> implements JsonAdapter.Factory {
|
||||
final Class<T> baseType;
|
||||
final String labelKey;
|
||||
final Class fallbackType;
|
||||
final Map<String, Type> labelToType = new LinkedHashMap<>();
|
||||
|
||||
/**
|
||||
* @param baseType The base type for which this factory will create adapters. Cannot be Object.
|
||||
* @param labelKey The key in the JSON object whose value determines the type to which to map the
|
||||
* JSON object.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public static <T> RuntimeJsonAdapterFactory<T> of(Class<T> baseType, String labelKey, Class<? extends T> fallbackType) {
|
||||
if (baseType == null) throw new NullPointerException("baseType == null");
|
||||
if (labelKey == null) throw new NullPointerException("labelKey == null");
|
||||
if (baseType == Object.class) {
|
||||
throw new IllegalArgumentException(
|
||||
"The base type must not be Object. Consider using a marker interface.");
|
||||
}
|
||||
return new RuntimeJsonAdapterFactory<>(baseType, labelKey, fallbackType);
|
||||
}
|
||||
|
||||
RuntimeJsonAdapterFactory(Class<T> baseType, String labelKey, Class fallbackType) {
|
||||
this.baseType = baseType;
|
||||
this.labelKey = labelKey;
|
||||
this.fallbackType = fallbackType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the subtype that can be created based on the label. When an unknown type is found
|
||||
* during encoding an {@linkplain IllegalArgumentException} will be thrown. When an unknown label
|
||||
* is found during decoding a {@linkplain JsonDataException} will be thrown.
|
||||
*/
|
||||
public RuntimeJsonAdapterFactory<T> registerSubtype(Class<? extends T> subtype, String label) {
|
||||
if (subtype == null) throw new NullPointerException("subtype == null");
|
||||
if (label == null) throw new NullPointerException("label == null");
|
||||
if (labelToType.containsKey(label) || labelToType.containsValue(subtype)) {
|
||||
throw new IllegalArgumentException("Subtypes and labels must be unique.");
|
||||
}
|
||||
labelToType.put(label, subtype);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations, Moshi moshi) {
|
||||
if (Types.getRawType(type) != baseType || !annotations.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
int size = labelToType.size();
|
||||
Map<String, JsonAdapter<Object>> labelToAdapter = new LinkedHashMap<>(size);
|
||||
Map<Type, String> typeToLabel = new LinkedHashMap<>(size);
|
||||
for (Map.Entry<String, Type> entry : labelToType.entrySet()) {
|
||||
String label = entry.getKey();
|
||||
Type typeValue = entry.getValue();
|
||||
typeToLabel.put(typeValue, label);
|
||||
labelToAdapter.put(label, moshi.adapter(typeValue));
|
||||
}
|
||||
|
||||
final JsonAdapter<Object> fallbackAdapter = moshi.adapter(fallbackType);
|
||||
JsonAdapter<Object> objectJsonAdapter = moshi.adapter(Object.class);
|
||||
|
||||
return new RuntimeJsonAdapter(labelKey, labelToAdapter, typeToLabel,
|
||||
objectJsonAdapter, fallbackAdapter).nullSafe();
|
||||
}
|
||||
|
||||
static final class RuntimeJsonAdapter extends JsonAdapter<Object> {
|
||||
final String labelKey;
|
||||
final Map<String, JsonAdapter<Object>> labelToAdapter;
|
||||
final Map<Type, String> typeToLabel;
|
||||
final JsonAdapter<Object> objectJsonAdapter;
|
||||
final JsonAdapter<Object> fallbackAdapter;
|
||||
|
||||
RuntimeJsonAdapter(String labelKey, Map<String, JsonAdapter<Object>> labelToAdapter,
|
||||
Map<Type, String> typeToLabel, JsonAdapter<Object> objectJsonAdapter,
|
||||
JsonAdapter<Object> fallbackAdapter) {
|
||||
this.labelKey = labelKey;
|
||||
this.labelToAdapter = labelToAdapter;
|
||||
this.typeToLabel = typeToLabel;
|
||||
this.objectJsonAdapter = objectJsonAdapter;
|
||||
this.fallbackAdapter = fallbackAdapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object fromJson(JsonReader reader) throws IOException {
|
||||
JsonReader.Token peekedToken = reader.peek();
|
||||
if (peekedToken != JsonReader.Token.BEGIN_OBJECT) {
|
||||
throw new JsonDataException("Expected BEGIN_OBJECT but was " + peekedToken
|
||||
+ " at path " + reader.getPath());
|
||||
}
|
||||
Object jsonValue = reader.readJsonValue();
|
||||
Map<String, Object> jsonObject = (Map<String, Object>) jsonValue;
|
||||
Object label = jsonObject.get(labelKey);
|
||||
if (label == null) {
|
||||
throw new JsonDataException("Missing label for " + labelKey);
|
||||
}
|
||||
if (!(label instanceof String)) {
|
||||
throw new JsonDataException("Label for '"
|
||||
+ labelKey
|
||||
+ "' must be a string but was "
|
||||
+ label
|
||||
+ ", a "
|
||||
+ label.getClass());
|
||||
}
|
||||
JsonAdapter<Object> adapter = labelToAdapter.get(label);
|
||||
if (adapter == null) {
|
||||
return fallbackAdapter.fromJsonValue(jsonValue);
|
||||
}
|
||||
return adapter.fromJsonValue(jsonValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toJson(JsonWriter writer, Object value) throws IOException {
|
||||
Class<?> type = value.getClass();
|
||||
String label = typeToLabel.get(type);
|
||||
if (label == null) {
|
||||
throw new IllegalArgumentException("Expected one of "
|
||||
+ typeToLabel.keySet()
|
||||
+ " but found "
|
||||
+ value
|
||||
+ ", a "
|
||||
+ value.getClass()
|
||||
+ ". Register this subtype.");
|
||||
}
|
||||
JsonAdapter<Object> adapter = labelToAdapter.get(label);
|
||||
Map<String, Object> jsonValue = (Map<String, Object>) adapter.toJsonValue(value);
|
||||
|
||||
Map<String, Object> valueWithLabel = new LinkedHashMap<>(1 + jsonValue.size());
|
||||
valueWithLabel.put(labelKey, label);
|
||||
valueWithLabel.putAll(jsonValue);
|
||||
objectJsonAdapter.toJson(writer, valueWithLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RuntimeJsonAdapter(" + labelKey + ")";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@ import im.vector.matrix.android.api.util.Cancelable
|
|||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||
import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
|
||||
import im.vector.matrix.android.internal.database.model.RoomSummaryEntityFields
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.session.room.members.LoadRoomMembersRequest
|
||||
import im.vector.matrix.android.internal.session.sync.SyncTokenStore
|
||||
|
@ -36,7 +37,7 @@ data class DefaultRoom(
|
|||
override val roomSummary: LiveData<RoomSummary> by lazy {
|
||||
val liveData = monarchy
|
||||
.findAllMappedWithChanges(
|
||||
{ realm -> RoomSummaryEntity.where(realm, roomId) },
|
||||
{ realm -> RoomSummaryEntity.where(realm, roomId).isNotEmpty(RoomSummaryEntityFields.DISPLAY_NAME) },
|
||||
{ from -> from.asDomain() })
|
||||
|
||||
Transformations.map(liveData) {
|
||||
|
|
|
@ -8,6 +8,7 @@ import im.vector.matrix.android.api.session.room.model.RoomSummary
|
|||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||
import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
|
||||
import im.vector.matrix.android.internal.database.model.RoomSummaryEntityFields
|
||||
import im.vector.matrix.android.internal.database.query.lastSelected
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
|
||||
|
@ -38,7 +39,7 @@ class DefaultRoomService(private val monarchy: Monarchy) : RoomService {
|
|||
|
||||
override fun liveRoomSummaries(): LiveData<List<RoomSummary>> {
|
||||
return monarchy.findAllMappedWithChanges(
|
||||
{ realm -> RoomSummaryEntity.where(realm) },
|
||||
{ realm -> RoomSummaryEntity.where(realm).isNotEmpty(RoomSummaryEntityFields.DISPLAY_NAME) },
|
||||
{ it.asDomain() }
|
||||
)
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import im.vector.matrix.android.internal.session.sync.model.InvitedRoomSync
|
|||
import im.vector.matrix.android.internal.session.sync.model.RoomSync
|
||||
import im.vector.matrix.android.internal.session.sync.model.RoomSyncEphemeral
|
||||
import im.vector.matrix.android.internal.session.sync.model.RoomSyncSummary
|
||||
import im.vector.matrix.android.internal.session.sync.model.RoomsSyncResponse
|
||||
import io.realm.Realm
|
||||
import io.realm.kotlin.createObject
|
||||
|
||||
|
@ -29,7 +30,21 @@ internal class RoomSyncHandler(private val monarchy: Monarchy,
|
|||
data class LEFT(val data: Map<String, RoomSync>) : HandlingStrategy()
|
||||
}
|
||||
|
||||
fun handleRoomSync(handlingStrategy: HandlingStrategy) {
|
||||
fun handle(roomsSyncResponse: RoomsSyncResponse) {
|
||||
handleRoomSync(RoomSyncHandler.HandlingStrategy.JOINED(roomsSyncResponse.join))
|
||||
handleRoomSync(RoomSyncHandler.HandlingStrategy.INVITED(roomsSyncResponse.invite))
|
||||
handleRoomSync(RoomSyncHandler.HandlingStrategy.LEFT(roomsSyncResponse.leave))
|
||||
|
||||
monarchy.runTransactionSync { realm ->
|
||||
roomsSyncResponse.join.forEach { (roomId, roomSync) ->
|
||||
handleEphemeral(realm, roomId, roomSync.ephemeral)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PRIVATE METHODS *****************************************************************************
|
||||
|
||||
private fun handleRoomSync(handlingStrategy: HandlingStrategy) {
|
||||
monarchy.runTransactionSync { realm ->
|
||||
val rooms = when (handlingStrategy) {
|
||||
is HandlingStrategy.JOINED -> handlingStrategy.data.map { handleJoinedRoom(realm, it.key, it.value) }
|
||||
|
@ -38,18 +53,8 @@ internal class RoomSyncHandler(private val monarchy: Monarchy,
|
|||
}
|
||||
realm.insertOrUpdate(rooms)
|
||||
}
|
||||
|
||||
if (handlingStrategy is HandlingStrategy.JOINED) {
|
||||
monarchy.runTransactionSync { realm ->
|
||||
handlingStrategy.data.forEach { (roomId, roomSync) ->
|
||||
handleEphemeral(realm, roomId, roomSync.ephemeral)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PRIVATE METHODS *****************************************************************************
|
||||
|
||||
private fun handleJoinedRoom(realm: Realm,
|
||||
roomId: String,
|
||||
roomSync: RoomSync): RoomEntity {
|
||||
|
|
|
@ -30,7 +30,11 @@ class SyncModule : Module {
|
|||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
SyncResponseHandler(get())
|
||||
UserAccountDataSyncHandler(get())
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
SyncResponseHandler(get(), get())
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
|
|
|
@ -3,21 +3,20 @@ package im.vector.matrix.android.internal.session.sync
|
|||
import im.vector.matrix.android.internal.session.sync.model.SyncResponse
|
||||
import timber.log.Timber
|
||||
|
||||
internal class SyncResponseHandler(private val roomSyncHandler: RoomSyncHandler) {
|
||||
internal class SyncResponseHandler(private val roomSyncHandler: RoomSyncHandler,
|
||||
private val userAccountDataSyncHandler: UserAccountDataSyncHandler) {
|
||||
|
||||
fun handleResponse(syncResponse: SyncResponse?, fromToken: String?, isCatchingUp: Boolean) {
|
||||
if (syncResponse == null) {
|
||||
return
|
||||
}
|
||||
Timber.v("Handle sync response")
|
||||
|
||||
if (syncResponse.rooms != null) {
|
||||
// joined rooms events
|
||||
roomSyncHandler.handleRoomSync(RoomSyncHandler.HandlingStrategy.JOINED(syncResponse.rooms.join))
|
||||
roomSyncHandler.handleRoomSync(RoomSyncHandler.HandlingStrategy.INVITED(syncResponse.rooms.invite))
|
||||
roomSyncHandler.handleRoomSync(RoomSyncHandler.HandlingStrategy.LEFT(syncResponse.rooms.leave))
|
||||
roomSyncHandler.handle(syncResponse.rooms)
|
||||
}
|
||||
if (syncResponse.accountData != null) {
|
||||
userAccountDataSyncHandler.handle(syncResponse.accountData)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package im.vector.matrix.android.internal.session.sync
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
|
||||
import im.vector.matrix.android.internal.database.model.RoomSummaryEntityFields
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.session.sync.model.UserAccountDataDirectMessages
|
||||
import im.vector.matrix.android.internal.session.sync.model.UserAccountDataSync
|
||||
|
||||
class UserAccountDataSyncHandler(private val monarchy: Monarchy) {
|
||||
|
||||
fun handle(accountData: UserAccountDataSync) {
|
||||
accountData.list.forEach {
|
||||
when (it) {
|
||||
is UserAccountDataDirectMessages -> handleDirectChatRooms(it)
|
||||
else -> return@forEach
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleDirectChatRooms(directMessages: UserAccountDataDirectMessages) {
|
||||
val newDirectRoomIds = directMessages.content.values.flatten()
|
||||
monarchy.runTransactionSync { realm ->
|
||||
|
||||
val oldDirectRooms = RoomSummaryEntity.where(realm).equalTo(RoomSummaryEntityFields.IS_DIRECT, true).findAll()
|
||||
oldDirectRooms.forEach { it.isDirect = false }
|
||||
|
||||
newDirectRoomIds.forEach { roomId ->
|
||||
val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst()
|
||||
if (roomSummaryEntity != null) {
|
||||
roomSummaryEntity.isDirect = true
|
||||
realm.insertOrUpdate(roomSummaryEntity)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@ data class SyncResponse(
|
|||
/**
|
||||
* The user private data.
|
||||
*/
|
||||
@Json(name = "account_data") val accountData: Map<String, Any>? = emptyMap(),
|
||||
@Json(name = "account_data") val accountData: UserAccountDataSync? = null,
|
||||
|
||||
/**
|
||||
* The opaque token for the end.
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package im.vector.matrix.android.internal.session.sync.model
|
||||
|
||||
interface UserAccountData {
|
||||
|
||||
companion object {
|
||||
const val TYPE_IGNORED_USER_LIST = "m.ignored_user_list"
|
||||
const val TYPE_DIRECT_MESSAGES = "m.direct"
|
||||
const val TYPE_PREVIEW_URLS = "org.matrix.preview_urls"
|
||||
const val TYPE_WIDGETS = "m.widgets"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package im.vector.matrix.android.internal.session.sync.model
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class UserAccountDataDirectMessages(
|
||||
@Json(name = "content") val content: Map<String, List<String>>
|
||||
) : UserAccountData
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package im.vector.matrix.android.internal.session.sync.model
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class UserAccountDataFallback(
|
||||
@Json(name = "content") val content: Map<String, Any>
|
||||
) : UserAccountData
|
|
@ -0,0 +1,9 @@
|
|||
package im.vector.matrix.android.internal.session.sync.model
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class UserAccountDataSync(
|
||||
@Json(name = "events") val list: List<UserAccountData> = emptyList()
|
||||
)
|
Loading…
Reference in a new issue