More progress on various offline storages

Signed-off-by: Mario Danic <mario@lovelyhq.com>
This commit is contained in:
Mario Danic 2019-10-29 15:17:56 +01:00
parent 96c2315d91
commit f637e4765b
No known key found for this signature in database
GPG Key ID: CDE0BBD2738C4CC0
30 changed files with 830 additions and 113 deletions

View File

@ -2,23 +2,29 @@
"formatVersion": 1, "formatVersion": 1,
"database": { "database": {
"version": 1, "version": 1,
"identityHash": "a547a767687b46e3e5768a3d77d5d212", "identityHash": "8b9e5dddd027e51eb17ffd53d365e6d4",
"entities": [ "entities": [
{ {
"tableName": "conversations", "tableName": "conversations",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user` INTEGER NOT NULL, `conversation_id` TEXT NOT NULL, `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_id` INTEGER NOT NULL, `modified_at` INTEGER, `changing` INTEGER NOT NULL, PRIMARY KEY(`user`, `conversation_id`))", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `user` 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_id` INTEGER NOT NULL, `modified_at` INTEGER, `changing` INTEGER NOT NULL, FOREIGN KEY(`user`) REFERENCES `users`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)",
"fields": [ "fields": [
{ {
"fieldPath": "userId", "fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "user",
"columnName": "user", "columnName": "user",
"affinity": "INTEGER", "affinity": "INTEGER",
"notNull": true "notNull": false
}, },
{ {
"fieldPath": "conversationId", "fieldPath": "conversationId",
"columnName": "conversation_id", "columnName": "conversation_id",
"affinity": "TEXT", "affinity": "TEXT",
"notNull": true "notNull": false
}, },
{ {
"fieldPath": "token", "fieldPath": "token",
@ -161,10 +167,208 @@
], ],
"primaryKey": { "primaryKey": {
"columnNames": [ "columnNames": [
"user", "id"
"conversation_id"
], ],
"autoGenerate": false "autoGenerate": true
},
"indices": [
{
"name": "index_conversations_user",
"unique": false,
"columnNames": [
"user"
],
"createSql": "CREATE INDEX IF NOT EXISTS `index_conversations_user` ON `${TABLE_NAME}` (`user`)"
}
],
"foreignKeys": [
{
"table": "users",
"onDelete": "CASCADE",
"onUpdate": "NO ACTION",
"columns": [
"user"
],
"referencedColumns": [
"id"
]
}
]
},
{
"tableName": "messages",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `user` INTEGER, `conversation` INTEGER, `message_id` INTEGER NOT NULL, `actor_id` TEXT, `actor_type` TEXT, `actor_display_name` TEXT, `timestamp` INTEGER NOT NULL, `message` TEXT, `system_message_type` TEXT, FOREIGN KEY(`conversation`) REFERENCES `conversations`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "user",
"columnName": "user",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "conversation",
"columnName": "conversation",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "messageId",
"columnName": "message_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "actorId",
"columnName": "actor_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "actorType",
"columnName": "actor_type",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "actorDisplayName",
"columnName": "actor_display_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "systemMessageType",
"columnName": "system_message_type",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [
{
"name": "index_messages_conversation",
"unique": false,
"columnNames": [
"conversation"
],
"createSql": "CREATE INDEX IF NOT EXISTS `index_messages_conversation` ON `${TABLE_NAME}` (`conversation`)"
},
{
"name": "index_messages_user_conversation",
"unique": false,
"columnNames": [
"user",
"conversation"
],
"createSql": "CREATE INDEX IF NOT EXISTS `index_messages_user_conversation` ON `${TABLE_NAME}` (`user`, `conversation`)"
}
],
"foreignKeys": [
{
"table": "conversations",
"onDelete": "CASCADE",
"onUpdate": "NO ACTION",
"columns": [
"conversation"
],
"referencedColumns": [
"id"
]
}
]
},
{
"tableName": "users",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `user_id` TEXT, `username` TEXT, `token` TEXT, `display_name` TEXT, `push_configuration` TEXT, `capabilities` TEXT, `client_auth_cert` TEXT, `external_signaling` TEXT, `status` INTEGER)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "userId",
"columnName": "user_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "username",
"columnName": "username",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "token",
"columnName": "token",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "displayName",
"columnName": "display_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "pushConfiguration",
"columnName": "push_configuration",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "capabilities",
"columnName": "capabilities",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "clientCertificate",
"columnName": "client_auth_cert",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "externalSignaling",
"columnName": "external_signaling",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "status",
"columnName": "status",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
}, },
"indices": [], "indices": [],
"foreignKeys": [] "foreignKeys": []
@ -173,7 +377,7 @@
"views": [], "views": [],
"setupQueries": [ "setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", "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, 'a547a767687b46e3e5768a3d77d5d212')" "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '8b9e5dddd027e51eb17ffd53d365e6d4')"
] ]
} }
} }

View File

@ -2,11 +2,11 @@
"formatVersion": 1, "formatVersion": 1,
"database": { "database": {
"version": 4, "version": 4,
"identityHash": "99ff92e07b8afc6473ee55cf38d30a81", "identityHash": "8b9e5dddd027e51eb17ffd53d365e6d4",
"entities": [ "entities": [
{ {
"tableName": "conversations", "tableName": "conversations",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `user` 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_id` INTEGER NOT NULL, `modified_at` INTEGER, `changing` INTEGER NOT NULL, FOREIGN KEY(`user`) REFERENCES `users`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `user` 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_id` INTEGER NOT NULL, `modified_at` INTEGER, `changing` INTEGER NOT NULL, FOREIGN KEY(`user`) REFERENCES `users`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -171,7 +171,16 @@
], ],
"autoGenerate": true "autoGenerate": true
}, },
"indices": [], "indices": [
{
"name": "index_conversations_user",
"unique": false,
"columnNames": [
"user"
],
"createSql": "CREATE INDEX IF NOT EXISTS `index_conversations_user` ON `${TABLE_NAME}` (`user`)"
}
],
"foreignKeys": [ "foreignKeys": [
{ {
"table": "users", "table": "users",
@ -188,19 +197,67 @@
}, },
{ {
"tableName": "messages", "tableName": "messages",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `user` INTEGER, FOREIGN KEY(`user`) REFERENCES `users`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `user` INTEGER, `conversation` INTEGER, `message_id` INTEGER NOT NULL, `actor_id` TEXT, `actor_type` TEXT, `actor_display_name` TEXT, `timestamp` INTEGER NOT NULL, `message` TEXT, `system_message_type` TEXT, FOREIGN KEY(`conversation`) REFERENCES `conversations`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
"columnName": "id", "columnName": "id",
"affinity": "INTEGER", "affinity": "INTEGER",
"notNull": true "notNull": false
}, },
{ {
"fieldPath": "user", "fieldPath": "user",
"columnName": "user", "columnName": "user",
"affinity": "INTEGER", "affinity": "INTEGER",
"notNull": false "notNull": false
},
{
"fieldPath": "conversation",
"columnName": "conversation",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "messageId",
"columnName": "message_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "actorId",
"columnName": "actor_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "actorType",
"columnName": "actor_type",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "actorDisplayName",
"columnName": "actor_display_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "systemMessageType",
"columnName": "system_message_type",
"affinity": "TEXT",
"notNull": false
} }
], ],
"primaryKey": { "primaryKey": {
@ -209,14 +266,32 @@
], ],
"autoGenerate": true "autoGenerate": true
}, },
"indices": [], "indices": [
{
"name": "index_messages_conversation",
"unique": false,
"columnNames": [
"conversation"
],
"createSql": "CREATE INDEX IF NOT EXISTS `index_messages_conversation` ON `${TABLE_NAME}` (`conversation`)"
},
{
"name": "index_messages_user_conversation",
"unique": false,
"columnNames": [
"user",
"conversation"
],
"createSql": "CREATE INDEX IF NOT EXISTS `index_messages_user_conversation` ON `${TABLE_NAME}` (`user`, `conversation`)"
}
],
"foreignKeys": [ "foreignKeys": [
{ {
"table": "users", "table": "conversations",
"onDelete": "CASCADE", "onDelete": "CASCADE",
"onUpdate": "NO ACTION", "onUpdate": "NO ACTION",
"columns": [ "columns": [
"user" "conversation"
], ],
"referencedColumns": [ "referencedColumns": [
"id" "id"
@ -226,13 +301,13 @@
}, },
{ {
"tableName": "users", "tableName": "users",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `user_id` TEXT, `username` TEXT, `token` TEXT, `display_name` TEXT, `push_configuration` TEXT, `capabilities` TEXT, `client_auth_cert` TEXT, `external_signaling` TEXT, `status` INTEGER)", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `user_id` TEXT, `username` TEXT, `token` TEXT, `display_name` TEXT, `push_configuration` TEXT, `capabilities` TEXT, `client_auth_cert` TEXT, `external_signaling` TEXT, `status` INTEGER)",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
"columnName": "id", "columnName": "id",
"affinity": "INTEGER", "affinity": "INTEGER",
"notNull": true "notNull": false
}, },
{ {
"fieldPath": "userId", "fieldPath": "userId",
@ -302,7 +377,7 @@
"views": [], "views": [],
"setupQueries": [ "setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", "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, '99ff92e07b8afc6473ee55cf38d30a81')" "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '8b9e5dddd027e51eb17ffd53d365e6d4')"
] ]
} }
} }

