Unverified Commit f6b95022 authored by Rafael Kellermann Streit's avatar Rafael Kellermann Streit Committed by GitHub

Merge pull request #1669 from RocketChat/feature/db-save-messages

[FEATURE] Initial message db support
parents 6d35b48e e31ae695
...@@ -152,6 +152,8 @@ dependencies { ...@@ -152,6 +152,8 @@ dependencies {
implementation libraries.livedataKtx implementation libraries.livedataKtx
implementation 'com.google.code.findbugs:jsr305:3.0.2'
// Proprietary libraries // Proprietary libraries
playImplementation libraries.fcm playImplementation libraries.fcm
playImplementation libraries.firebaseAnalytics playImplementation libraries.firebaseAnalytics
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
673693445664
673693445664
...@@ -326,7 +326,7 @@ class LoginPresenter @Inject constructor( ...@@ -326,7 +326,7 @@ class LoginPresenter @Inject constructor(
getCustomOauthScope(serviceMap) ?: "openid" getCustomOauthScope(serviceMap) ?: "openid"
) )
} }
wordpressOauthUrl?.let { wordpressOauthUrl.let {
view.setupWordpressButtonListener(it, state) view.setupWordpressButtonListener(it, state)
view.enableLoginByWordpress() view.enableLoginByWordpress()
totalSocialAccountsEnabled++ totalSocialAccountsEnabled++
......
...@@ -51,7 +51,7 @@ class ActionsListAdapter(actions: List<Action>, var actionAttachmentOnClickListe ...@@ -51,7 +51,7 @@ class ActionsListAdapter(actions: List<Action>, var actionAttachmentOnClickListe
action_button.isVisible = true action_button.isVisible = true
action_image_button.isVisible = false action_image_button.isVisible = false
this.action_button.setText(action.text) this.action_button.text = action.text
} }
} }
} }
......
...@@ -190,7 +190,7 @@ class ChatRoomAdapter( ...@@ -190,7 +190,7 @@ class ChatRoomAdapter(
notifyDataSetChanged() notifyDataSetChanged()
} }
fun updateItem(message: BaseUiModel<*>) { fun updateItem(message: BaseUiModel<*>): Boolean {
val index = dataSet.indexOfLast { it.messageId == message.messageId } val index = dataSet.indexOfLast { it.messageId == message.messageId }
val indexOfNext = dataSet.indexOfFirst { it.messageId == message.messageId } val indexOfNext = dataSet.indexOfFirst { it.messageId == message.messageId }
Timber.d("index: $index") Timber.d("index: $index")
...@@ -209,7 +209,9 @@ class ChatRoomAdapter( ...@@ -209,7 +209,9 @@ class ChatRoomAdapter(
dataSet.removeAt(indexOfNext) dataSet.removeAt(indexOfNext)
notifyItemRemoved(indexOfNext) notifyItemRemoved(indexOfNext)
} }
return true
} }
return false
} }
fun removeItem(messageId: String) { fun removeItem(messageId: String) {
......
package chat.rocket.android.chatroom.adapter package chat.rocket.android.chatroom.adapter
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import android.text.method.LinkMovementMethod import android.text.method.LinkMovementMethod
import android.view.View import android.view.View
import androidx.core.view.isVisible
import androidx.core.widget.ImageViewCompat
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.chatroom.uimodel.ColorAttachmentUiModel import chat.rocket.android.chatroom.uimodel.ColorAttachmentUiModel
import chat.rocket.android.emoji.EmojiReactionListener import chat.rocket.android.emoji.EmojiReactionListener
...@@ -15,8 +18,7 @@ class ColorAttachmentViewHolder(itemView: View, ...@@ -15,8 +18,7 @@ class ColorAttachmentViewHolder(itemView: View,
reactionListener: EmojiReactionListener? = null) reactionListener: EmojiReactionListener? = null)
: BaseViewHolder<ColorAttachmentUiModel>(itemView, listener, reactionListener) { : BaseViewHolder<ColorAttachmentUiModel>(itemView, listener, reactionListener) {
val drawable: Drawable? = ContextCompat.getDrawable(itemView.context, val drawable: Drawable = ColorDrawable(ContextCompat.getColor(itemView.context, R.color.quoteBar))
R.drawable.quote_vertical_gray_bar)
init { init {
with(itemView) { with(itemView) {
...@@ -27,10 +29,20 @@ class ColorAttachmentViewHolder(itemView: View, ...@@ -27,10 +29,20 @@ class ColorAttachmentViewHolder(itemView: View,
override fun bindViews(data: ColorAttachmentUiModel) { override fun bindViews(data: ColorAttachmentUiModel) {
with(itemView) { with(itemView) {
drawable?.let { quote_bar.setColorFilter(data.color)
quote_bar.background = drawable.mutate().apply { setTint(data.color) } if (data.text.isNotEmpty()) {
attachment_text.text = data.text attachment_text.isVisible = true
} attachment_text.text = data.text
} else {
attachment_text.isVisible = false
}
if (data.fields.isNullOrEmpty()) {
text_fields.isVisible = false
} else {
text_fields.isVisible = true
text_fields.text = data.fields
}
} }
} }
......
...@@ -5,9 +5,14 @@ import chat.rocket.android.chatroom.presentation.ChatRoomView ...@@ -5,9 +5,14 @@ import chat.rocket.android.chatroom.presentation.ChatRoomView
import chat.rocket.android.chatroom.ui.ChatRoomFragment import chat.rocket.android.chatroom.ui.ChatRoomFragment
import chat.rocket.android.core.lifecycle.CancelStrategy import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.dagger.scope.PerFragment import chat.rocket.android.dagger.scope.PerFragment
import chat.rocket.android.db.ChatRoomDao
import chat.rocket.android.db.DatabaseManager
import chat.rocket.android.db.DatabaseManagerFactory
import chat.rocket.android.server.domain.GetCurrentServerInteractor
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import kotlinx.coroutines.experimental.Job import kotlinx.coroutines.experimental.Job
import javax.inject.Named
@Module @Module
class ChatRoomFragmentModule { class ChatRoomFragmentModule {
...@@ -33,4 +38,8 @@ class ChatRoomFragmentModule { ...@@ -33,4 +38,8 @@ class ChatRoomFragmentModule {
fun provideCancelStrategy(owner: LifecycleOwner, jobs: Job): CancelStrategy { fun provideCancelStrategy(owner: LifecycleOwner, jobs: Job): CancelStrategy {
return CancelStrategy(owner, jobs) return CancelStrategy(owner, jobs)
} }
@Provides
@PerFragment
fun provideChatRoomDao(manager: DatabaseManager): ChatRoomDao = manager.chatRoomDao()
} }
...@@ -28,7 +28,6 @@ import chat.rocket.android.server.domain.JobSchedulerInteractor ...@@ -28,7 +28,6 @@ import chat.rocket.android.server.domain.JobSchedulerInteractor
import chat.rocket.android.server.domain.MessagesRepository import chat.rocket.android.server.domain.MessagesRepository
import chat.rocket.android.server.domain.PermissionsInteractor import chat.rocket.android.server.domain.PermissionsInteractor
import chat.rocket.android.server.domain.PublicSettings import chat.rocket.android.server.domain.PublicSettings
import chat.rocket.android.server.domain.RoomRepository
import chat.rocket.android.server.domain.UsersRepository import chat.rocket.android.server.domain.UsersRepository
import chat.rocket.android.server.domain.uploadMaxFileSize import chat.rocket.android.server.domain.uploadMaxFileSize
import chat.rocket.android.server.domain.uploadMimeTypeFilter import chat.rocket.android.server.domain.uploadMimeTypeFilter
...@@ -92,7 +91,6 @@ class ChatRoomPresenter @Inject constructor( ...@@ -92,7 +91,6 @@ class ChatRoomPresenter @Inject constructor(
private val uriInteractor: UriInteractor, private val uriInteractor: UriInteractor,
private val messagesRepository: MessagesRepository, private val messagesRepository: MessagesRepository,
private val usersRepository: UsersRepository, private val usersRepository: UsersRepository,
private val roomsRepository: RoomRepository,
private val localRepository: LocalRepository, private val localRepository: LocalRepository,
private val analyticsManager: AnalyticsManager, private val analyticsManager: AnalyticsManager,
private val userHelper: UserHelper, private val userHelper: UserHelper,
...@@ -303,7 +301,7 @@ class ChatRoomPresenter @Inject constructor( ...@@ -303,7 +301,7 @@ class ChatRoomPresenter @Inject constructor(
type = null, type = null,
updatedAt = null, updatedAt = null,
urls = null, urls = null,
isTemporary = true, synced = false,
unread = true unread = true
) )
try { try {
...@@ -315,6 +313,7 @@ class ChatRoomPresenter @Inject constructor( ...@@ -315,6 +313,7 @@ class ChatRoomPresenter @Inject constructor(
), false ), false
) )
client.sendMessage(id, chatRoomId, text) client.sendMessage(id, chatRoomId, text)
messagesRepository.save(newMessage.copy(synced = true))
logMessageSent() logMessageSent()
} catch (ex: Exception) { } catch (ex: Exception) {
// Ok, not very beautiful, but the backend sends us a not valid response // Ok, not very beautiful, but the backend sends us a not valid response
...@@ -504,7 +503,7 @@ class ChatRoomPresenter @Inject constructor( ...@@ -504,7 +503,7 @@ class ChatRoomPresenter @Inject constructor(
val messages = val messages =
retryIO(description = "history($chatRoomId, $roomType, $instant)") { retryIO(description = "history($chatRoomId, $roomType, $instant)") {
client.history( client.history(
chatRoomId!!, roomType, count = 50, chatRoomId, roomType, count = 50,
oldest = instant oldest = instant
) )
} }
...@@ -713,6 +712,7 @@ class ChatRoomPresenter @Inject constructor( ...@@ -713,6 +712,7 @@ class ChatRoomPresenter @Inject constructor(
client.getMembers(chatRoomId, roomTypeOf(chatRoomType), offset, 50).result client.getMembers(chatRoomId, roomTypeOf(chatRoomType), offset, 50).result
}.take(50) // Get only 50, the backend is returning 7k+ users }.take(50) // Get only 50, the backend is returning 7k+ users
usersRepository.saveAll(members) usersRepository.saveAll(members)
dbManager.processUsersBatch(members)
val self = localRepository.get(LocalRepository.CURRENT_USERNAME_KEY) val self = localRepository.get(LocalRepository.CURRENT_USERNAME_KEY)
// Take at most the 100 most recent messages distinguished by user. Can return less. // Take at most the 100 most recent messages distinguished by user. Can return less.
val recentMessages = messagesRepository.getRecentMessages(chatRoomId, 100) val recentMessages = messagesRepository.getRecentMessages(chatRoomId, 100)
...@@ -785,9 +785,6 @@ class ChatRoomPresenter @Inject constructor( ...@@ -785,9 +785,6 @@ class ChatRoomPresenter @Inject constructor(
}.filterNot { filterSelfOut && self != null && self == it.text }) }.filterNot { filterSelfOut && self != null && self == it.text })
} }
ROOMS -> { ROOMS -> {
if (rooms.isNotEmpty()) {
roomsRepository.saveAll(rooms)
}
view.populateRoomSuggestions(rooms.map { view.populateRoomSuggestions(rooms.map {
val fullName = it.fullName ?: "" val fullName = it.fullName ?: ""
val name = it.name ?: "" val name = it.name ?: ""
...@@ -1125,11 +1122,11 @@ class ChatRoomPresenter @Inject constructor( ...@@ -1125,11 +1122,11 @@ class ChatRoomPresenter @Inject constructor(
val index = roomMessages.indexOfFirst { msg -> msg.id == streamedMessage.id } val index = roomMessages.indexOfFirst { msg -> msg.id == streamedMessage.id }
if (index > -1) { if (index > -1) {
Timber.d("Updating message at $index") Timber.d("Updating message at $index")
messagesRepository.save(streamedMessage) //messagesRepository.save(streamedMessage)
view.dispatchUpdateMessage(index, viewModelStreamedMessage) view.dispatchUpdateMessage(index, viewModelStreamedMessage)
} else { } else {
Timber.d("Adding new message") Timber.d("Adding new message")
messagesRepository.save(streamedMessage) //messagesRepository.save(streamedMessage)
view.showNewMessage(viewModelStreamedMessage, true) view.showNewMessage(viewModelStreamedMessage, true)
} }
} }
......
...@@ -2,9 +2,11 @@ package chat.rocket.android.chatroom.service ...@@ -2,9 +2,11 @@ package chat.rocket.android.chatroom.service
import android.app.job.JobParameters import android.app.job.JobParameters
import android.app.job.JobService import android.app.job.JobService
import chat.rocket.android.server.domain.CurrentServerRepository import chat.rocket.android.db.DatabaseManagerFactory
import chat.rocket.android.server.domain.MessagesRepository import chat.rocket.android.server.domain.GetAccountsInteractor
import chat.rocket.android.server.infraestructure.ConnectionManagerFactory import chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import chat.rocket.android.server.infraestructure.DatabaseMessageMapper
import chat.rocket.android.server.infraestructure.DatabaseMessagesRepository
import chat.rocket.core.internal.rest.sendMessage import chat.rocket.core.internal.rest.sendMessage
import chat.rocket.core.model.Message import chat.rocket.core.model.Message
import dagger.android.AndroidInjection import dagger.android.AndroidInjection
...@@ -17,9 +19,9 @@ class MessageService : JobService() { ...@@ -17,9 +19,9 @@ class MessageService : JobService() {
@Inject @Inject
lateinit var factory: ConnectionManagerFactory lateinit var factory: ConnectionManagerFactory
@Inject @Inject
lateinit var currentServerRepository: CurrentServerRepository lateinit var dbFactory: DatabaseManagerFactory
@Inject @Inject
lateinit var messageRepository: MessagesRepository lateinit var getAccountsInteractor: GetAccountsInteractor
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
...@@ -32,21 +34,21 @@ class MessageService : JobService() { ...@@ -32,21 +34,21 @@ class MessageService : JobService() {
override fun onStartJob(params: JobParameters?): Boolean { override fun onStartJob(params: JobParameters?): Boolean {
launch(CommonPool) { launch(CommonPool) {
val currentServer = currentServerRepository.get() getAccountsInteractor.get().forEach { account ->
if (currentServer != null) { retrySendingMessages(params, account.serverUrl)
retrySendingMessages(params, currentServer)
jobFinished(params, false)
} }
jobFinished(params, false)
} }
return true return true
} }
private suspend fun retrySendingMessages(params: JobParameters?, currentServer: String) { private suspend fun retrySendingMessages(params: JobParameters?, serverUrl: String) {
val dbManager = dbFactory.create(serverUrl)
val messageRepository = DatabaseMessagesRepository(dbManager, DatabaseMessageMapper(dbManager))
val temporaryMessages = messageRepository.getAllUnsent() val temporaryMessages = messageRepository.getAllUnsent()
.sortedWith(compareBy(Message::timestamp)) .sortedWith(compareBy(Message::timestamp))
if (temporaryMessages.isNotEmpty()) { if (temporaryMessages.isNotEmpty()) {
val connectionManager = factory.create(currentServer) val client = factory.create(serverUrl).client
val client = connectionManager.client
temporaryMessages.forEach { message -> temporaryMessages.forEach { message ->
try { try {
client.sendMessage( client.sendMessage(
...@@ -57,7 +59,7 @@ class MessageService : JobService() { ...@@ -57,7 +59,7 @@ class MessageService : JobService() {
attachments = message.attachments, attachments = message.attachments,
alias = message.senderAlias alias = message.senderAlias
) )
messageRepository.save(message.copy(isTemporary = false)) messageRepository.save(message.copy(synced = true))
Timber.d("Sent scheduled message given by id: ${message.id}") Timber.d("Sent scheduled message given by id: ${message.id}")
} catch (ex: Exception) { } catch (ex: Exception) {
Timber.e(ex) Timber.e(ex)
...@@ -71,7 +73,7 @@ class MessageService : JobService() { ...@@ -71,7 +73,7 @@ class MessageService : JobService() {
// some other error // some other error
if (ex.message?.contains("E11000", true) == true) { if (ex.message?.contains("E11000", true) == true) {
// XXX: Temporary solution. We need proper error codes from the api. // XXX: Temporary solution. We need proper error codes from the api.
messageRepository.save(message.copy(isTemporary = false)) messageRepository.save(message.copy(synced = false))
} }
jobFinished(params, true) jobFinished(params, true)
} }
......
...@@ -545,9 +545,12 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -545,9 +545,12 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
override fun dispatchUpdateMessage(index: Int, message: List<BaseUiModel<*>>) { override fun dispatchUpdateMessage(index: Int, message: List<BaseUiModel<*>>) {
ui { ui {
adapter.updateItem(message.last()) if (adapter.updateItem(message.last())) {
if (message.size > 1) { if (message.size > 1) {
adapter.prependData(listOf(message.first())) adapter.prependData(listOf(message.first()))
}
} else {
showNewMessage(message, true)
} }
} }
} }
......
...@@ -9,6 +9,7 @@ data class ColorAttachmentUiModel( ...@@ -9,6 +9,7 @@ data class ColorAttachmentUiModel(
val id: Long, val id: Long,
val color: Int, val color: Int,
val text: CharSequence, val text: CharSequence,
val fields: CharSequence? = null,
override val message: Message, override val message: Message,
override val rawData: ColorAttachment, override val rawData: ColorAttachment,
override val messageId: String, override val messageId: String,
......
...@@ -42,6 +42,7 @@ import chat.rocket.core.model.attachment.Attachment ...@@ -42,6 +42,7 @@ import chat.rocket.core.model.attachment.Attachment
import chat.rocket.core.model.attachment.AudioAttachment import chat.rocket.core.model.attachment.AudioAttachment
import chat.rocket.core.model.attachment.AuthorAttachment import chat.rocket.core.model.attachment.AuthorAttachment
import chat.rocket.core.model.attachment.ColorAttachment import chat.rocket.core.model.attachment.ColorAttachment
import chat.rocket.core.model.attachment.Field
import chat.rocket.core.model.attachment.FileAttachment import chat.rocket.core.model.attachment.FileAttachment
import chat.rocket.core.model.attachment.GenericFileAttachment import chat.rocket.core.model.attachment.GenericFileAttachment
import chat.rocket.core.model.attachment.ImageAttachment import chat.rocket.core.model.attachment.ImageAttachment
...@@ -129,14 +130,14 @@ class UiModelMapper @Inject constructor( ...@@ -129,14 +130,14 @@ class UiModelMapper @Inject constructor(
withContext(CommonPool) { withContext(CommonPool) {
val list = ArrayList<BaseUiModel<*>>() val list = ArrayList<BaseUiModel<*>>()
message.urls?.forEach { message.urls?.forEach { url ->
val url = mapUrl(message, it) mapUrl(message, url)?.let { list.add(it) }
url?.let { list.add(url) }
} }
message.attachments?.forEach { message.attachments?.mapNotNull { attachment ->
val attachment = mapAttachment(message, it) mapAttachment(message, attachment)
attachment?.let { list.add(attachment) } }?.asReversed()?.let {
list.addAll(it)
} }
mapMessage(message).let { mapMessage(message).let {
...@@ -175,7 +176,7 @@ class UiModelMapper @Inject constructor( ...@@ -175,7 +176,7 @@ class UiModelMapper @Inject constructor(
broadcast = broadcast ?: false, broadcast = broadcast ?: false,
alert = alert, alert = alert,
fullName = fullname, fullName = fullname,
name = name ?: "", name = name,
favorite = favorite ?: false, favorite = favorite ?: false,
default = isDefault ?: false, default = isDefault ?: false,
readonly = readonly, readonly = readonly,
...@@ -334,34 +335,39 @@ class UiModelMapper @Inject constructor( ...@@ -334,34 +335,39 @@ class UiModelMapper @Inject constructor(
val localDateTime = DateTimeHelper.getLocalDateTime(message.timestamp) val localDateTime = DateTimeHelper.getLocalDateTime(message.timestamp)
val dayMarkerText = DateTimeHelper.getFormattedDateForMessages(localDateTime, context) val dayMarkerText = DateTimeHelper.getFormattedDateForMessages(localDateTime, context)
val fieldsText = mapFields(fields)
ColorAttachmentUiModel(attachmentUrl = url, id = id, color = color.color, ColorAttachmentUiModel(attachmentUrl = url, id = id, color = color.color,
text = text, message = message, rawData = attachment, text = text, fields = fieldsText, message = message, rawData = attachment,
messageId = message.id, reactions = getReactions(message), messageId = message.id, reactions = getReactions(message),
preview = message.copy(message = content.message), unread = message.unread, preview = message.copy(message = content.message), unread = message.unread,
showDayMarker = false, currentDayMarkerText = dayMarkerText) showDayMarker = false, currentDayMarkerText = dayMarkerText)
} }
} }
private fun mapAuthorAttachment(message: Message, attachment: AuthorAttachment): AuthorAttachmentUiModel { private fun mapFields(fields: List<Field>?): CharSequence? {
return with(attachment) { return fields?.let {
val content = stripMessageQuotes(message) buildSpannedString {
it.forEachIndexed { index, field ->
val fieldsText = fields?.let { bold { append(field.title) }
buildSpannedString { append("\n")
it.forEachIndexed { index, field -> if (field.value.isNotEmpty()) {
bold { append(field.title) } append(field.value)
append("\n") }
if (field.value.isNotEmpty()) {
append(field.value)
}
if (index != it.size - 1) { // it is not the last one, append a new line if (index != it.size - 1) { // it is not the last one, append a new line
append("\n\n") append("\n\n")
}
} }
} }
} }
}
}
private fun mapAuthorAttachment(message: Message, attachment: AuthorAttachment): AuthorAttachmentUiModel {
return with(attachment) {
val content = stripMessageQuotes(message)
val fieldsText = mapFields(fields)
val id = attachmentId(message, attachment) val id = attachmentId(message, attachment)
val localDateTime = DateTimeHelper.getLocalDateTime(message.timestamp) val localDateTime = DateTimeHelper.getLocalDateTime(message.timestamp)
...@@ -477,7 +483,7 @@ class UiModelMapper @Inject constructor( ...@@ -477,7 +483,7 @@ class UiModelMapper @Inject constructor(
val time = getTime(message.timestamp) val time = getTime(message.timestamp)
val avatar = getUserAvatar(message) val avatar = getUserAvatar(message)
val preview = mapMessagePreview(message) val preview = mapMessagePreview(message)
val isTemp = message.isTemporary ?: false val synced = message.synced
val unread = if (settings.messageReadReceiptEnabled()) { val unread = if (settings.messageReadReceiptEnabled()) {
message.unread ?: false message.unread ?: false
} else { } else {
...@@ -492,7 +498,7 @@ class UiModelMapper @Inject constructor( ...@@ -492,7 +498,7 @@ class UiModelMapper @Inject constructor(
messageId = message.id, avatar = avatar!!, time = time, senderName = sender, messageId = message.id, avatar = avatar!!, time = time, senderName = sender,
content = content, isPinned = message.pinned, currentDayMarkerText = dayMarkerText, content = content, isPinned = message.pinned, currentDayMarkerText = dayMarkerText,
showDayMarker = false, reactions = getReactions(message), isFirstUnread = false, showDayMarker = false, reactions = getReactions(message), isFirstUnread = false,
preview = preview, isTemporary = isTemp, unread = unread) preview = preview, isTemporary = !synced, unread = unread)
} }
private fun mapMessagePreview(message: Message): Message { private fun mapMessagePreview(message: Message): Message {
......
...@@ -5,5 +5,4 @@ import chat.rocket.android.suggestions.model.SuggestionModel ...@@ -5,5 +5,4 @@ import chat.rocket.android.suggestions.model.SuggestionModel
class ChatRoomSuggestionUiModel(text: String, class ChatRoomSuggestionUiModel(text: String,
val fullName: String, val fullName: String,
val name: String, val name: String,
searchList: List<String>) : SuggestionModel(text, searchList, false) { searchList: List<String>) : SuggestionModel(text, searchList, false)
} \ No newline at end of file
\ No newline at end of file
...@@ -30,7 +30,6 @@ import chat.rocket.android.chatrooms.viewmodel.ChatRoomsViewModel ...@@ -30,7 +30,6 @@ import chat.rocket.android.chatrooms.viewmodel.ChatRoomsViewModel
import chat.rocket.android.chatrooms.viewmodel.ChatRoomsViewModelFactory import chat.rocket.android.chatrooms.viewmodel.ChatRoomsViewModelFactory
import chat.rocket.android.chatrooms.viewmodel.LoadingState import chat.rocket.android.chatrooms.viewmodel.LoadingState
import chat.rocket.android.chatrooms.viewmodel.Query import chat.rocket.android.chatrooms.viewmodel.Query
import chat.rocket.android.db.DatabaseManager
import chat.rocket.android.helper.ChatRoomsSortOrder import chat.rocket.android.helper.ChatRoomsSortOrder
import chat.rocket.android.helper.Constants import chat.rocket.android.helper.Constants
import chat.rocket.android.helper.SharedPreferenceHelper import chat.rocket.android.helper.SharedPreferenceHelper
...@@ -57,10 +56,10 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -57,10 +56,10 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
@Inject @Inject
lateinit var factory: ChatRoomsViewModelFactory lateinit var factory: ChatRoomsViewModelFactory
@Inject @Inject
lateinit var dbManager: DatabaseManager // TODO - remove when moving ChatRoom screen to DB
@Inject
lateinit var analyticsManager: AnalyticsManager lateinit var analyticsManager: AnalyticsManager
lateinit var viewModel: ChatRoomsViewModel
private lateinit var viewModel: ChatRoomsViewModel
private var searchView: SearchView? = null private var searchView: SearchView? = null
private var sortView: MenuItem? = null private var sortView: MenuItem? = null
private val handler = Handler() private val handler = Handler()
......
...@@ -9,7 +9,6 @@ import android.content.Context ...@@ -9,7 +9,6 @@ import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import chat.rocket.android.BuildConfig import chat.rocket.android.BuildConfig
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.analytics.Analytics
import chat.rocket.android.analytics.AnalyticsManager import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.AnswersAnalytics import chat.rocket.android.analytics.AnswersAnalytics
import chat.rocket.android.analytics.GoogleAnalyticsForFirebase import chat.rocket.android.analytics.GoogleAnalyticsForFirebase
...@@ -26,7 +25,6 @@ import chat.rocket.android.infrastructure.SharedPreferencesLocalRepository ...@@ -26,7 +25,6 @@ import chat.rocket.android.infrastructure.SharedPreferencesLocalRepository
import chat.rocket.android.push.GroupedPush import chat.rocket.android.push.GroupedPush
import chat.rocket.android.push.PushManager import chat.rocket.android.push.PushManager
import chat.rocket.android.server.domain.AccountsRepository import chat.rocket.android.server.domain.AccountsRepository
import chat.rocket.android.server.domain.ActiveUsersRepository
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor import chat.rocket.android.server.domain.AnalyticsTrackingInteractor
import chat.rocket.android.server.domain.AnalyticsTrackingRepository import chat.rocket.android.server.domain.AnalyticsTrackingRepository
import chat.rocket.android.server.domain.ChatRoomsRepository import chat.rocket.android.server.domain.ChatRoomsRepository
...@@ -39,17 +37,15 @@ import chat.rocket.android.server.domain.JobSchedulerInteractor ...@@ -39,17 +37,15 @@ import chat.rocket.android.server.domain.JobSchedulerInteractor
import chat.rocket.android.server.domain.MessagesRepository import chat.rocket.android.server.domain.MessagesRepository
import chat.rocket.android.server.domain.MultiServerTokenRepository import chat.rocket.android.server.domain.MultiServerTokenRepository
import chat.rocket.android.server.domain.PermissionsRepository import chat.rocket.android.server.domain.PermissionsRepository
import chat.rocket.android.server.domain.RoomRepository
import chat.rocket.android.server.domain.SettingsRepository import chat.rocket.android.server.domain.SettingsRepository
import chat.rocket.android.server.domain.TokenRepository import chat.rocket.android.server.domain.TokenRepository
import chat.rocket.android.server.domain.UsersRepository import chat.rocket.android.server.domain.UsersRepository
import chat.rocket.android.server.infraestructure.DatabaseMessageMapper
import chat.rocket.android.server.infraestructure.DatabaseMessagesRepository
import chat.rocket.android.server.infraestructure.JobSchedulerInteractorImpl import chat.rocket.android.server.infraestructure.JobSchedulerInteractorImpl
import chat.rocket.android.server.infraestructure.MemoryActiveUsersRepository
import chat.rocket.android.server.infraestructure.MemoryChatRoomsRepository import chat.rocket.android.server.infraestructure.MemoryChatRoomsRepository
import chat.rocket.android.server.infraestructure.MemoryRoomRepository
import chat.rocket.android.server.infraestructure.MemoryUsersRepository import chat.rocket.android.server.infraestructure.MemoryUsersRepository
import chat.rocket.android.server.infraestructure.SharedPreferencesAccountsRepository import chat.rocket.android.server.infraestructure.SharedPreferencesAccountsRepository
import chat.rocket.android.server.infraestructure.SharedPreferencesMessagesRepository
import chat.rocket.android.server.infraestructure.SharedPreferencesPermissionsRepository import chat.rocket.android.server.infraestructure.SharedPreferencesPermissionsRepository
import chat.rocket.android.server.infraestructure.SharedPreferencesSettingsRepository import chat.rocket.android.server.infraestructure.SharedPreferencesSettingsRepository
import chat.rocket.android.server.infraestructure.SharedPrefsAnalyticsTrackingRepository import chat.rocket.android.server.infraestructure.SharedPrefsAnalyticsTrackingRepository
...@@ -201,24 +197,12 @@ class AppModule { ...@@ -201,24 +197,12 @@ class AppModule {
return SharedPreferencesPermissionsRepository(localRepository, moshi) return SharedPreferencesPermissionsRepository(localRepository, moshi)
} }
@Provides
@Singleton
fun provideRoomRepository(): RoomRepository {
return MemoryRoomRepository()
}
@Provides @Provides
@Singleton @Singleton
fun provideChatRoomRepository(): ChatRoomsRepository { fun provideChatRoomRepository(): ChatRoomsRepository {
return MemoryChatRoomsRepository() return MemoryChatRoomsRepository()
} }
@Provides
@Singleton
fun provideActiveUsersRepository(): ActiveUsersRepository {
return MemoryActiveUsersRepository()
}
@Provides @Provides
@Singleton @Singleton
fun provideMoshi( fun provideMoshi(
...@@ -254,13 +238,8 @@ class AppModule { ...@@ -254,13 +238,8 @@ class AppModule {
} }
@Provides @Provides
@Singleton fun provideMessageRepository(databaseManager: DatabaseManager): MessagesRepository {
fun provideMessageRepository( return DatabaseMessagesRepository(databaseManager, DatabaseMessageMapper(databaseManager))
@ForMessages preferences: SharedPreferences,
moshi: Moshi,
currentServerInteractor: GetCurrentServerInteractor
): MessagesRepository {
return SharedPreferencesMessagesRepository(preferences, moshi, currentServerInteractor)
} }
@Provides @Provides
......
...@@ -4,7 +4,7 @@ import androidx.room.Insert ...@@ -4,7 +4,7 @@ import androidx.room.Insert
import androidx.room.OnConflictStrategy import androidx.room.OnConflictStrategy
interface BaseDao<T> { interface BaseDao<T> {
@Insert @Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(vararg obj: T) fun insert(vararg obj: T)
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
......
...@@ -99,7 +99,7 @@ abstract class ChatRoomDao : BaseDao<ChatRoomEntity> { ...@@ -99,7 +99,7 @@ abstract class ChatRoomDao : BaseDao<ChatRoomEntity> {
abstract fun update(list: List<ChatRoomEntity>) abstract fun update(list: List<ChatRoomEntity>)
@Transaction @Transaction
open fun update(toRemove: List<String>, toInsert: List<ChatRoomEntity>, toUpdate: List<ChatRoomEntity>) { open fun update(toInsert: List<ChatRoomEntity>, toUpdate: List<ChatRoomEntity>, toRemove: List<String>) {
insertOrReplace(toInsert) insertOrReplace(toInsert)
update(toUpdate) update(toUpdate)
toRemove.forEach { id -> toRemove.forEach { id ->
......
This diff is collapsed.
...@@ -2,29 +2,32 @@ package chat.rocket.android.db ...@@ -2,29 +2,32 @@ package chat.rocket.android.db
import androidx.room.Database import androidx.room.Database
import androidx.room.RoomDatabase import androidx.room.RoomDatabase
import androidx.room.migration.Migration import chat.rocket.android.db.model.AttachmentActionEntity
import androidx.sqlite.db.SupportSQLiteDatabase import chat.rocket.android.db.model.AttachmentEntity
import chat.rocket.android.db.model.AttachmentFieldEntity
import chat.rocket.android.db.model.ChatRoomEntity import chat.rocket.android.db.model.ChatRoomEntity
import chat.rocket.android.db.model.MessageChannels
import chat.rocket.android.db.model.MessageEntity
import chat.rocket.android.db.model.MessageFavoritesRelation
import chat.rocket.android.db.model.MessageMentionsRelation
import chat.rocket.android.db.model.MessagesSync
import chat.rocket.android.db.model.ReactionEntity
import chat.rocket.android.db.model.UrlEntity
import chat.rocket.android.db.model.UserEntity import chat.rocket.android.db.model.UserEntity
@Database( @Database(
entities = [UserEntity::class, ChatRoomEntity::class], entities = [
version = 5, UserEntity::class, ChatRoomEntity::class, MessageEntity::class,
MessageFavoritesRelation::class, MessageMentionsRelation::class,
MessageChannels::class, AttachmentEntity::class,
AttachmentFieldEntity::class, AttachmentActionEntity::class, UrlEntity::class,
ReactionEntity::class, MessagesSync::class
],
version = 9,
exportSchema = true exportSchema = true
) )
abstract class RCDatabase : RoomDatabase() { abstract class RCDatabase : RoomDatabase() {
abstract fun userDao(): UserDao abstract fun userDao(): UserDao
abstract fun chatRoomDao(): ChatRoomDao abstract fun chatRoomDao(): ChatRoomDao
abstract fun messageDao(): MessageDao
companion object {
@JvmField
val MIGRATION_4_5 = Migration4to5()
}
}
class Migration4to5 : Migration(4, 5) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("CREATE INDEX `index_chatrooms_lastMessageUserId` ON `chatrooms` (`lastMessageUserId`)")
}
} }
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
package chat.rocket.android.db.model
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Index
import androidx.room.PrimaryKey
@Entity(tableName = "reactions",
foreignKeys = [
ForeignKey(entity = MessageEntity::class, parentColumns = ["id"],
childColumns = ["messageId"], onDelete = ForeignKey.CASCADE)
],
indices = [
Index(value = ["messageId"])
]
)
data class ReactionEntity(
@PrimaryKey val reaction: String,
val messageId: String,
val count: Int,
val usernames: String
) : BaseMessageEntity
\ No newline at end of file
This diff is collapsed.
package chat.rocket.android.server.domain
import chat.rocket.common.model.User
interface ActiveUsersRepository {
fun save(url: String, activeUsers: List<User>)
fun get(url: String): List<User>
}
\ No newline at end of file
This diff is collapsed.
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