From 72251d1e58e9825eef818877be97c4451d7953e3 Mon Sep 17 00:00:00 2001 From: Mario Danic Date: Sun, 29 Dec 2019 01:25:33 +0100 Subject: [PATCH] Fix issue with storing participants list --- app/build.gradle | 8 ++- .../1.json | 14 ++-- .../models/json/conversations/Conversation.kt | 2 +- .../EnumParticipantFlagsConverter.kt | 36 +++++++++++ .../EnumParticipantTypeConverter.java | 8 ++- .../models/json/participants/Participant.java | 64 +++++++++++-------- .../converters/ParticipantMapConverter.kt | 48 ++++++++++++++ .../converters/ParticipantTypeConverter.kt | 11 +--- .../talk/newarch/local/db/TalkDatabase.kt | 2 +- .../local/models/ConversationEntity.kt | 17 ++--- build.gradle | 1 + 11 files changed, 148 insertions(+), 63 deletions(-) create mode 100644 app/src/main/java/com/nextcloud/talk/models/json/converters/EnumParticipantFlagsConverter.kt create mode 100644 app/src/main/java/com/nextcloud/talk/newarch/local/converters/ParticipantMapConverter.kt diff --git a/app/build.gradle b/app/build.gradle index bbc65715d..e74118c69 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -23,6 +23,7 @@ apply plugin: 'findbugs' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' +apply plugin: 'kotlinx-serialization' def taskRequest = getGradle().getStartParameter().getTaskRequests().toString() if (taskRequest.contains("Gplay") || taskRequest.contains("findbugs") || @@ -160,7 +161,7 @@ ext { koin_version = "2.1.0-alpha-1" lifecycle_version = "2.2.0-rc01" coil_version = "0.8.0" - room_version = "2.2.2" + room_version = "2.2.3" } configurations.all { @@ -173,6 +174,7 @@ dependencies { implementation fileTree(include: ['*'], dir: 'libs') implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" + implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.14.0" // JVM dependency // Koin for Android implementation "org.koin:koin-android:$koin_version" // Koin AndroidX Scope features @@ -227,8 +229,8 @@ dependencies { androidTestImplementation "androidx.work:work-testing:$work_version" implementation 'androidx.appcompat:appcompat:1.1.0' - implementation 'com.google.android.material:material:1.2.0-alpha02' - implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta3' + implementation 'com.google.android.material:material:1.2.0-alpha03' + implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta4' implementation 'com.github.vanniktech:Emoji:0.6.0' implementation group: 'androidx.emoji', name: 'emoji-bundled', version: '1.0.0' implementation 'org.michaelevans.colorart:library:0.0.3' diff --git a/app/schemas/com.nextcloud.talk.newarch.local.db.TalkDatabase/1.json b/app/schemas/com.nextcloud.talk.newarch.local.db.TalkDatabase/1.json index 40088fe66..f63b80b4e 100644 --- a/app/schemas/com.nextcloud.talk.newarch.local.db.TalkDatabase/1.json +++ b/app/schemas/com.nextcloud.talk.newarch.local.db.TalkDatabase/1.json @@ -2,11 +2,11 @@ "formatVersion": 1, "database": { "version": 1, - "identityHash": "3a9126341dd46ffc54056126b59ed5fb", + "identityHash": "2c4f372b48cd11e679b04c6d577f1cd8", "entities": [ { "tableName": "conversations", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `user_id` INTEGER, `conversation_id` TEXT, `token` TEXT, `name` TEXT, `display_name` TEXT, `type` INTEGER, `count` INTEGER NOT NULL, `number_of_guests` INTEGER NOT NULL, `participants_count` INTEGER NOT NULL, `participant_type` INTEGER, `has_password` INTEGER NOT NULL, `session_id` TEXT, `favorite` INTEGER NOT NULL, `last_activity` INTEGER NOT NULL, `unread_messages` INTEGER NOT NULL, `unread_mention` INTEGER NOT NULL, `last_message` TEXT, `object_type` TEXT, `notification_level` INTEGER, `read_only_state` INTEGER, `lobby_state` INTEGER, `lobby_timer` INTEGER, `last_read_message` INTEGER NOT NULL, `can_start_call` INTEGER, `modified_at` INTEGER, `changing` INTEGER NOT NULL, PRIMARY KEY(`id`), FOREIGN KEY(`user_id`) REFERENCES `users`(`id`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `user_id` INTEGER, `conversation_id` TEXT, `token` TEXT, `name` TEXT, `display_name` TEXT, `type` INTEGER, `count` INTEGER NOT NULL, `number_of_guests` INTEGER NOT NULL, `participants` TEXT, `participant_type` INTEGER, `has_password` INTEGER NOT NULL, `session_id` TEXT, `favorite` INTEGER NOT NULL, `last_activity` INTEGER NOT NULL, `unread_messages` INTEGER NOT NULL, `unread_mention` INTEGER NOT NULL, `last_message` TEXT, `object_type` TEXT, `notification_level` INTEGER, `read_only_state` INTEGER, `lobby_state` INTEGER, `lobby_timer` INTEGER, `last_read_message` INTEGER NOT NULL, `can_start_call` INTEGER, `modified_at` INTEGER, `changing` INTEGER NOT NULL, PRIMARY KEY(`id`), FOREIGN KEY(`user_id`) REFERENCES `users`(`id`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)", "fields": [ { "fieldPath": "id", @@ -63,10 +63,10 @@ "notNull": true }, { - "fieldPath": "participantsCount", - "columnName": "participants_count", - "affinity": "INTEGER", - "notNull": true + "fieldPath": "participants", + "columnName": "participants", + "affinity": "TEXT", + "notNull": false }, { "fieldPath": "participantType", @@ -389,7 +389,7 @@ "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '3a9126341dd46ffc54056126b59ed5fb')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '2c4f372b48cd11e679b04c6d577f1cd8')" ] } } \ No newline at end of file diff --git a/app/src/main/java/com/nextcloud/talk/models/json/conversations/Conversation.kt b/app/src/main/java/com/nextcloud/talk/models/json/conversations/Conversation.kt index 6864fa7e1..ae51873a6 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/conversations/Conversation.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/conversations/Conversation.kt @@ -61,7 +61,7 @@ class Conversation { /*@JsonField(name = ["guestList"]) var guestList: HashMap>? = null*/ @JsonField(name = ["participants"]) - var participants: HashMap>? = null + var participants: HashMap? = null @JsonField(name = ["participantType"], typeConverter = EnumParticipantTypeConverter::class) var participantType: Participant.ParticipantType? = null @JsonField(name = ["hasPassword"]) diff --git a/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumParticipantFlagsConverter.kt b/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumParticipantFlagsConverter.kt new file mode 100644 index 000000000..4557475ab --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumParticipantFlagsConverter.kt @@ -0,0 +1,36 @@ +/* + * + * * Nextcloud Talk application + * * + * * @author Mario Danic + * * Copyright (C) 2017-2020 Mario Danic + * * + * * This program is free software: you can redistribute it and/or modify + * * it under the terms of the GNU General Public License as published by + * * the Free Software Foundation, either version 3 of the License, or + * * at your option) any later version. + * * + * * This program is distributed in the hope that it will be useful, + * * but WITHOUT ANY WARRANTY; without even the implied warranty of + * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * * GNU General Public License for more details. + * * + * * You should have received a copy of the GNU General Public License + * * along with this program. If not, see . + * + */ + +package com.nextcloud.talk.models.json.converters + +import com.bluelinelabs.logansquare.typeconverters.LongBasedTypeConverter +import com.nextcloud.talk.models.json.participants.Participant + +class EnumParticipantFlagsConverter : LongBasedTypeConverter() { + override fun getFromLong(l: Long): Participant.ParticipantFlags { + return Participant.ParticipantFlags.fromValue(l) + } + + override fun convertToLong(`object`: Participant.ParticipantFlags?): Long { + return `object`?.value ?: 0 + } +} diff --git a/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumParticipantTypeConverter.java b/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumParticipantTypeConverter.java index 79531a6bd..3ad342da8 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumParticipantTypeConverter.java +++ b/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumParticipantTypeConverter.java @@ -38,16 +38,16 @@ public class EnumParticipantTypeConverter return Participant.ParticipantType.GUEST; case 5: return Participant.ParticipantType.USER_FOLLOWING_LINK; + case 6: + return Participant.ParticipantType.GUEST_AS_MODERATOR; default: - return Participant.ParticipantType.DUMMY; + return Participant.ParticipantType.GUEST; } } @Override public int convertToInt(Participant.ParticipantType object) { switch (object) { - case DUMMY: - return 0; case OWNER: return 1; case MODERATOR: @@ -58,6 +58,8 @@ public class EnumParticipantTypeConverter return 4; case USER_FOLLOWING_LINK: return 5; + case GUEST_AS_MODERATOR: + return 6; default: return 0; } diff --git a/app/src/main/java/com/nextcloud/talk/models/json/participants/Participant.java b/app/src/main/java/com/nextcloud/talk/models/json/participants/Participant.java index edb122f77..67f0a804c 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/participants/Participant.java +++ b/app/src/main/java/com/nextcloud/talk/models/json/participants/Participant.java @@ -22,11 +22,10 @@ package com.nextcloud.talk.models.json.participants; import com.bluelinelabs.logansquare.annotation.JsonField; import com.bluelinelabs.logansquare.annotation.JsonObject; +import com.nextcloud.talk.models.json.converters.EnumParticipantFlagsConverter; import com.nextcloud.talk.models.json.converters.EnumParticipantTypeConverter; -import com.nextcloud.talk.models.json.converters.ObjectParcelConverter; import org.parceler.Parcel; -import org.parceler.ParcelPropertyConverter; import lombok.Data; @@ -55,39 +54,52 @@ public class Participant { public String sessionId; @JsonField(name = "conversationId") - public long roomId; + public long conversationId; - @ParcelPropertyConverter(ObjectParcelConverter.class) - @JsonField(name = "inCall") - public Object inCall; + @JsonField(name = { "inCall", "call" }, typeConverter = EnumParticipantFlagsConverter.class) + public ParticipantFlags participantFlags; + + @JsonField(name = "source") public String source; public boolean selected; + + public enum ParticipantType { + OWNER(1), + MODERATOR(2), + USER(3), + GUEST(4), + USER_FOLLOWING_LINK(5), + GUEST_AS_MODERATOR(6); - public ParticipantFlags getParticipantFlags() { - ParticipantFlags participantFlags = ParticipantFlags.NOT_IN_CALL; - if (inCall != null) { - if (inCall instanceof Long) { - participantFlags = ParticipantFlags.fromValue((Long) inCall); - } else if (inCall instanceof Boolean) { - if ((boolean) inCall) { - participantFlags = ParticipantFlags.IN_CALL; - } else { - participantFlags = ParticipantFlags.NOT_IN_CALL; - } + private long value; + + ParticipantType(long value) { + this.value = value; + } + + public static ParticipantType fromValue(long value) { + if (value == 1) { + return OWNER; + } else if (value == 2) { + return MODERATOR; + } else if (value == 3) { + return USER; + } else if (value == 4) { + return GUEST; + } else if (value == 5) { + return USER_FOLLOWING_LINK; + } else if (value == 6) { + return GUEST_AS_MODERATOR; + } else { + return GUEST; } } - return participantFlags; - } + public long getValue() { + return value; + } - public enum ParticipantType { - DUMMY, - OWNER, - MODERATOR, - USER, - GUEST, - USER_FOLLOWING_LINK } public enum ParticipantFlags { diff --git a/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ParticipantMapConverter.kt b/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ParticipantMapConverter.kt new file mode 100644 index 000000000..a5ad58c07 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ParticipantMapConverter.kt @@ -0,0 +1,48 @@ +/* + * + * * Nextcloud Talk application + * * + * * @author Mario Danic + * * Copyright (C) 2017-2020 Mario Danic + * * + * * This program is free software: you can redistribute it and/or modify + * * it under the terms of the GNU General Public License as published by + * * the Free Software Foundation, either version 3 of the License, or + * * at your option) any later version. + * * + * * This program is distributed in the hope that it will be useful, + * * but WITHOUT ANY WARRANTY; without even the implied warranty of + * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * * GNU General Public License for more details. + * * + * * You should have received a copy of the GNU General Public License + * * along with this program. If not, see . + * + */ + +package com.nextcloud.talk.newarch.local.converters + +import androidx.room.TypeConverter +import com.bluelinelabs.logansquare.LoganSquare +import com.nextcloud.talk.models.json.participants.Participant + +class ParticipantMapConverter { + @TypeConverter + fun fromMapToString(map: HashMap?): String? { + if (map == null) { + return "" + } + + return LoganSquare.serialize(map) + } + + @TypeConverter + fun fromStringToHashMap(value: String?): HashMap? { + if (value.isNullOrEmpty()) { + return null + } + + return LoganSquare.parse(value, HashMap::class.java) as java.util.HashMap? + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ParticipantTypeConverter.kt b/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ParticipantTypeConverter.kt index dd77d09e8..424745484 100644 --- a/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ParticipantTypeConverter.kt +++ b/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ParticipantTypeConverter.kt @@ -22,7 +22,6 @@ package com.nextcloud.talk.newarch.local.converters import androidx.room.TypeConverter import com.nextcloud.talk.models.json.participants.Participant.ParticipantType -import com.nextcloud.talk.models.json.participants.Participant.ParticipantType.* class ParticipantTypeConverter { @TypeConverter @@ -32,14 +31,6 @@ class ParticipantTypeConverter { @TypeConverter fun fromIntToParticipantType(value: Int): ParticipantType { - when (value) { - 0 -> return DUMMY - 1 -> return OWNER - 2 -> return MODERATOR - 3 -> return USER - 4 -> return GUEST - else -> return USER_FOLLOWING_LINK - - } + return ParticipantType.fromValue(value.toLong()) } } \ No newline at end of file diff --git a/app/src/main/java/com/nextcloud/talk/newarch/local/db/TalkDatabase.kt b/app/src/main/java/com/nextcloud/talk/newarch/local/db/TalkDatabase.kt index 5acacaf07..d8772f2a5 100644 --- a/app/src/main/java/com/nextcloud/talk/newarch/local/db/TalkDatabase.kt +++ b/app/src/main/java/com/nextcloud/talk/newarch/local/db/TalkDatabase.kt @@ -44,7 +44,7 @@ import com.nextcloud.talk.newarch.local.models.UserNgEntity ConversationTypeConverter::class, ParticipantTypeConverter::class, PushConfigurationConverter::class, CapabilitiesConverter::class, ExternalSignalingConverter::class, - UserStatusConverter::class, SystemMessageTypeConverter::class + UserStatusConverter::class, SystemMessageTypeConverter::class, ParticipantMapConverter::class ) abstract class TalkDatabase : RoomDatabase() { diff --git a/app/src/main/java/com/nextcloud/talk/newarch/local/models/ConversationEntity.kt b/app/src/main/java/com/nextcloud/talk/newarch/local/models/ConversationEntity.kt index 3f79dc8c5..9c9450c33 100644 --- a/app/src/main/java/com/nextcloud/talk/newarch/local/models/ConversationEntity.kt +++ b/app/src/main/java/com/nextcloud/talk/newarch/local/models/ConversationEntity.kt @@ -25,6 +25,7 @@ import androidx.room.ForeignKey.CASCADE import com.nextcloud.talk.models.json.chat.ChatMessage import com.nextcloud.talk.models.json.conversations.Conversation import com.nextcloud.talk.models.json.conversations.Conversation.* +import com.nextcloud.talk.models.json.participants.Participant import com.nextcloud.talk.models.json.participants.Participant.ParticipantType import java.util.* @@ -50,12 +51,7 @@ data class ConversationEntity( @ColumnInfo(name = "type") var type: ConversationType? = null, @ColumnInfo(name = "count") var count: Long = 0, @ColumnInfo(name = "number_of_guests") var numberOfGuests: Long = 0, - /*@ColumnInfo(name = "guest_list") var guestList: HashMap>? = null, - @ColumnInfo(name = "participants") var participants: HashMap>? = - null, - */ - // hack for participants list - @ColumnInfo(name = "participants_count") var participantsCount: Int = 0, + @ColumnInfo(name = "participants") var participants: HashMap? = null, @ColumnInfo(name = "participant_type") var participantType: ParticipantType? = null, @ColumnInfo(name = "has_password") var hasPassword: Boolean = false, @ColumnInfo(name = "session_id") var sessionId: String? = null, @@ -92,7 +88,7 @@ data class ConversationEntity( if (type != other.type) return false if (count != other.count) return false if (numberOfGuests != other.numberOfGuests) return false - if (participantsCount != other.participantsCount) return false + if (participants != other.participants) return false if (participantType != other.participantType) return false if (hasPassword != other.hasPassword) return false if (sessionId != other.sessionId) return false @@ -130,10 +126,7 @@ fun ConversationEntity.toConversation(): Conversation { conversation.displayName = this.displayName conversation.count = this.count conversation.numberOfGuests = this.numberOfGuests - conversation.participants = HashMap() - for (i in 0 until participantsCount) { - conversation.participants?.put(i.toString(), HashMap()) - } + conversation.participants = this.participants conversation.participantType = this.participantType conversation.hasPassword = this.hasPassword conversation.sessionId = this.sessionId @@ -163,7 +156,7 @@ fun Conversation.toConversationEntity(): ConversationEntity { conversationEntity.displayName = this.displayName conversationEntity.count = this.count conversationEntity.numberOfGuests = this.numberOfGuests - conversationEntity.participantsCount = this.participants?.size ?: 0 + conversationEntity.participants = this.participants conversationEntity.participantType = this.participantType conversationEntity.hasPassword = this.hasPassword conversationEntity.sessionId = this.sessionId diff --git a/build.gradle b/build.gradle index 689dab2fe..b3f2ac8bb 100644 --- a/build.gradle +++ b/build.gradle @@ -35,6 +35,7 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:3.5.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlin_version}" + classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files