View File

@ -37,6 +37,7 @@ import autodagger.AutoComponent
import autodagger.AutoInjector import autodagger.AutoInjector
import coil.Coil import coil.Coil
import coil.ImageLoader import coil.ImageLoader
import com.bluelinelabs.logansquare.LoganSquare
import com.facebook.cache.disk.DiskCacheConfig import com.facebook.cache.disk.DiskCacheConfig
import com.facebook.drawee.backends.pipeline.Fresco import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.imagepipeline.core.ImagePipelineConfig import com.facebook.imagepipeline.core.ImagePipelineConfig
@ -50,21 +51,32 @@ import com.nextcloud.talk.jobs.AccountRemovalWorker
import com.nextcloud.talk.jobs.CapabilitiesWorker import com.nextcloud.talk.jobs.CapabilitiesWorker
import com.nextcloud.talk.jobs.PushRegistrationWorker import com.nextcloud.talk.jobs.PushRegistrationWorker
import com.nextcloud.talk.jobs.SignalingSettingsWorker import com.nextcloud.talk.jobs.SignalingSettingsWorker
import com.nextcloud.talk.models.ExternalSignalingServer
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.models.json.capabilities.Capabilities
import com.nextcloud.talk.models.json.push.PushConfigurationState
import com.nextcloud.talk.newarch.di.module.CommunicationModule import com.nextcloud.talk.newarch.di.module.CommunicationModule
import com.nextcloud.talk.newarch.di.module.NetworkModule import com.nextcloud.talk.newarch.di.module.NetworkModule
import com.nextcloud.talk.newarch.di.module.StorageModule import com.nextcloud.talk.newarch.di.module.StorageModule
import com.nextcloud.talk.newarch.features.conversationsList.di.module.ConversationsListModule import com.nextcloud.talk.newarch.features.conversationsList.di.module.ConversationsListModule
import com.nextcloud.talk.newarch.local.dao.UsersDao
import com.nextcloud.talk.newarch.local.models.UserNgEntity
import com.nextcloud.talk.newarch.local.models.other.UserStatus.ACTIVE
import com.nextcloud.talk.newarch.local.models.other.UserStatus.DORMANT
import com.nextcloud.talk.utils.ClosedInterfaceImpl import com.nextcloud.talk.utils.ClosedInterfaceImpl
import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.DisplayUtils
import com.nextcloud.talk.utils.OkHttpNetworkFetcherWithCache import com.nextcloud.talk.utils.OkHttpNetworkFetcherWithCache
import com.nextcloud.talk.utils.database.arbitrarystorage.ArbitraryStorageModule import com.nextcloud.talk.utils.database.arbitrarystorage.ArbitraryStorageModule
import com.nextcloud.talk.utils.database.user.UserModule import com.nextcloud.talk.utils.database.user.UserModule
import com.nextcloud.talk.utils.database.user.UserUtils
import com.nextcloud.talk.utils.preferences.AppPreferences import com.nextcloud.talk.utils.preferences.AppPreferences
import com.nextcloud.talk.webrtc.MagicWebRTCUtils import com.nextcloud.talk.webrtc.MagicWebRTCUtils
import com.vanniktech.emoji.EmojiManager import com.vanniktech.emoji.EmojiManager
import com.vanniktech.emoji.googlecompat.GoogleCompatEmojiProvider import com.vanniktech.emoji.googlecompat.GoogleCompatEmojiProvider
import de.cotech.hw.SecurityKeyManager import de.cotech.hw.SecurityKeyManager
import de.cotech.hw.SecurityKeyManagerConfig import de.cotech.hw.SecurityKeyManagerConfig
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import org.conscrypt.Conscrypt import org.conscrypt.Conscrypt
import org.koin.android.ext.android.inject import org.koin.android.ext.android.inject
@ -76,6 +88,7 @@ import org.webrtc.voiceengine.WebRtcAudioManager
import org.webrtc.voiceengine.WebRtcAudioUtils import org.webrtc.voiceengine.WebRtcAudioUtils
import java.security.Security import java.security.Security
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@AutoComponent( @AutoComponent(
@ -90,10 +103,13 @@ class NextcloudTalkApplication : Application(), LifecycleObserver {
//endregion //endregion
//region Getters //region Getters
@Inject
lateinit var userUtils: UserUtils
val imageLoader: ImageLoader by inject() val imageLoader: ImageLoader by inject()
val appPreferences: AppPreferences by inject() val appPreferences: AppPreferences by inject()
val okHttpClient: OkHttpClient by inject() val okHttpClient: OkHttpClient by inject()
val usersDao: UsersDao by inject()
//endregion //endregion
//region private methods //region private methods
@ -139,6 +155,7 @@ class NextcloudTalkApplication : Application(), LifecycleObserver {
componentApplication.inject(this) componentApplication.inject(this)
Coil.setDefaultImageLoader(imageLoader) Coil.setDefaultImageLoader(imageLoader)
migrateUsers()
setAppTheme(appPreferences.theme) setAppTheme(appPreferences.theme)
super.onCreate() super.onCreate()
@ -223,6 +240,32 @@ class NextcloudTalkApplication : Application(), LifecycleObserver {
MultiDex.install(this) MultiDex.install(this)
} }
fun migrateUsers() {
GlobalScope.launch {
val users: List<UserEntity> = userUtils.users as List<UserEntity>
var userNg: UserNgEntity
val newUsers = mutableListOf<UserNgEntity>()
for (user in users) {
userNg = UserNgEntity()
userNg.userId = user.userId
userNg.username = user.username
userNg.token = user.token
userNg.displayName = user.displayName
userNg.pushConfiguration = LoganSquare.parse(user.pushConfigurationState, PushConfigurationState::class.java)
userNg.capabilities = LoganSquare.parse(user.capabilities, Capabilities::class.java)
userNg.clientCertificate = user.clientCertificate
userNg.externalSignaling = LoganSquare.parse(user.externalSignalingServer, ExternalSignalingServer::class.java)
if (user.current) {
userNg.status = ACTIVE
} else {
userNg.status = DORMANT
}
newUsers.add(userNg)
}
usersDao.saveUsers(*newUsers.toTypedArray())
}
}
companion object { companion object {
private val TAG = NextcloudTalkApplication::class.java.simpleName private val TAG = NextcloudTalkApplication::class.java.simpleName
//region Singleton //region Singleton

View File

@ -167,8 +167,8 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
var currentConversation: Conversation? = null var currentConversation: Conversation? = null
var inConversation = false var inConversation = false
var historyRead = false var historyRead = false
var globalLastKnownFutureMessageId = -1 var globalLastKnownFutureMessageId: Long = -1
var globalLastKnownPastMessageId = -1 var globalLastKnownPastMessageId: Long = -1
var adapter: MessagesListAdapter<ChatMessage>? = null var adapter: MessagesListAdapter<ChatMessage>? = null
var mentionAutocomplete: Autocomplete<*>? = null var mentionAutocomplete: Autocomplete<*>? = null
var layoutManager: LinearLayoutManager? = null var layoutManager: LinearLayoutManager? = null
@ -1079,14 +1079,14 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
fieldMap["limit"] = 100 fieldMap["limit"] = 100
fieldMap["setReadMarker"] = 1 fieldMap["setReadMarker"] = 1
val lastKnown: Int val lastKnown: Long
if (lookIntoFuture > 0) { if (lookIntoFuture > 0) {
lastKnown = globalLastKnownFutureMessageId lastKnown = globalLastKnownFutureMessageId
} else { } else {
lastKnown = globalLastKnownPastMessageId lastKnown = globalLastKnownPastMessageId
} }
fieldMap["lastKnownMessageId"] = lastKnown fieldMap["lastKnownMessageId"] = lastKnown.toInt()
if (!wasDetached) { if (!wasDetached) {
if (lookIntoFuture > 0) { if (lookIntoFuture > 0) {
@ -1158,8 +1158,8 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
.get("X-Chat-Last-Given") .get("X-Chat-Last-Given")
if (response.headers().size() > 0 && !TextUtils.isEmpty(xChatLastGivenHeader)) { if (response.headers().size() > 0 && !TextUtils.isEmpty(xChatLastGivenHeader)) {
val header = Integer.parseInt(xChatLastGivenHeader!!) val header = xChatLastGivenHeader?.toLong()
if (header > 0) { if (header != null) {
if (isFromTheFuture) { if (isFromTheFuture) {
globalLastKnownFutureMessageId = header globalLastKnownFutureMessageId = header
} else { } else {

View File

@ -21,6 +21,7 @@ package com.nextcloud.talk.models.json.chat;
import android.text.TextUtils; import android.text.TextUtils;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.room.Ignore;
import com.bluelinelabs.logansquare.annotation.JsonField; import com.bluelinelabs.logansquare.annotation.JsonField;
import com.bluelinelabs.logansquare.annotation.JsonIgnore; import com.bluelinelabs.logansquare.annotation.JsonIgnore;
import com.bluelinelabs.logansquare.annotation.JsonObject; import com.bluelinelabs.logansquare.annotation.JsonObject;
@ -46,17 +47,29 @@ import org.parceler.Parcel;
@JsonObject(serializeNullCollectionElements = true, serializeNullObjects = true) @JsonObject(serializeNullCollectionElements = true, serializeNullObjects = true)
public class ChatMessage implements IMessage, MessageContentType, MessageContentType.Image { public class ChatMessage implements IMessage, MessageContentType, MessageContentType.Image {
@JsonIgnore @JsonIgnore
@Ignore
public boolean isGrouped; public boolean isGrouped;
@JsonIgnore @JsonIgnore
@Ignore
public boolean isOneToOneConversation; public boolean isOneToOneConversation;
@JsonIgnore @JsonIgnore
@Ignore
public UserEntity activeUser; public UserEntity activeUser;
@JsonIgnore @JsonIgnore
@Ignore
public Map<String, String> selectedIndividualHashMap; public Map<String, String> selectedIndividualHashMap;
@JsonIgnore @JsonIgnore
@Ignore
public boolean isLinkPreviewAllowed; public boolean isLinkPreviewAllowed;
@JsonIgnore
public Long internalUserId = null;
@JsonIgnore
public Long internalMessageId = null;
@JsonIgnore
public Long internalConversationId = null;
@JsonField(name = "id") @JsonField(name = "id")
public int jsonMessageId; @Ignore
public Long jsonMessageId;
@JsonField(name = "token") @JsonField(name = "token")
public String token; public String token;
// guests or users // guests or users
@ -73,9 +86,13 @@ public class ChatMessage implements IMessage, MessageContentType, MessageContent
@JsonField(name = "message") @JsonField(name = "message")
public String message; public String message;
@JsonField(name = "messageParameters") @JsonField(name = "messageParameters")
@Ignore
public HashMap<String, HashMap<String, String>> messageParameters; public HashMap<String, HashMap<String, String>> messageParameters;
@JsonField(name = "systemMessage", typeConverter = EnumSystemMessageTypeConverter.class) @JsonField(name = "systemMessage", typeConverter = EnumSystemMessageTypeConverter.class)
public SystemMessageType systemMessageType; public SystemMessageType systemMessageType;
@JsonIgnore
@Ignore
List<MessageType> messageTypesToIgnore = Arrays.asList(MessageType.REGULAR_TEXT_MESSAGE, List<MessageType> messageTypesToIgnore = Arrays.asList(MessageType.REGULAR_TEXT_MESSAGE,
MessageType.SYSTEM_MESSAGE, MessageType.SINGLE_LINK_VIDEO_MESSAGE, MessageType.SYSTEM_MESSAGE, MessageType.SINGLE_LINK_VIDEO_MESSAGE,
MessageType.SINGLE_LINK_AUDIO_MESSAGE, MessageType.SINGLE_LINK_MESSAGE); MessageType.SINGLE_LINK_AUDIO_MESSAGE, MessageType.SINGLE_LINK_MESSAGE);
@ -138,7 +155,7 @@ public class ChatMessage implements IMessage, MessageContentType, MessageContent
@Override @Override
public String getId() { public String getId() {
return Integer.toString(jsonMessageId); return Long.toString(jsonMessageId);
} }
@Override @Override

View File

@ -97,7 +97,7 @@ class Conversation {
@JsonField(name = ["lobbyTimer"]) @JsonField(name = ["lobbyTimer"])
var lobbyTimer: Long? = 0 var lobbyTimer: Long? = 0
@JsonField(name = ["lastReadMessageId"]) @JsonField(name = ["lastReadMessageId"])
var lastReadMessageId: Int = 0 var lastReadMessageId: Long = 0
var changing: Boolean = false var changing: Boolean = false
val isPublic: Boolean = ConversationType.PUBLIC_CONVERSATION == type val isPublic: Boolean = ConversationType.PUBLIC_CONVERSATION == type

View File

@ -18,25 +18,24 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.nextcloud.talk.newarch.data.repository package com.nextcloud.talk.newarch.data.repository.offline
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.map import androidx.lifecycle.map
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.models.json.conversations.Conversation import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.newarch.domain.repository.NextcloudTalkOfflineRepository import com.nextcloud.talk.newarch.domain.repository.offline.ConversationsRepository
import com.nextcloud.talk.newarch.local.db.TalkDatabase import com.nextcloud.talk.newarch.local.dao.ConversationsDao
import com.nextcloud.talk.newarch.local.models.toConversation import com.nextcloud.talk.newarch.local.models.toConversation
import com.nextcloud.talk.newarch.local.models.toConversationEntity import com.nextcloud.talk.newarch.local.models.toConversationEntity
class NextcloudTalkOfflineRepositoryImpl(val nextcloudTalkDatabase: TalkDatabase) : class ConversationsRepositoryImpl(val conversationsDao: ConversationsDao) :
NextcloudTalkOfflineRepository { ConversationsRepository {
override suspend fun setChangingValueForConversation( override suspend fun setChangingValueForConversation(
userId: Long, userId: Long,
conversationId: String, conversationId: String,
changing: Boolean changing: Boolean
) { ) {
nextcloudTalkDatabase.conversationsDao() conversationsDao
.updateChangingValueForConversation(userId, conversationId, changing) .updateChangingValueForConversation(userId, conversationId, changing)
} }
@ -45,7 +44,7 @@ class NextcloudTalkOfflineRepositoryImpl(val nextcloudTalkDatabase: TalkDatabase
conversationId: String, conversationId: String,
favorite: Boolean favorite: Boolean
) { ) {
nextcloudTalkDatabase.conversationsDao() conversationsDao
.updateFavoriteValueForConversation(userId, conversationId, favorite) .updateFavoriteValueForConversation(userId, conversationId, favorite)
} }
@ -53,12 +52,12 @@ class NextcloudTalkOfflineRepositoryImpl(val nextcloudTalkDatabase: TalkDatabase
userId: Long, userId: Long,
conversationId: String conversationId: String
) { ) {
nextcloudTalkDatabase.conversationsDao() conversationsDao
.deleteConversation(userId, conversationId) .deleteConversation(userId, conversationId)
} }
override fun getConversationsForUser(userId: Long): LiveData<List<Conversation>> { override fun getConversationsForUser(userId: Long): LiveData<List<Conversation>> {
return nextcloudTalkDatabase.conversationsDao() return conversationsDao
.getConversationsForUser(userId) .getConversationsForUser(userId)
.map { data -> .map { data ->
data.map { data.map {
@ -67,12 +66,8 @@ class NextcloudTalkOfflineRepositoryImpl(val nextcloudTalkDatabase: TalkDatabase
} }
} }
internal fun getDatabase(): TalkDatabase {
return nextcloudTalkDatabase
}
override suspend fun clearConversationsForUser(userId: Long) { override suspend fun clearConversationsForUser(userId: Long) {
nextcloudTalkDatabase.conversationsDao() conversationsDao
.clearConversationsForUser(userId) .clearConversationsForUser(userId)
} }
@ -80,7 +75,7 @@ class NextcloudTalkOfflineRepositoryImpl(val nextcloudTalkDatabase: TalkDatabase
userId: Long, userId: Long,
conversations: List<Conversation> conversations: List<Conversation>
) { ) {
nextcloudTalkDatabase.conversationsDao() conversationsDao
.updateConversationsForUser( .updateConversationsForUser(
userId, userId,
conversations.map { conversations.map {
@ -93,7 +88,7 @@ class NextcloudTalkOfflineRepositoryImpl(val nextcloudTalkDatabase: TalkDatabase
userId: Long, userId: Long,
timestamp: Long timestamp: Long
) { ) {
nextcloudTalkDatabase.conversationsDao() conversationsDao
.deleteConversationsForUserWithTimestamp(userId, timestamp) .deleteConversationsForUserWithTimestamp(userId, timestamp)
} }
} }

View File

@ -0,0 +1,39 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.newarch.data.repository.offline
import androidx.lifecycle.LiveData
import androidx.lifecycle.map
import com.nextcloud.talk.models.json.chat.ChatMessage
import com.nextcloud.talk.newarch.domain.repository.offline.MessagesRepository
import com.nextcloud.talk.newarch.local.dao.MessagesDao
import com.nextcloud.talk.newarch.local.models.toConversation
class MessagesRepositoryImpl(val messagesDao: MessagesDao): MessagesRepository {
override fun getMessagesWithUserForConversation(
userId: Int,
conversationId: String
): LiveData<List<ChatMessage>> {
TODO(
"not implemented"
) //To change body of created functions use File | Settings | File Templates.
}
}

View File

@ -0,0 +1,28 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.newarch.data.repository.offline
import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
import com.nextcloud.talk.newarch.local.dao.UsersDao
class UsersRepositoryImpl(val usersDao: UsersDao): UsersRepository {
}

View File

@ -18,13 +18,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.nextcloud.talk.newarch.data.repository package com.nextcloud.talk.newarch.data.repository.online
import com.nextcloud.talk.models.database.UserEntity import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.models.json.conversations.Conversation import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.models.json.generic.GenericOverall import com.nextcloud.talk.models.json.generic.GenericOverall
import com.nextcloud.talk.newarch.data.source.remote.ApiService import com.nextcloud.talk.newarch.data.source.remote.ApiService
import com.nextcloud.talk.newarch.domain.repository.NextcloudTalkRepository import com.nextcloud.talk.newarch.domain.repository.online.NextcloudTalkRepository
import com.nextcloud.talk.newarch.utils.getCredentials import com.nextcloud.talk.newarch.utils.getCredentials
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils

View File

@ -31,10 +31,10 @@ import com.github.aurae.retrofit2.LoganSquareConverterFactory
import com.nextcloud.talk.BuildConfig import com.nextcloud.talk.BuildConfig
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.newarch.data.repository.NextcloudTalkRepositoryImpl import com.nextcloud.talk.newarch.data.repository.online.NextcloudTalkRepositoryImpl
import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler
import com.nextcloud.talk.newarch.data.source.remote.ApiService import com.nextcloud.talk.newarch.data.source.remote.ApiService
import com.nextcloud.talk.newarch.domain.repository.NextcloudTalkRepository import com.nextcloud.talk.newarch.domain.repository.online.NextcloudTalkRepository
import com.nextcloud.talk.newarch.utils.NetworkUtils import com.nextcloud.talk.newarch.utils.NetworkUtils
import com.nextcloud.talk.newarch.utils.NetworkUtils.GetProxyRunnable import com.nextcloud.talk.newarch.utils.NetworkUtils.GetProxyRunnable
import com.nextcloud.talk.newarch.utils.NetworkUtils.MagicAuthenticator import com.nextcloud.talk.newarch.utils.NetworkUtils.MagicAuthenticator
@ -61,7 +61,6 @@ import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import java.io.IOException import java.io.IOException
import java.net.CookieManager import java.net.CookieManager
import java.net.CookiePolicy.ACCEPT_ALL import java.net.CookiePolicy.ACCEPT_ALL
import java.net.CookiePolicy.ACCEPT_NONE
import java.net.Proxy import java.net.Proxy
import java.security.KeyStore import java.security.KeyStore
import java.security.KeyStoreException import java.security.KeyStoreException

View File

@ -21,11 +21,17 @@
package com.nextcloud.talk.newarch.di.module package com.nextcloud.talk.newarch.di.module
import android.content.Context import android.content.Context
import androidx.room.Room
import com.nextcloud.talk.R.string import com.nextcloud.talk.R.string
import com.nextcloud.talk.models.database.Models import com.nextcloud.talk.models.database.Models
import com.nextcloud.talk.newarch.data.repository.NextcloudTalkOfflineRepositoryImpl import com.nextcloud.talk.newarch.data.repository.offline.ConversationsRepositoryImpl
import com.nextcloud.talk.newarch.domain.repository.NextcloudTalkOfflineRepository import com.nextcloud.talk.newarch.data.repository.offline.MessagesRepositoryImpl
import com.nextcloud.talk.newarch.data.repository.offline.UsersRepositoryImpl
import com.nextcloud.talk.newarch.domain.repository.offline.ConversationsRepository
import com.nextcloud.talk.newarch.domain.repository.offline.MessagesRepository
import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
import com.nextcloud.talk.newarch.local.dao.ConversationsDao
import com.nextcloud.talk.newarch.local.dao.MessagesDao
import com.nextcloud.talk.newarch.local.dao.UsersDao
import com.nextcloud.talk.newarch.local.db.TalkDatabase import com.nextcloud.talk.newarch.local.db.TalkDatabase
import com.nextcloud.talk.utils.database.user.UserUtils import com.nextcloud.talk.utils.database.user.UserUtils
import com.nextcloud.talk.utils.preferences.AppPreferences import com.nextcloud.talk.utils.preferences.AppPreferences
@ -44,13 +50,27 @@ val StorageModule = module {
single { createSqlCipherDatabaseSource(androidContext()) } single { createSqlCipherDatabaseSource(androidContext()) }
single { createDataStore(get()) } single { createDataStore(get()) }
single { createUserUtils(get()) } single { createUserUtils(get()) }
single { createNextcloudTalkOfflineRepository(get()) } single { createConversationsRepository(get()) }
single { createMessagesRepository(get()) }
single { createUsersRepository(get()) }
single { TalkDatabase.getInstance(androidApplication()) } single { TalkDatabase.getInstance(androidApplication()) }
single { get<TalkDatabase>().conversationsDao() } single { get<TalkDatabase>().conversationsDao() }
single { get<TalkDatabase>().messagesDao() }
single { get<TalkDatabase>().usersDao() }
} }
fun createNextcloudTalkOfflineRepository(database: TalkDatabase): NextcloudTalkOfflineRepository { fun createConversationsRepository(conversationsDao: ConversationsDao): ConversationsRepository {
return NextcloudTalkOfflineRepositoryImpl(database) return ConversationsRepositoryImpl(conversationsDao)
}
fun createMessagesRepository(messagesDao: MessagesDao): MessagesRepository {
return MessagesRepositoryImpl(messagesDao)
}
fun createUsersRepository(usersDao: UsersDao): UsersRepository {
return UsersRepositoryImpl(usersDao)
} }
fun createPreferences(context: Context): AppPreferences { fun createPreferences(context: Context): AppPreferences {

View File

@ -18,13 +18,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.nextcloud.talk.newarch.domain.repository package com.nextcloud.talk.newarch.domain.repository.offline
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.models.json.conversations.Conversation import com.nextcloud.talk.models.json.conversations.Conversation
interface NextcloudTalkOfflineRepository { interface ConversationsRepository {
fun getConversationsForUser(userId: Long): LiveData<List<Conversation>> fun getConversationsForUser(userId: Long): LiveData<List<Conversation>>
suspend fun clearConversationsForUser(userId: Long) suspend fun clearConversationsForUser(userId: Long)
suspend fun saveConversationsForUser( suspend fun saveConversationsForUser(

View File

@ -0,0 +1,30 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.newarch.domain.repository.offline
import androidx.lifecycle.LiveData
import com.nextcloud.talk.models.json.chat.ChatMessage
import com.nextcloud.talk.models.json.conversations.Conversation
interface MessagesRepository {
fun getMessagesWithUserForConversation(userId: Int, conversationId: String): LiveData<List<ChatMessage>>
}

View File

@ -0,0 +1,25 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.newarch.domain.repository.offline
interface UsersRepository {
}

View File

@ -18,7 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.nextcloud.talk.newarch.domain.repository package com.nextcloud.talk.newarch.domain.repository.online
import com.nextcloud.talk.models.database.UserEntity import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.models.json.conversations.Conversation import com.nextcloud.talk.models.json.conversations.Conversation

View File

@ -22,7 +22,7 @@ package com.nextcloud.talk.newarch.domain.usecases
import com.nextcloud.talk.models.json.generic.GenericOverall import com.nextcloud.talk.models.json.generic.GenericOverall
import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler
import com.nextcloud.talk.newarch.domain.repository.NextcloudTalkRepository import com.nextcloud.talk.newarch.domain.repository.online.NextcloudTalkRepository
import com.nextcloud.talk.newarch.domain.usecases.base.UseCase import com.nextcloud.talk.newarch.domain.usecases.base.UseCase
import org.koin.core.parameter.DefinitionParameters import org.koin.core.parameter.DefinitionParameters

View File

@ -22,7 +22,7 @@ package com.nextcloud.talk.newarch.domain.usecases
import com.nextcloud.talk.models.json.conversations.Conversation import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler
import com.nextcloud.talk.newarch.domain.repository.NextcloudTalkRepository import com.nextcloud.talk.newarch.domain.repository.online.NextcloudTalkRepository
import com.nextcloud.talk.newarch.domain.usecases.base.UseCase import com.nextcloud.talk.newarch.domain.usecases.base.UseCase
import org.koin.core.parameter.DefinitionParameters import org.koin.core.parameter.DefinitionParameters

View File

@ -22,7 +22,7 @@ package com.nextcloud.talk.newarch.domain.usecases
import com.nextcloud.talk.models.json.generic.GenericOverall import com.nextcloud.talk.models.json.generic.GenericOverall
import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler
import com.nextcloud.talk.newarch.domain.repository.NextcloudTalkRepository import com.nextcloud.talk.newarch.domain.repository.online.NextcloudTalkRepository
import com.nextcloud.talk.newarch.domain.usecases.base.UseCase import com.nextcloud.talk.newarch.domain.usecases.base.UseCase
import org.koin.core.parameter.DefinitionParameters import org.koin.core.parameter.DefinitionParameters

View File

@ -22,7 +22,7 @@ package com.nextcloud.talk.newarch.domain.usecases
import com.nextcloud.talk.models.json.generic.GenericOverall import com.nextcloud.talk.models.json.generic.GenericOverall
import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler
import com.nextcloud.talk.newarch.domain.repository.NextcloudTalkRepository import com.nextcloud.talk.newarch.domain.repository.online.NextcloudTalkRepository
import com.nextcloud.talk.newarch.domain.usecases.base.UseCase import com.nextcloud.talk.newarch.domain.usecases.base.UseCase
import org.koin.core.parameter.DefinitionParameters import org.koin.core.parameter.DefinitionParameters

View File

@ -23,7 +23,7 @@ package com.nextcloud.talk.newarch.features.conversationsList
import android.app.Application import android.app.Application
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import com.nextcloud.talk.newarch.domain.repository.NextcloudTalkOfflineRepository import com.nextcloud.talk.newarch.domain.repository.offline.ConversationsRepository
import com.nextcloud.talk.newarch.domain.usecases.DeleteConversationUseCase import com.nextcloud.talk.newarch.domain.usecases.DeleteConversationUseCase
import com.nextcloud.talk.newarch.domain.usecases.GetConversationsUseCase import com.nextcloud.talk.newarch.domain.usecases.GetConversationsUseCase
import com.nextcloud.talk.newarch.domain.usecases.LeaveConversationUseCase import com.nextcloud.talk.newarch.domain.usecases.LeaveConversationUseCase
@ -37,7 +37,7 @@ class ConversationListViewModelFactory constructor(
private val leaveConversationUseCase: LeaveConversationUseCase, private val leaveConversationUseCase: LeaveConversationUseCase,
private val deleteConversationUseCase: DeleteConversationUseCase, private val deleteConversationUseCase: DeleteConversationUseCase,
private val userUtils: UserUtils, private val userUtils: UserUtils,
private val offlineRepository: NextcloudTalkOfflineRepository private val offlineRepository: ConversationsRepository
) : ViewModelProvider.Factory { ) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T { override fun <T : ViewModel?> create(modelClass: Class<T>): T {

View File

@ -22,20 +22,10 @@ package com.nextcloud.talk.newarch.features.conversationsList
import android.app.Application import android.app.Application
import android.content.Intent import android.content.Intent
import android.graphics.Bitmap
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations import androidx.lifecycle.Transformations
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import coil.request.LoadRequest
import coil.target.ViewTarget
import com.facebook.common.executors.UiThreadImmediateExecutorService
import com.facebook.common.references.CloseableReference
import com.facebook.datasource.DataSource
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber
import com.facebook.imagepipeline.image.CloseableImage
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.R.drawable import com.nextcloud.talk.R.drawable
import com.nextcloud.talk.R.string import com.nextcloud.talk.R.string
@ -45,7 +35,7 @@ import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.models.json.generic.GenericOverall import com.nextcloud.talk.models.json.generic.GenericOverall
import com.nextcloud.talk.newarch.conversationsList.mvp.BaseViewModel import com.nextcloud.talk.newarch.conversationsList.mvp.BaseViewModel
import com.nextcloud.talk.newarch.data.model.ErrorModel import com.nextcloud.talk.newarch.data.model.ErrorModel
import com.nextcloud.talk.newarch.domain.repository.NextcloudTalkOfflineRepository import com.nextcloud.talk.newarch.domain.repository.offline.ConversationsRepository
import com.nextcloud.talk.newarch.domain.usecases.DeleteConversationUseCase import com.nextcloud.talk.newarch.domain.usecases.DeleteConversationUseCase
import com.nextcloud.talk.newarch.domain.usecases.GetConversationsUseCase import com.nextcloud.talk.newarch.domain.usecases.GetConversationsUseCase
import com.nextcloud.talk.newarch.domain.usecases.LeaveConversationUseCase import com.nextcloud.talk.newarch.domain.usecases.LeaveConversationUseCase
@ -53,8 +43,6 @@ import com.nextcloud.talk.newarch.domain.usecases.SetConversationFavoriteValueUs
import com.nextcloud.talk.newarch.domain.usecases.base.UseCaseResponse import com.nextcloud.talk.newarch.domain.usecases.base.UseCaseResponse
import com.nextcloud.talk.newarch.utils.ViewState import com.nextcloud.talk.newarch.utils.ViewState
import com.nextcloud.talk.newarch.utils.ViewState.LOADING import com.nextcloud.talk.newarch.utils.ViewState.LOADING
import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.DisplayUtils
import com.nextcloud.talk.utils.ShareUtils import com.nextcloud.talk.utils.ShareUtils
import com.nextcloud.talk.utils.database.user.UserUtils import com.nextcloud.talk.utils.database.user.UserUtils
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -67,10 +55,10 @@ class ConversationsListViewModel constructor(
private val leaveConversationUseCase: LeaveConversationUseCase, private val leaveConversationUseCase: LeaveConversationUseCase,
private val deleteConversationUseCase: DeleteConversationUseCase, private val deleteConversationUseCase: DeleteConversationUseCase,
private val userUtils: UserUtils, private val userUtils: UserUtils,
private val offlineRepository: NextcloudTalkOfflineRepository private val offlineRepository: ConversationsRepository
) : BaseViewModel<ConversationsListView>(application) { ) : BaseViewModel<ConversationsListView>(application) {
val viewState = MutableLiveData<ViewState>(LOADING) val viewState = MutableLiveData(LOADING)
var messageData: String? = null var messageData: String? = null
val searchQuery = MutableLiveData<String>() val searchQuery = MutableLiveData<String>()
val currentUserLiveData: MutableLiveData<UserEntity> = MutableLiveData() val currentUserLiveData: MutableLiveData<UserEntity> = MutableLiveData()

View File

@ -22,8 +22,8 @@ package com.nextcloud.talk.newarch.features.conversationsList.di.module
import android.app.Application import android.app.Application
import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler
import com.nextcloud.talk.newarch.domain.repository.NextcloudTalkOfflineRepository import com.nextcloud.talk.newarch.domain.repository.offline.ConversationsRepository
import com.nextcloud.talk.newarch.domain.repository.NextcloudTalkRepository import com.nextcloud.talk.newarch.domain.repository.online.NextcloudTalkRepository
import com.nextcloud.talk.newarch.domain.usecases.DeleteConversationUseCase import com.nextcloud.talk.newarch.domain.usecases.DeleteConversationUseCase
import com.nextcloud.talk.newarch.domain.usecases.GetConversationsUseCase import com.nextcloud.talk.newarch.domain.usecases.GetConversationsUseCase
import com.nextcloud.talk.newarch.domain.usecases.LeaveConversationUseCase import com.nextcloud.talk.newarch.domain.usecases.LeaveConversationUseCase
@ -83,7 +83,7 @@ fun createConversationListViewModelFactory(
leaveConversationUseCase: LeaveConversationUseCase, leaveConversationUseCase: LeaveConversationUseCase,
deleteConversationUseCase: DeleteConversationUseCase, deleteConversationUseCase: DeleteConversationUseCase,
userUtils: UserUtils, userUtils: UserUtils,
offlineRepository: NextcloudTalkOfflineRepository offlineRepository: ConversationsRepository
): ConversationListViewModelFactory { ): ConversationListViewModelFactory {
return ConversationListViewModelFactory( return ConversationListViewModelFactory(
application, getConversationsUseCase, application, getConversationsUseCase,

View File

@ -0,0 +1,106 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.newarch.local.converters
import androidx.room.TypeConverter
import com.nextcloud.talk.models.json.chat.ChatMessage
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.CALL_ENDED
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.CALL_JOINED
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.CALL_LEFT
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.CALL_STARTED
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.CONVERSATION_CREATED
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.CONVERSATION_RENAMED
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.DUMMY
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.FILE_SHARED
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.GUESTS_ALLOWED
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.GUESTS_DISALLOWED
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.LOBBY_NONE
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.LOBBY_NON_MODERATORS
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.LOBBY_OPEN_TO_EVERYONE
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.MODERATOR_DEMOTED
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.MODERATOR_PROMOTED
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.PASSWORD_REMOVED
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.PASSWORD_SET
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.USER_ADDED
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.USER_REMOVED
import com.nextcloud.talk.newarch.local.models.other.UserStatus
import com.nextcloud.talk.newarch.local.models.other.UserStatus.ACTIVE
import com.nextcloud.talk.newarch.local.models.other.UserStatus.DORMANT
import com.nextcloud.talk.newarch.local.models.other.UserStatus.PENDING_DELETE
class SystemMessageTypeConverter {
@TypeConverter
fun fromStringToSystemMessageType(string: String): SystemMessageType {
when (string) {
"conversation_created" -> return CONVERSATION_CREATED
"conversation_renamed" -> return CONVERSATION_RENAMED
"call_started" -> return CALL_STARTED
"call_joined" -> return CALL_JOINED
"call_left" -> return CALL_LEFT
"call_ended" -> return CALL_ENDED
"guests_allowed" -> return GUESTS_ALLOWED
"guests_disallowed" -> return GUESTS_DISALLOWED
"password_set" -> return PASSWORD_SET
"password_removed" -> return PASSWORD_REMOVED
"user_added" -> return USER_ADDED
"user_removed" -> return USER_REMOVED
"moderator_promoted" -> return MODERATOR_PROMOTED
"moderator_demoted" -> return MODERATOR_DEMOTED
"file_shared" -> return FILE_SHARED
"lobby_none" -> return LOBBY_NONE
"lobby_non_moderators" -> return LOBBY_NON_MODERATORS
"lobby_timer_reached" -> return LOBBY_OPEN_TO_EVERYONE
else -> return DUMMY
}
}
@TypeConverter
fun fromSystemMessageTypeToString(systemMessageType: SystemMessageType?): String {
if (systemMessageType == null) {
return ""
}
when (systemMessageType) {
CONVERSATION_CREATED -> return "conversation_created"
CONVERSATION_RENAMED -> return "conversation_renamed"
CALL_STARTED -> return "call_started"
CALL_JOINED -> return "call_joined"
CALL_LEFT -> return "call_left"
CALL_ENDED -> return "call_ended"
GUESTS_ALLOWED -> return "guests_allowed"
GUESTS_DISALLOWED -> return "guests_disallowed"
PASSWORD_SET -> return "password_set"
PASSWORD_REMOVED -> return "password_removed"
USER_ADDED -> return "user_added"
USER_REMOVED -> return "user_removed"
MODERATOR_PROMOTED -> return "moderator_promoted"
MODERATOR_DEMOTED -> return "moderator_demoted"
FILE_SHARED -> return "file_shared"
LOBBY_NONE -> return "lobby_none"
LOBBY_NON_MODERATORS -> return "lobby_non_moderators"
LOBBY_OPEN_TO_EVERYONE -> return "lobby_timer_reached"
else -> return ""
}
}
}

View File

@ -0,0 +1,39 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.newarch.local.dao
import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.nextcloud.talk.models.json.chat.ChatMessage
import com.nextcloud.talk.newarch.local.models.ConversationEntity
import com.nextcloud.talk.newarch.local.models.MessageEntity
@Dao
abstract class MessagesDao {
@Query("SELECT * FROM messages WHERE id = :userId AND conversation = :conversationId")
abstract fun getMessagesWithUserForConversation(userId: Long, conversationId: String): LiveData<List<MessageEntity>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract suspend fun saveMessages(vararg messages: MessageEntity)
}

View File

@ -0,0 +1,47 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.newarch.local.dao
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.nextcloud.talk.newarch.local.models.UserNgEntity
@Dao
abstract class UsersDao {
@Query("DELETE FROM users WHERE id = :userId")
abstract fun deleteUserForId(userId: Long)
@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract fun saveUser(user: UserNgEntity)
@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract suspend fun saveUsers(vararg users: UserNgEntity)
// get all users not scheduled for deletion
@Query("SELECT * FROM users where status != 2")
abstract fun getUsers(): List<UserNgEntity>
@Query("SELECT * FROM users where status = 2")
abstract fun getUsersScheduledForDeletion(): List<UserNgEntity>
}

View File

@ -34,15 +34,18 @@ import com.nextcloud.talk.newarch.local.converters.LobbyStateConverter
import com.nextcloud.talk.newarch.local.converters.NotificationLevelConverter import com.nextcloud.talk.newarch.local.converters.NotificationLevelConverter
import com.nextcloud.talk.newarch.local.converters.ParticipantTypeConverter import com.nextcloud.talk.newarch.local.converters.ParticipantTypeConverter
import com.nextcloud.talk.newarch.local.converters.PushConfigurationConverter import com.nextcloud.talk.newarch.local.converters.PushConfigurationConverter
import com.nextcloud.talk.newarch.local.converters.SystemMessageTypeConverter
import com.nextcloud.talk.newarch.local.converters.UserStatusConverter import com.nextcloud.talk.newarch.local.converters.UserStatusConverter
import com.nextcloud.talk.newarch.local.dao.ConversationsDao import com.nextcloud.talk.newarch.local.dao.ConversationsDao
import com.nextcloud.talk.newarch.local.dao.MessagesDao
import com.nextcloud.talk.newarch.local.dao.UsersDao
import com.nextcloud.talk.newarch.local.models.ConversationEntity import com.nextcloud.talk.newarch.local.models.ConversationEntity
import com.nextcloud.talk.newarch.local.models.MessageEntity import com.nextcloud.talk.newarch.local.models.MessageEntity
import com.nextcloud.talk.newarch.local.models.UserEntityNg import com.nextcloud.talk.newarch.local.models.UserNgEntity
@Database( @Database(
entities = [ConversationEntity::class, MessageEntity::class, UserEntityNg::class], entities = [ConversationEntity::class, MessageEntity::class, UserNgEntity::class],
version = 4, version = 1,
exportSchema = true exportSchema = true
) )
@TypeConverters( @TypeConverters(
@ -51,12 +54,14 @@ import com.nextcloud.talk.newarch.local.models.UserEntityNg
ConversationTypeConverter::class, ParticipantTypeConverter::class, ConversationTypeConverter::class, ParticipantTypeConverter::class,
PushConfigurationConverter::class, CapabilitiesConverter::class, PushConfigurationConverter::class, CapabilitiesConverter::class,
ExternalSignalingConverter::class, ExternalSignalingConverter::class,
UserStatusConverter::class UserStatusConverter::class, SystemMessageTypeConverter::class
) )
abstract class TalkDatabase : RoomDatabase() { abstract class TalkDatabase : RoomDatabase() {
abstract fun conversationsDao(): ConversationsDao abstract fun conversationsDao(): ConversationsDao
abstract fun messagesDao(): MessagesDao
abstract fun usersDao(): UsersDao
companion object { companion object {
private const val DB_NAME = "talk.db" private const val DB_NAME = "talk.db"

View File

@ -24,6 +24,7 @@ import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.ForeignKey import androidx.room.ForeignKey
import androidx.room.ForeignKey.CASCADE import androidx.room.ForeignKey.CASCADE
import androidx.room.Index
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import com.nextcloud.talk.models.json.chat.ChatMessage import com.nextcloud.talk.models.json.chat.ChatMessage
import com.nextcloud.talk.models.json.conversations.Conversation import com.nextcloud.talk.models.json.conversations.Conversation
@ -34,15 +35,19 @@ import com.nextcloud.talk.models.json.conversations.Conversation.NotificationLev
import com.nextcloud.talk.models.json.participants.Participant.ParticipantType import com.nextcloud.talk.models.json.participants.Participant.ParticipantType
import java.util.HashMap import java.util.HashMap
@Entity(tableName = "conversations", @Entity(
foreignKeys = arrayOf( tableName = "conversations",
ForeignKey(entity = UserEntityNg::class, indices = [Index(value = ["user"])],
foreignKeys = [ForeignKey(
entity = UserNgEntity::class,
parentColumns = arrayOf("id"), parentColumns = arrayOf("id"),
childColumns = arrayOf("user"), childColumns = arrayOf("user"),
onDelete = CASCADE) onDelete = CASCADE,
)) deferred = true
)]
)
data class ConversationEntity( data class ConversationEntity(
@PrimaryKey(autoGenerate = true) var id: Long? = null, @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") var id: Long? = null,
@ColumnInfo(name = "user") var user: Long?, @ColumnInfo(name = "user") var user: Long?,
@ColumnInfo(name = "conversation_id") var conversationId: String?, @ColumnInfo(name = "conversation_id") var conversationId: String?,
@ColumnInfo(name = "token") var token: String? = null, @ColumnInfo(name = "token") var token: String? = null,
@ -72,7 +77,7 @@ data class ConversationEntity(
) var conversationReadOnlyState: ConversationReadOnlyState? = null, ) var conversationReadOnlyState: ConversationReadOnlyState? = null,
@ColumnInfo(name = "lobby_state") var lobbyState: LobbyState? = null, @ColumnInfo(name = "lobby_state") var lobbyState: LobbyState? = null,
@ColumnInfo(name = "lobby_timer") var lobbyTimer: Long? = null, @ColumnInfo(name = "lobby_timer") var lobbyTimer: Long? = null,
@ColumnInfo(name = "last_read_message_id") var lastReadMessageId: Int = 0, @ColumnInfo(name = "last_read_message_id") var lastReadMessageId: Long = 0,
@ColumnInfo(name = "modified_at") var modifiedAt: Long? = null, @ColumnInfo(name = "modified_at") var modifiedAt: Long? = null,
@ColumnInfo(name = "changing") var changing: Boolean = false @ColumnInfo(name = "changing") var changing: Boolean = false
) )
@ -111,7 +116,8 @@ fun ConversationEntity.toConversation(): Conversation {
} }
fun Conversation.toConversationEntity(): ConversationEntity { fun Conversation.toConversationEntity(): ConversationEntity {
val conversationEntity = ConversationEntity(this.internalId, this.internalUserId, this.conversationId) val conversationEntity =
ConversationEntity(this.internalId, this.internalUserId, this.conversationId)
conversationEntity.token = this.token conversationEntity.token = this.token
conversationEntity.name = this.name conversationEntity.name = this.name
conversationEntity.displayName = this.displayName conversationEntity.displayName = this.displayName

View File

@ -20,20 +20,72 @@
package com.nextcloud.talk.newarch.local.models package com.nextcloud.talk.newarch.local.models
import androidx.annotation.NonNull
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.ForeignKey import androidx.room.ForeignKey
import androidx.room.Index
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import androidx.room.RoomWarnings
import com.nextcloud.talk.models.json.chat.ChatMessage
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType
@Entity(tableName = "messages", @Entity(
foreignKeys = arrayOf( tableName = "messages",
ForeignKey(entity = UserEntityNg::class, indices = [Index(value = ["conversation"]), Index(value = ["user", "conversation"])],
foreignKeys = [ForeignKey(
entity = ConversationEntity::class,
parentColumns = arrayOf("id"), parentColumns = arrayOf("id"),
childColumns = arrayOf("user"), childColumns = arrayOf("conversation"),
onDelete = ForeignKey.CASCADE onDelete = ForeignKey.CASCADE,
deferred = true
)]
) )
))data class MessageEntity( data class MessageEntity(
@PrimaryKey(autoGenerate = true) var id: Long = 0, @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") var id: Long? = null,
@NonNull @ColumnInfo(name = "user") var user: Long? = null @ColumnInfo(name = "user") var user: Long? = 0,
@ColumnInfo(name = "conversation") var conversation: Long? = null,
@ColumnInfo(name = "message_id") var messageId: Long = 0,
@ColumnInfo(name = "actor_id") var actorId: String? = null,
@ColumnInfo(name = "actor_type") var actorType: String? = null,
@ColumnInfo(name = "actor_display_name") var actorDisplayName: String? = null,
@ColumnInfo(name = "timestamp") var timestamp: Long = 0,
@ColumnInfo(name = "message") var message: String? = null,
/*@JsonField(name = "messageParameters")
public HashMap<String, HashMap<String, String>> messageParameters;*/
@ColumnInfo(name = "system_message_type") var systemMessageType: SystemMessageType? = null
) )
@SuppressWarnings(RoomWarnings.CURSOR_MISMATCH)
fun MessageEntity.toChatMessage(): ChatMessage {
val chatMessage = ChatMessage()
chatMessage.internalMessageId = this.id
chatMessage.internalUserId = this.user
chatMessage.internalConversationId = this.conversation
chatMessage.jsonMessageId = this.messageId
chatMessage.actorType = this.actorType
chatMessage.actorId = this.actorId
chatMessage.actorDisplayName = this.actorDisplayName
chatMessage.timestamp = this.timestamp
chatMessage.message = this.message
//chatMessage.messageParameters = this.messageParameters
chatMessage.systemMessageType = this.systemMessageType
return chatMessage
}
@SuppressWarnings(RoomWarnings.CURSOR_MISMATCH)
fun ChatMessage.toMessageEntity(): MessageEntity {
val messageEntity = MessageEntity()
messageEntity.id = this.internalMessageId
messageEntity.user = this.internalUserId
messageEntity.conversation = this.internalConversationId
messageEntity.messageId = this.jsonMessageId
messageEntity.actorType = this.actorType
messageEntity.actorId = this.actorId
messageEntity.actorDisplayName = this.actorDisplayName
messageEntity.timestamp = this.timestamp
messageEntity.message = this.message
messageEntity.systemMessageType = this.systemMessageType
//messageEntity.messageParameters = this.messageParameters
return messageEntity
}

View File

@ -29,8 +29,8 @@ import com.nextcloud.talk.models.json.push.PushConfigurationState
import com.nextcloud.talk.newarch.local.models.other.UserStatus import com.nextcloud.talk.newarch.local.models.other.UserStatus
@Entity(tableName = "users") @Entity(tableName = "users")
data class UserEntityNg( data class UserNgEntity(
@PrimaryKey(autoGenerate = true) var id: Long = 0, @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") var id: Long? = null,
@ColumnInfo(name = "user_id") var userId: String? = null, @ColumnInfo(name = "user_id") var userId: String? = null,
@ColumnInfo(name = "username") var username: String? = null, @ColumnInfo(name = "username") var username: String? = null,
@ColumnInfo(name = "token") var token: String? = null, @ColumnInfo(name = "token") var token: String? = null,