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

Merge pull request #1512 from RocketChat/beta

[RELEASE] Merge BETA into DEVELOP
parents 638759d7 7332dc06
......@@ -12,7 +12,7 @@ android {
applicationId "chat.rocket.android"
minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk
versionCode 2031
versionCode 2032
versionName "2.5.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
......
{
"formatVersion": 1,
"database": {
"version": 5,
"identityHash": "47a0c30e2696ae09bc86df16cc37279d",
"entities": [
{
"tableName": "users",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `username` TEXT, `name` TEXT, `status` TEXT NOT NULL, `utcOffset` REAL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "username",
"columnName": "username",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "status",
"columnName": "status",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "utcOffset",
"columnName": "utcOffset",
"affinity": "REAL",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_users_username",
"unique": false,
"columnNames": [
"username"
],
"createSql": "CREATE INDEX `index_users_username` ON `${TABLE_NAME}` (`username`)"
}
],
"foreignKeys": []
},
{
"tableName": "chatrooms",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` TEXT NOT NULL, `type` TEXT NOT NULL, `name` TEXT NOT NULL, `fullname` TEXT, `userId` TEXT, `ownerId` TEXT, `readonly` INTEGER, `isDefault` INTEGER, `favorite` INTEGER, `open` INTEGER NOT NULL, `alert` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `userMentions` INTEGER, `groupMentions` INTEGER, `updatedAt` INTEGER, `timestamp` INTEGER, `lastSeen` INTEGER, `lastMessageText` TEXT, `lastMessageUserId` TEXT, `lastMessageTimestamp` INTEGER, `broadcast` INTEGER, PRIMARY KEY(`id`), FOREIGN KEY(`ownerId`) REFERENCES `users`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`userId`) REFERENCES `users`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`lastMessageUserId`) REFERENCES `users`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "subscriptionId",
"columnName": "subscriptionId",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "fullname",
"columnName": "fullname",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "userId",
"columnName": "userId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "ownerId",
"columnName": "ownerId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "readonly",
"columnName": "readonly",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "isDefault",
"columnName": "isDefault",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "favorite",
"columnName": "favorite",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "open",
"columnName": "open",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "alert",
"columnName": "alert",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "unread",
"columnName": "unread",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "userMentions",
"columnName": "userMentions",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "groupMentions",
"columnName": "groupMentions",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "updatedAt",
"columnName": "updatedAt",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "lastSeen",
"columnName": "lastSeen",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "lastMessageText",
"columnName": "lastMessageText",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "lastMessageUserId",
"columnName": "lastMessageUserId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "lastMessageTimestamp",
"columnName": "lastMessageTimestamp",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "broadcast",
"columnName": "broadcast",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_chatrooms_userId",
"unique": false,
"columnNames": [
"userId"
],
"createSql": "CREATE INDEX `index_chatrooms_userId` ON `${TABLE_NAME}` (`userId`)"
},
{
"name": "index_chatrooms_ownerId",
"unique": false,
"columnNames": [
"ownerId"
],
"createSql": "CREATE INDEX `index_chatrooms_ownerId` ON `${TABLE_NAME}` (`ownerId`)"
},
{
"name": "index_chatrooms_subscriptionId",
"unique": true,
"columnNames": [
"subscriptionId"
],
"createSql": "CREATE UNIQUE INDEX `index_chatrooms_subscriptionId` ON `${TABLE_NAME}` (`subscriptionId`)"
},
{
"name": "index_chatrooms_updatedAt",
"unique": false,
"columnNames": [
"updatedAt"
],
"createSql": "CREATE INDEX `index_chatrooms_updatedAt` ON `${TABLE_NAME}` (`updatedAt`)"
},
{
"name": "index_chatrooms_lastMessageUserId",
"unique": false,
"columnNames": [
"lastMessageUserId"
],
"createSql": "CREATE INDEX `index_chatrooms_lastMessageUserId` ON `${TABLE_NAME}` (`lastMessageUserId`)"
}
],
"foreignKeys": [
{
"table": "users",
"onDelete": "NO ACTION",
"onUpdate": "NO ACTION",
"columns": [
"ownerId"
],
"referencedColumns": [
"id"
]
},
{
"table": "users",
"onDelete": "NO ACTION",
"onUpdate": "NO ACTION",
"columns": [
"userId"
],
"referencedColumns": [
"id"
]
},
{
"table": "users",
"onDelete": "NO ACTION",
"onUpdate": "NO ACTION",
"columns": [
"lastMessageUserId"
],
"referencedColumns": [
"id"
]
}
]
}
],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"47a0c30e2696ae09bc86df16cc37279d\")"
]
}
}
\ No newline at end of file
......@@ -10,6 +10,7 @@ import chat.rocket.android.chatrooms.adapter.model.RoomUiModel
import chat.rocket.android.db.model.ChatRoom
import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.infrastructure.checkIfMyself
import chat.rocket.android.server.domain.GetCurrentUserInteractor
import chat.rocket.android.server.domain.PublicSettings
import chat.rocket.android.server.domain.showLastMessage
import chat.rocket.android.server.domain.useRealName
......@@ -27,7 +28,7 @@ import chat.rocket.core.model.SpotlightResult
class RoomUiModelMapper(
private val context: Application,
private val settings: PublicSettings,
private val localRepository: LocalRepository,
private val userInteractor: GetCurrentUserInteractor,
private val serverUrl: String
) {
private val nameUnreadColor = ContextCompat.getColor(context, R.color.colorPrimaryText)
......@@ -37,6 +38,10 @@ class RoomUiModelMapper(
private val messageUnreadColor = ContextCompat.getColor(context, android.R.color.primary_text_light)
private val messageColor = ContextCompat.getColor(context, R.color.colorSecondaryText)
private val currentUser by lazy {
userInteractor.get()
}
fun map(rooms: List<ChatRoom>, grouped: Boolean = false): List<ItemHolder<*>> {
val list = ArrayList<ItemHolder<*>>(rooms.size + 4)
var lastType: String? = null
......@@ -88,8 +93,9 @@ class RoomUiModelMapper(
name = name!!,
type = type,
avatar = serverUrl.avatarUrl(name!!, isGroupOrChannel = true),
lastMessage = mapLastMessage(lastMessage?.sender?.username,
lastMessage?.sender?.name, lastMessage?.message)
lastMessage = mapLastMessage(lastMessage?.sender?.id, lastMessage?.sender?.username,
lastMessage?.sender?.name, lastMessage?.message,
isDirectMessage = type is RoomType.DirectMessage)
)
}
}
......@@ -107,14 +113,17 @@ class RoomUiModelMapper(
serverUrl.avatarUrl(name, isGroupOrChannel = true)
}
val unread = mapUnread(unread)
val lastMessage = mapLastMessage(chatRoom.lastMessageUserName,
chatRoom.lastMessageUserFullName, lastMessageText, isUnread)
val lastMessage = mapLastMessage(lastMessageUserId, chatRoom.lastMessageUserName,
chatRoom.lastMessageUserFullName, lastMessageText, isUnread,
type is RoomType.DirectMessage)
val open = open
RoomUiModel(
id = id,
name = roomName,
type = type,
avatar = avatar,
open = open,
date = timestamp,
unread = unread,
alert = isUnread,
......@@ -136,14 +145,16 @@ class RoomUiModelMapper(
}
}
private fun mapLastMessage(name: String?, fullName: String?, text: String?, unread: Boolean = false): CharSequence? {
private fun mapLastMessage(userId: String?, name: String?, fullName: String?, text: String?,
unread: Boolean = false,
isDirectMessage: Boolean = false): CharSequence? {
return if (!settings.showLastMessage()) {
null
} else if (name != null && text != null) {
val user = if (localRepository.checkIfMyself(name)) {
val user = if (currentUser != null && currentUser!!.id == userId) {
"${context.getString(R.string.msg_you)}: "
} else {
"${mapName(name, fullName, unread)}: "
if (isDirectMessage) "" else "${mapName(name, fullName, unread)}: "
}
val color = if (unread) messageUnreadColor else messageColor
......
......@@ -8,6 +8,7 @@ data class RoomUiModel(
val type: RoomType,
val name: CharSequence,
val avatar: String,
val open: Boolean = false,
val date: CharSequence? = null,
val unread: String? = null,
val alert: Boolean = false,
......
......@@ -9,9 +9,12 @@ import chat.rocket.android.chatrooms.ui.ChatRoomsFragment
import chat.rocket.android.dagger.scope.PerFragment
import chat.rocket.android.db.ChatRoomDao
import chat.rocket.android.db.DatabaseManager
import chat.rocket.android.db.UserDao
import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.server.domain.GetCurrentUserInteractor
import chat.rocket.android.server.domain.PublicSettings
import chat.rocket.android.server.domain.SettingsRepository
import chat.rocket.android.server.domain.TokenRepository
import chat.rocket.android.server.infraestructure.ConnectionManager
import chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import chat.rocket.android.server.infraestructure.RocketChatClientFactory
......@@ -48,6 +51,10 @@ class ChatRoomsFragmentModule {
@PerFragment
fun provideChatRoomDao(manager: DatabaseManager): ChatRoomDao = manager.chatRoomDao()
@Provides
@PerFragment
fun provideUserDao(manager: DatabaseManager): UserDao = manager.userDao()
@Provides
@PerFragment
fun provideConnectionManager(
......@@ -80,9 +87,19 @@ class ChatRoomsFragmentModule {
fun provideRoomMapper(
context: Application,
repository: SettingsRepository,
localRepository: LocalRepository,
userInteractor: GetCurrentUserInteractor,
@Named("currentServer") serverUrl: String
): RoomUiModelMapper {
return RoomUiModelMapper(context, repository.get(serverUrl), localRepository, serverUrl)
return RoomUiModelMapper(context, repository.get(serverUrl), userInteractor, serverUrl)
}
@Provides
@PerFragment
fun provideGetCurrentUserInteractor(
tokenRepository: TokenRepository,
@Named("currentServer") serverUrl: String,
userDao: UserDao
): GetCurrentUserInteractor {
return GetCurrentUserInteractor(tokenRepository, serverUrl, userDao)
}
}
\ No newline at end of file
......@@ -3,7 +3,6 @@ package chat.rocket.android.chatrooms.domain
import chat.rocket.android.db.DatabaseManager
import chat.rocket.android.db.model.ChatRoomEntity
import chat.rocket.android.db.model.UserEntity
import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.util.retryIO
import chat.rocket.core.RocketChatClient
import chat.rocket.core.internal.rest.chatRooms
......@@ -19,60 +18,10 @@ class FetchChatRoomsInteractor(
suspend fun refreshChatRooms() {
val rooms = retryIO("fetch chatRooms", times = 10,
initialDelay = 200, maxDelay = 2000) {
client.chatRooms().update.map { room ->
mapChatRoom(room)
}
client.chatRooms().update
}
Timber.d("Refreshing rooms: $rooms")
dbManager.insert(rooms)
}
private suspend fun mapChatRoom(room: ChatRoom): ChatRoomEntity {
with(room) {
val userId = userId()
if (userId != null && dbManager.findUser(userId) == null) {
Timber.d("Missing user, inserting: $userId")
dbManager.insert(UserEntity(userId))
}
lastMessage?.sender?.let { user ->
user.id?.let { id ->
if (dbManager.findUser(id) == null) {
Timber.d("Missing last message user, inserting: $id")
dbManager.insert(UserEntity(id, user.username, user.name))
}
}
}
user?.id?.let { id ->
if (dbManager.findUser(id) == null) {
Timber.d("Missing owner user, inserting: $id")
dbManager.insert(UserEntity(id, user?.username, user?.name))
}
}
return ChatRoomEntity(
id = id,
subscriptionId = subscriptionId,
type = type.toString(),
name = name,
fullname = fullName,
userId = userId,
ownerId = user?.id,
readonly = readonly,
isDefault = default,
favorite = favorite,
open = open,
alert = alert,
unread = unread,
userMentions = userMentions,
groupMentions = groupMentions,
updatedAt = updatedAt,
timestamp = timestamp,
lastSeen = lastSeen,
lastMessageText = lastMessage?.message,
lastMessageUserId = lastMessage?.sender?.id,
lastMessageTimestamp = lastMessage?.timestamp,
broadcast = broadcast
)
}
dbManager.processRooms(rooms)
}
}
\ No newline at end of file
......@@ -9,8 +9,8 @@ import chat.rocket.android.helper.UserHelper
import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.main.presentation.MainNavigator
import chat.rocket.android.server.domain.SettingsRepository
import chat.rocket.android.server.domain.useSpecialCharsOnRoom
import chat.rocket.android.server.domain.useRealName
import chat.rocket.android.server.domain.useSpecialCharsOnRoom
import chat.rocket.android.server.infraestructure.ConnectionManager
import chat.rocket.android.util.extension.launchUI
import chat.rocket.android.util.retryIO
......@@ -20,9 +20,12 @@ import chat.rocket.common.model.User
import chat.rocket.common.model.roomTypeOf
import chat.rocket.core.internal.realtime.createDirectMessage
import chat.rocket.core.internal.rest.me
import chat.rocket.core.internal.rest.show
import kotlinx.coroutines.experimental.withTimeout
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Named
import kotlin.coroutines.experimental.suspendCoroutine
class ChatRoomsPresenter @Inject constructor(
private val view: ChatRoomsView,
......@@ -44,7 +47,7 @@ class ChatRoomsPresenter @Inject constructor(
try {
val room = dbManager.getRoom(chatRoom.id)
if (room != null) {
loadChatRoom(room.chatRoom)
loadChatRoom(room.chatRoom, true)
} else {
with(chatRoom) {
val entity = ChatRoomEntity(
......@@ -53,44 +56,56 @@ class ChatRoomsPresenter @Inject constructor(
type = type.toString(),
name = username ?: name.toString(),
fullname = name.toString(),
open = false
open = open
)
loadChatRoom(entity)
loadChatRoom(entity, false)
}
}
} catch (ex: Exception) {
Timber.d(ex, "Error loading channel")
view.showGenericErrorMessage()
} finally {
view.hideLoadingRoom()
}
}
}
fun loadChatRoom(chatRoom: ChatRoomEntity) {
suspend fun loadChatRoom(chatRoom: ChatRoomEntity, local: Boolean = false) {
with(chatRoom) {
val isDirectMessage = roomTypeOf(type) is RoomType.DirectMessage
val roomName = if (settings.useSpecialCharsOnRoom() || (isDirectMessage && settings.useRealName())) {
fullname ?: name
} else {
name
}
fullname ?: name
} else {
name
}
launchUI(strategy) {
val myself = getCurrentUser()
if (myself?.username == null) {
view.showMessage(R.string.msg_generic_error)
} else {
val id = if (isDirectMessage && !open) {
val myself = getCurrentUser()
if (myself?.username == null) {
view.showMessage(R.string.msg_generic_error)
} else {
val id = if (isDirectMessage && !open) {
// If from local database, we already have the roomId, no need to concatenate
if (local) {
retryIO {
client.show(id, roomTypeOf(RoomType.DIRECT_MESSAGE))
}
id
} else {
retryIO("createDirectMessage($name)") {
client.createDirectMessage(name)
withTimeout(10000) {
createDirectMessage(name)
}
}
val fromTo = mutableListOf(myself.id, id).apply {
sort()
}
fromTo.joinToString("")
} else {
id
}
} else {
id
}
navigator.toChatRoom(
navigator.toChatRoom(
chatRoomId = id,
chatRoomName = roomName,
chatRoomType = type,
......@@ -99,8 +114,7 @@ class ChatRoomsPresenter @Inject constructor(
isSubscribed = open,
isCreator = ownerId == myself.id || isDirectMessage,
isFavorite = favorite ?: false
)
}
)
}
}
}
......@@ -126,4 +140,10 @@ class ChatRoomsPresenter @Inject constructor(
}
return null
}
private suspend fun createDirectMessage(name: String): Boolean = suspendCoroutine { cont ->
client.createDirectMessage(name) { success, _ ->
cont.resume(success)
}
}
}
\ No newline at end of file
......@@ -21,19 +21,23 @@ abstract class ChatRoomDao : BaseDao<ChatRoomEntity> {
abstract fun get(id: String): ChatRoom?
@Transaction
@Query("$BASE_QUERY")
@Query("$BASE_QUERY $FILTER_NOT_OPENED")
abstract fun getAllSync(): List<ChatRoom>
@Transaction
@Query("""$BASE_QUERY WHERE chatrooms.name LIKE '%' || :query || '%' OR users.name LIKE '%' || :query || '%'""")
@Query("""$BASE_QUERY
WHERE chatrooms.name LIKE '%' || :query || '%'
OR users.name LIKE '%' || :query || '%'
""")
abstract fun searchSync(query: String): List<ChatRoom>
@Query("SELECT COUNT(id) FROM chatrooms")
@Query("SELECT COUNT(id) FROM chatrooms WHERE open = 1")
abstract fun count(): Long
@Transaction
@Query("""
$BASE_QUERY
$FILTER_NOT_OPENED
ORDER BY
CASE
WHEN lastMessageTimeStamp IS NOT NULL THEN lastMessageTimeStamp
......@@ -45,6 +49,7 @@ abstract class ChatRoomDao : BaseDao<ChatRoomEntity> {
@Transaction
@Query("""
$BASE_QUERY
$FILTER_NOT_OPENED
ORDER BY
$TYPE_ORDER,
CASE
......@@ -57,6 +62,7 @@ abstract class ChatRoomDao : BaseDao<ChatRoomEntity> {
@Transaction
@Query("""
$BASE_QUERY
$FILTER_NOT_OPENED
ORDER BY name
""")
abstract fun getAllAlphabetically(): LiveData<List<ChatRoom>>
......@@ -64,6 +70,7 @@ abstract class ChatRoomDao : BaseDao<ChatRoomEntity> {
@Transaction
@Query("""
$BASE_QUERY
$FILTER_NOT_OPENED
ORDER BY
$TYPE_ORDER,
name
......@@ -113,6 +120,10 @@ abstract class ChatRoomDao : BaseDao<ChatRoomEntity> {
LEFT JOIN users AS lmUsers ON chatrooms.lastMessageUserId = lmUsers.id
"""
const val FILTER_NOT_OPENED = """
WHERE chatrooms.open = 1
"""
const val TYPE_ORDER = """
CASE
WHEN type = 'c' THEN 1
......
......@@ -2,16 +2,29 @@ package chat.rocket.android.db
import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import chat.rocket.android.db.model.ChatRoomEntity
import chat.rocket.android.db.model.UserEntity
@Database(
entities = [UserEntity::class, ChatRoomEntity::class],
version = 4,
version = 5,
exportSchema = true
)
abstract class RCDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
abstract fun chatRoomDao(): ChatRoomDao
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
......@@ -13,6 +13,12 @@ import timber.log.Timber
@Dao
abstract class UserDao : BaseDao<UserEntity> {
@Query("""
UPDATE users set STATUS = "offline"
""")
abstract fun clearStatus()
@Update(onConflict = OnConflictStrategy.IGNORE)
abstract fun update(user: UserEntity): Int
......@@ -22,6 +28,9 @@ abstract class UserDao : BaseDao<UserEntity> {
@Query("SELECT id FROM users WHERE ID = :id")
abstract fun findUser(id: String): String?
@Query("SELECT * FROM users WHERE ID = :id")
abstract fun getUser(id:String): UserEntity?
@Transaction
open fun upsert(user: BaseUserEntity) {
internalUpsert(user)
......
......@@ -11,7 +11,8 @@ import androidx.room.PrimaryKey
Index(value = ["userId"]),
Index(value = ["ownerId"]),
Index(value = ["subscriptionId"], unique = true),
Index(value = ["updatedAt"])
Index(value = ["updatedAt"]),
Index(value = ["lastMessageUserId"])
],
foreignKeys = [
ForeignKey(entity = UserEntity::class, parentColumns = ["id"], childColumns = ["ownerId"]),
......@@ -19,7 +20,6 @@ import androidx.room.PrimaryKey
ForeignKey(entity = UserEntity::class, parentColumns = ["id"], childColumns = ["lastMessageUserId"])
]
)
data class ChatRoomEntity(
@PrimaryKey var id: String,
var subscriptionId: String,
......
......@@ -32,5 +32,6 @@ interface LocalRepository {
}
}
// FIXME - we are saving the user full name here when the server is UI_Use_Real_Name true
fun LocalRepository.checkIfMyself(username: String) = username() == username
fun LocalRepository.username() = get(LocalRepository.CURRENT_USERNAME_KEY)
\ No newline at end of file
......@@ -9,6 +9,7 @@ import chat.rocket.android.server.domain.GetAccountsInteractor
import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.domain.GetSettingsInteractor
import chat.rocket.android.server.domain.PublicSettings
import chat.rocket.android.server.domain.RefreshSettingsInteractor
import chat.rocket.android.server.domain.RemoveAccountInteractor
import chat.rocket.android.server.domain.SaveAccountInteractor
import chat.rocket.android.server.domain.TokenRepository
......@@ -33,6 +34,7 @@ import chat.rocket.core.internal.rest.unregisterPushToken
import chat.rocket.core.model.Myself
import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.channels.Channel
import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.withContext
import timber.log.Timber
import javax.inject.Inject
......@@ -43,6 +45,7 @@ class MainPresenter @Inject constructor(
private val navigator: MainNavigator,
private val tokenRepository: TokenRepository,
private val serverInteractor: GetCurrentServerInteractor,
private val refreshSettingsInteractor: RefreshSettingsInteractor,
private val localRepository: LocalRepository,
private val navHeaderMapper: NavHeaderUiModelMapper,
private val saveAccountInteractor: SaveAccountInteractor,
......@@ -149,6 +152,7 @@ class MainPresenter @Inject constructor(
}
fun connect() {
launch { refreshSettingsInteractor.refresh(currentServer) }
manager.connect()
}
......
......@@ -14,6 +14,7 @@ import chat.rocket.android.profile.presentation.ProfileView
import chat.rocket.android.util.extension.asObservable
import chat.rocket.android.util.extensions.*
import dagger.android.support.AndroidSupportInjection
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.rxkotlin.Observables
import kotlinx.android.synthetic.main.avatar_profile.*
......@@ -28,7 +29,7 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
private lateinit var currentEmail: String
private lateinit var currentAvatar: String
private var actionMode: ActionMode? = null
private lateinit var editTextsDisposable: Disposable
private val editTextsDisposable = CompositeDisposable()
companion object {
fun newInstance() = ProfileFragment()
......@@ -170,7 +171,7 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
}
private fun subscribeEditTexts() {
editTextsDisposable = Observables.combineLatest(
editTextsDisposable.add(Observables.combineLatest(
text_name.asObservable(),
text_username.asObservable(),
text_email.asObservable(),
......@@ -186,11 +187,11 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
} else {
finishActionMode()
}
}
})
}
private fun unsubscribeEditTexts() {
editTextsDisposable.dispose()
editTextsDisposable.clear()
}
private fun startActionMode() {
......
package chat.rocket.android.server.domain
import chat.rocket.android.db.UserDao
import chat.rocket.android.db.model.UserEntity
class GetCurrentUserInteractor(
private val tokenRepository: TokenRepository,
private val currentServer: String,
private val userDao: UserDao
) {
fun get(): UserEntity? {
return tokenRepository.get(currentServer)?.let {
userDao.getUser(it.userId)
}
}
}
......@@ -71,6 +71,7 @@ class ConnectionManager(
Timber.d("Changing status to: $status")
when (status) {
is State.Connected -> {
dbManager.clearUsersStatus()
client.subscribeSubscriptions { _, id ->
Timber.d("Subscribed to subscriptions: $id")
subscriptionId = id
......@@ -149,7 +150,7 @@ class ConnectionManager(
launch(parent = connectJob) {
for (myself in client.userDataChannel) {
Timber.d("Got userData")
userActor.send(myself.asUser())
dbManager.updateSelfUser(myself)
for (channel in userDataChannels) {
channel.send(myself)
}
......@@ -260,10 +261,6 @@ class ConnectionManager(
}
}
private fun Myself.asUser(): User {
return User(id, name, username, status, utcOffset, null, roles)
}
private fun Long.orZero(): Long {
return if (this < 0) 0 else this
}
......
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
......@@ -11,7 +11,7 @@
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent" />
<android.support.constraint.ConstraintLayout
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_container"
android:layout_width="0dp"
android:layout_height="0dp"
......@@ -20,7 +20,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar_layout">
<android.support.design.chip.ChipGroup
<com.google.android.material.chip.ChipGroup
android:id="@+id/members_chips"
style="@style/Widget.MaterialComponents.Chip.Entry"
android:layout_width="match_parent"
......@@ -31,7 +31,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</android.support.design.chip.ChipGroup>
</com.google.android.material.chip.ChipGroup>
<com.wang.avi.AVLoadingIndicatorView
android:id="@+id/view_loading"
......@@ -63,12 +63,12 @@
android:background="@color/colorDividerMessageComposer"
app:layout_constraintTop_toBottomOf="@id/text_search_member" />
<android.support.v7.widget.RecyclerView
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:scrollbars="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/separator_1" />
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
......@@ -41,4 +41,4 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="04/06/2018 14:18:36" />
</android.support.constraint.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_height"
......@@ -29,6 +29,6 @@
android:gravity="end"
android:textSize="14sp" />
</android.support.v7.widget.Toolbar>
</androidx.appcompat.widget.Toolbar>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
......@@ -265,4 +265,5 @@
<string name="read_by">Leído por</string>
<string name="message_information_title">Información del mensaje</string>
<string name="msg_log_out">Saliendo de tu cuenta…</string>
<string name="msg_sent_attachment">Envió un archivo</string>
</resources>
......@@ -293,4 +293,5 @@
<string name="read_by">Lire par</string>
<string name="message_information_title">Informations sur le message</string>
<string name="msg_log_out">Déconnecter…</string>
<string name="msg_sent_attachment">Envoyé un fichier</string>
</resources>
......@@ -272,4 +272,5 @@
<string name="read_by">Lida por</string>
<string name="message_information_title">Informações da mensagem</string>
<string name="msg_log_out">Deslogando…</string>
<string name="msg_sent_attachment">Enviou um arquivo</string>
</resources>
......@@ -124,6 +124,7 @@
<string name="msg_upload_file">Upload file</string>
<string name="msg_file_description">File description</string>
<string name="msg_send">Send</string>
<string name="msg_sent_attachment">Sent an attachment</string>
<!-- Create channel messages -->
<string name="msg_private_channel">Private</string>
......
......@@ -5,8 +5,8 @@ buildscript {
repositories {
google()
jcenter()
mavenCentral()
maven { url 'https://maven.fabric.io/public' }
mavenCentral()
}
dependencies {
......
......@@ -24,9 +24,9 @@ ext {
playServices : '15.0.0',
exoPlayer : '2.6.0',
flexbox : '0.3.2',
material : '1.0.0-alpha1',
material : '1.0.0-beta01',
room : '2.0.0-alpha1',
room : '2.0.0-beta01',
lifecycle : '2.0.0-beta01',
rxKotlin : '2.2.0',
......
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