Commit 76b6fe16 authored by Lucio Maciel's avatar Lucio Maciel

Fixed merging issues and save attachments

parent c63e1da7
......@@ -152,6 +152,8 @@ dependencies {
implementation libraries.livedataKtx
implementation 'com.google.code.findbugs:jsr305:3.0.2'
// Proprietary libraries
playImplementation libraries.fcm
playImplementation libraries.firebaseAnalytics
......
This diff is collapsed.
......@@ -39,20 +39,6 @@ class ChatRoomFragmentModule {
return CancelStrategy(owner, jobs)
}
@Provides
@PerFragment
@Named("currentServer")
fun provideCurrentServer(currentServerInteractor: GetCurrentServerInteractor): String {
return currentServerInteractor.get()!!
}
@Provides
@PerFragment
fun provideDatabaseManager(factory: DatabaseManagerFactory,
@Named("currentServer") currentServer: String): DatabaseManager {
return factory.create(currentServer)
}
@Provides
@PerFragment
fun provideChatRoomDao(manager: DatabaseManager): ChatRoomDao = manager.chatRoomDao()
......
......@@ -14,6 +14,7 @@ import chat.rocket.android.db.model.ReactionMessageRelation
import chat.rocket.android.db.model.UrlEntity
import chat.rocket.android.db.model.UserEntity
import chat.rocket.android.db.model.UserStatus
import chat.rocket.android.db.model.asEntity
import chat.rocket.android.util.extensions.removeTrailingSlash
import chat.rocket.android.util.extensions.toEntity
import chat.rocket.android.util.extensions.userId
......@@ -113,12 +114,23 @@ class DatabaseManager(val context: Application,
Timber.d("Running ChatRooms transaction: remove: $toRemove - insert: $toInsert - update: $filteredUpdate")
chatRoomDao().update(filteredInsert, filteredUpdate, toRemove.toList())
//updateMessages(batch)
} catch (ex: Exception) {
Timber.d(ex, "Error updating chatrooms")
}
}
}
private fun updateMessages(batch: List<StreamMessage<BaseRoom>>) {
val list = batch.filterNot { it.type == Type.Removed }
.filter { it.data is Room }
.filterNot { (it.data as Room).lastMessage == null }
.map { (it.data as Room).lastMessage!! }
processMessagesBatch(list)
}
fun updateSelfUser(myself: Myself) {
launch(dbContext) {
val user = userDao().getUser(myself.id)
......@@ -157,7 +169,7 @@ class DatabaseManager(val context: Application,
private suspend fun createMessageEntities(message: Message): Pair<MessageEntity, List<BaseMessageEntity>> {
val messageEntity = message.toEntity()
val list = mutableListOf<BaseMessageEntity>()
//createAttachments(message)?.let {}
createAttachments(message)?.let { list.addAll(it) }
createFavoriteRelations(message)?.let { list.addAll(it) }
createMentionRelations(message)?.let { list.addAll(it) }
createChannelRelations(message)?.let { list.addAll(it) }
......@@ -174,11 +186,13 @@ class DatabaseManager(val context: Application,
return null
}
val reactions = message.reactions!!
val list = mutableListOf<BaseMessageEntity>()
message.reactions!!.keys.forEach { reaction ->
reactions.keys.forEach { reaction ->
list.add(ReactionEntity(reaction))
val users = message.reactions!![reaction]
val users = reactions[reaction]
users?.size?.let { size ->
list.add(ReactionMessageRelation(reaction, message.id, size))
}
......@@ -247,10 +261,13 @@ class DatabaseManager(val context: Application,
return null
}
message.attachments!!.forEach {
val list = ArrayList<BaseMessageEntity>(message.attachments!!.size)
message.attachments!!.forEach { attachment ->
list.addAll(attachment.asEntity(message.id))
}
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
return list
}
private suspend fun createUpdates(): List<ChatRoomEntity> {
......
......@@ -4,6 +4,15 @@ import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.PrimaryKey
import chat.rocket.android.util.extension.orFalse
import chat.rocket.core.model.attachment.Attachment
import chat.rocket.core.model.attachment.AudioAttachment
import chat.rocket.core.model.attachment.AuthorAttachment
import chat.rocket.core.model.attachment.ColorAttachment
import chat.rocket.core.model.attachment.ImageAttachment
import chat.rocket.core.model.attachment.MessageAttachment
import chat.rocket.core.model.attachment.VideoAttachment
import timber.log.Timber
@Entity(tableName = "attachments",
foreignKeys = [
......@@ -12,47 +21,47 @@ import androidx.room.PrimaryKey
])
data class AttachmentEntity(
@PrimaryKey
val id: String,
var id: String,
@ColumnInfo(name = "message_id")
val messageId: String,
val title: String?,
val type: String?,
val description: String?,
val text: String?,
val title: String? = null,
val type: String? = null,
val description: String? = null,
val text: String? = null,
@ColumnInfo(name = "author_name")
val authorName: String?,
val authorName: String? = null,
@ColumnInfo(name = "author_icon")
val authorIcon: String?,
val authorIcon: String? = null,
@ColumnInfo(name = "author_link")
val authorLink: String?,
val authorLink: String? = null,
@ColumnInfo(name = "thumb_url")
val thumbUrl: String?,
val color: String?,
val thumbUrl: String? = null,
val color: String? = null,
@ColumnInfo(name = "title_link")
val titleLink: String?,
val titleLink: String? = null,
@ColumnInfo(name = "title_link_download")
val titleLinkDownload: String?,
val titleLinkDownload: Boolean = false,
@ColumnInfo(name = "image_url")
val imageUrl: String?,
val imageUrl: String? = null,
@ColumnInfo(name = "image_type")
val imageType: String?,
val imageType: String? = null,
@ColumnInfo(name = "image_size")
val imageSize: String?,
val imageSize: Long? = null,
@ColumnInfo(name = "video_url")
val videoUrl: String?,
val videoUrl: String? = null,
@ColumnInfo(name = "video_type")
val videoType: String?,
val videoType: String? = null,
@ColumnInfo(name = "video_size")
val videoSize: String?,
val videoSize: Long? = null,
@ColumnInfo(name = "audio_url")
val audioUrl: String?,
val audioUrl: String? = null,
@ColumnInfo(name = "audio_type")
val audioType: String?,
val audioType: String? = null,
@ColumnInfo(name = "audio_size")
val audioSize: String?,
val audioSize: Long? = null,
@ColumnInfo(name = "message_link")
val messageLink: String?,
val timestamp: Long?
val messageLink: String? = null,
val timestamp: Long? = null
) : BaseMessageEntity
@Entity(tableName = "attachment_fields",
......@@ -67,4 +76,106 @@ data class AttachmentFieldEntity(
) : BaseMessageEntity {
@PrimaryKey(autoGenerate = true)
var id: Long? = null
}
\ No newline at end of file
}
fun Attachment.asEntity(msgId: String): List<BaseMessageEntity> {
return when(this) {
is ImageAttachment -> listOf(asEntity(msgId))
is VideoAttachment -> listOf(asEntity(msgId))
is AudioAttachment -> listOf(asEntity(msgId))
is AuthorAttachment -> asEntity(msgId)
is ColorAttachment -> listOf(asEntity(msgId))
is MessageAttachment -> listOf(asEntity(msgId))
// TODO - Action Attachments
else -> {
Timber.d("Missing conversion for: ${javaClass.canonicalName}")
emptyList()
}
}
}
fun ImageAttachment.asEntity(msgId: String): AttachmentEntity =
AttachmentEntity(
id = "${msgId}_${hashCode()}",
messageId = msgId,
title = title,
description = description,
text = text,
titleLink = titleLink,
titleLinkDownload = titleLinkDownload.orFalse(),
imageUrl = url,
imageType = type,
imageSize = size
)
fun VideoAttachment.asEntity(msgId: String): AttachmentEntity =
AttachmentEntity(
id = "${msgId}_${hashCode()}",
messageId = msgId,
title = title,
description = description,
text = text,
titleLink = titleLink,
titleLinkDownload = titleLinkDownload.orFalse(),
videoUrl = url,
videoType = type,
videoSize = size
)
fun AudioAttachment.asEntity(msgId: String): AttachmentEntity =
AttachmentEntity(
id = "${msgId}_${hashCode()}",
messageId = msgId,
title = title,
description = description,
text = text,
titleLink = titleLink,
titleLinkDownload = titleLinkDownload.orFalse(),
audioUrl = url,
audioType = type,
audioSize = size
)
fun AuthorAttachment.asEntity(msgId: String): List<BaseMessageEntity> {
val list = mutableListOf<BaseMessageEntity>()
val attachment = AttachmentEntity(
id = "${msgId}_${hashCode()}",
messageId = msgId,
authorLink = url,
authorIcon = authorIcon,
authorName = authorName
)
list.add(attachment)
fields?.forEach { field ->
val entity = AttachmentFieldEntity(
attachmentId = attachment.id,
title = field.title,
value = field.value
)
list.add(entity)
}
return list
}
fun ColorAttachment.asEntity(msgId: String): AttachmentEntity =
AttachmentEntity(
id = "${msgId}_${hashCode()}",
messageId = msgId,
color = color.rawColor
)
// TODO - how to model An message attachment with attachments???
fun MessageAttachment.asEntity(msgId: String): AttachmentEntity =
AttachmentEntity(
id = "${msgId}_${hashCode()}",
messageId = msgId,
authorName = author,
authorIcon = icon,
text = text,
thumbUrl = thumbUrl,
color = color?.rawColor,
messageLink = url,
timestamp = timestamp
)
\ No newline at end of file
......@@ -12,6 +12,7 @@ import chat.rocket.core.internal.realtime.socket.connect
import chat.rocket.core.internal.realtime.socket.disconnect
import chat.rocket.core.internal.realtime.socket.model.State
import chat.rocket.core.internal.realtime.socket.model.StreamMessage
import chat.rocket.core.internal.realtime.socket.model.Type
import chat.rocket.core.internal.realtime.subscribeActiveUsers
import chat.rocket.core.internal.realtime.subscribeRoomMessages
import chat.rocket.core.internal.realtime.subscribeRooms
......@@ -129,9 +130,9 @@ class ConnectionManager(
}
val messagesActor = createBatchActor<Message>(messagesContext, parent = connectJob,
maxSize = 100, maxTime = 300) { messages ->
maxSize = 100, maxTime = 500) { messages ->
Timber.d("Processing Messages batch: ${messages.size}")
dbManager.processMessagesBatch(messages)
dbManager.processMessagesBatch(messages.distinctBy { it.id })
}
// stream-notify-user - ${userId}/rooms-changed
......@@ -139,6 +140,11 @@ class ConnectionManager(
for (room in client.roomsChannel) {
Timber.d("GOT Room streamed")
roomsActor.send(room)
if (room.type != Type.Removed) {
room.data.lastMessage?.let {
messagesActor.send(it)
}
}
}
}
......
......@@ -9,7 +9,7 @@ import kotlinx.coroutines.experimental.launch
inline fun Fragment.ui(crossinline block: (activity: FragmentActivity) -> Unit): Job? {
// Checking first for activity and view saves us from some synchronyzed and thread local checks
if (activity != null && view != null) {
if (activity != null && view != null && context != null) {
// If we already are running on the Main Thread (UI Thread), just go ahead and execute the block
return if (Looper.getMainLooper() == Looper.myLooper()) {
block(activity!!)
......@@ -17,7 +17,7 @@ inline fun Fragment.ui(crossinline block: (activity: FragmentActivity) -> Unit):
} else {
// Launch a Job on the UI context and check again if the activity and view are still valid
launch(UI) {
if (activity != null && view != null) {
if (activity != null && view != null && context != null) {
block(activity!!)
}
}
......
......@@ -4,12 +4,10 @@ import chat.rocket.android.db.model.MessageEntity
import chat.rocket.android.server.domain.model.Account
import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.util.retryIO
import chat.rocket.core.RocketChatClient
import chat.rocket.core.internal.rest.registerPushToken
import chat.rocket.core.model.Message
import chat.rocket.core.model.asString
import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.withContext
import timber.log.Timber
......
package chat.rocket.android.util.extension
fun Boolean?.orFalse(): Boolean = this ?: false
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment