Skip to content

Commit

Permalink
Merge pull request #332 from WideChat/cgamache_dev
Browse files Browse the repository at this point in the history
Immediate message load in room
  • Loading branch information
jaytat0 authored May 3, 2019
2 parents 2f2792c + 83e5b32 commit dc6e47d
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ class ChatRoomPresenter @Inject constructor(

private var chatRoomId: String? = null
private lateinit var chatRoomType: String
private lateinit var chatRoomName: String
private var chatIsBroadcast: Boolean = false
private var chatRoles = emptyList<ChatRoomRole>()
private val stateChannel = Channel<State>()
Expand All @@ -124,57 +125,83 @@ class ChatRoomPresenter @Inject constructor(
private lateinit var draftKey: String

fun setupChatRoom(
roomId: String,
roomName: String,
roomType: String,
chatRoomMessage: String? = null
roomId: String,
roomName: String,
roomType: String,
chatRoomMessage: String? = null
) {
draftKey = "${currentServer}_${LocalRepository.DRAFT_KEY}$roomId"
chatRoomId = roomId
chatRoomType = roomType
chatRoomName = roomName
chatRoles = emptyList()
var canModerate = isOwnerOrMod()

GlobalScope.launch(Dispatchers.IO + strategy.jobs) {
try {
chatRoles = if (roomTypeOf(roomType) !is RoomType.DirectMessage) {
client.chatRoomRoles(roomType = roomTypeOf(roomType), roomName = roomName)
} else {
emptyList()
}
} catch (ex: Exception) {
Timber.e(ex)
chatRoles = emptyList()
} finally {
// User has at least an 'owner' or 'moderator' role.
val canModerate = isOwnerOrMod()
// Can post anyway if has the 'post-readonly' permission on server.
val room = dbManager.getRoom(roomId)
room?.let {
chatIsBroadcast = it.chatRoom.broadcast ?: false
val roomUiModel = roomMapper.map(it, true)
launchUI(strategy) {
view.onRoomUpdated(roomUiModel = roomUiModel.copy(
// Can post anyway if has the 'post-readonly' permission on server.
val room = dbManager.getRoom(roomId)
room?.let {
chatIsBroadcast = it.chatRoom.broadcast ?: false
val roomUiModel = roomMapper.map(it, true)
launchUI(strategy) {
view.onRoomUpdated(roomUiModel = roomUiModel.copy(
broadcast = chatIsBroadcast,
canModerate = canModerate,
writable = roomUiModel.writable || canModerate
))
}
))
}
}

loadMessages(roomId, chatRoomType, clearDataSet = true)
loadActiveMembers(roomId, chatRoomType, filterSelfOut = true)

loadMessages(roomId, roomType, clearDataSet = true)
chatRoomMessage?.let { messageHelper.messageIdFromPermalink(it) }
chatRoomMessage?.let { messageHelper.messageIdFromPermalink(it) }
?.let { messageId ->
val name = messageHelper.roomNameFromPermalink(chatRoomMessage)
citeMessage(
name!!,
messageHelper.roomTypeFromPermalink(chatRoomMessage)!!,
messageId,
true
name!!,
messageHelper.roomTypeFromPermalink(chatRoomMessage)!!,
messageId,
true
)
}
subscribeRoomChanges()


/*FIXME: Get chat role can cause unresponsive problems especially on slower connections
We are updating the room again after the first step so that initial messages
get loaded in and the system appears more responsive. Something should be
done to either fix the load in speed of moderator roles or store the
information locally*/
if (getChatRole()) {
canModerate = isOwnerOrMod()
if (canModerate) {
//FIXME: add this in when moderator page is actually created
//view.updateModeration()
}
}

subscribeRoomChanges()
}
}

private suspend fun getChatRole() : Boolean {
var returnVal = false
try {
if (roomTypeOf(chatRoomType) !is RoomType.DirectMessage) {
chatRoles = withContext(Dispatchers.IO + strategy.jobs) {
client.chatRoomRoles(roomType = roomTypeOf(chatRoomType), roomName = chatRoomName)
}
returnVal = true
} else {
chatRoles = emptyList()
}
} catch (ex: Exception) {
Timber.e(ex)
chatRoles = emptyList()
}
return returnVal
}

private suspend fun subscribeRoomChanges() {
withContext(Dispatchers.IO + strategy.jobs) {
chatRoomId?.let {
Expand Down Expand Up @@ -206,8 +233,7 @@ class ChatRoomPresenter @Inject constructor(
) {
this.chatRoomId = chatRoomId
this.chatRoomType = chatRoomType
launchUI(strategy) {
view.showLoading()
GlobalScope.launch(Dispatchers.IO + strategy.jobs) {
try {
if (offset == 0L) {
// FIXME - load just 50 messages from DB to speed up. We will reload from Network after that
Expand Down Expand Up @@ -243,8 +269,6 @@ class ChatRoomPresenter @Inject constructor(
}.ifNull {
view.showGenericErrorMessage()
}
} finally {
view.hideLoading()
}

subscribeTypingStatus()
Expand Down Expand Up @@ -790,13 +814,15 @@ class ChatRoomPresenter @Inject constructor(
}
}

fun loadActiveMembers(
suspend fun loadActiveMembers(
chatRoomId: String,
chatRoomType: String,
offset: Long = 0,
filterSelfOut: Boolean = false
) {
launchUI(strategy) {
val activeUsers = mutableListOf<PeopleSuggestionUiModel>()

withContext(Dispatchers.IO + strategy.jobs) {
try {
val members = retryIO("getMembers($chatRoomId, $chatRoomType, $offset)") {
client.getMembers(chatRoomId, roomTypeOf(chatRoomType), offset, 50).result
Expand All @@ -806,8 +832,7 @@ class ChatRoomPresenter @Inject constructor(
val self = localRepository.get(LocalRepository.CURRENT_USERNAME_KEY)
// Take at most the 100 most recent messages distinguished by user. Can return less.
val recentMessages = messagesRepository.getRecentMessages(chatRoomId, 100)
.filterNot { filterSelfOut && it.sender?.username == self }
val activeUsers = mutableListOf<PeopleSuggestionUiModel>()
.filterNot { filterSelfOut && it.sender?.username == self }
recentMessages.forEach {
val sender = it.sender
val username = sender?.username ?: ""
Expand All @@ -817,10 +842,10 @@ class ChatRoomPresenter @Inject constructor(
val status = if (found != null) found.status else UserStatus.Offline()
val searchList = mutableListOf(username, name)
activeUsers.add(
PeopleSuggestionUiModel(
avatarUrl, username, username, name, status,
true, searchList
)
PeopleSuggestionUiModel(
avatarUrl, username, username, name, status,
true, searchList
)
)
}
// Filter out from members list the active users.
Expand All @@ -836,21 +861,22 @@ class ChatRoomPresenter @Inject constructor(
val avatarUrl = currentServer.avatarUrl(username)
val searchList = mutableListOf(username, name)
PeopleSuggestionUiModel(
avatarUrl,
username,
username,
name,
it.status,
true,
searchList
avatarUrl,
username,
username,
name,
it.status,
true,
searchList
)
})

view.populatePeopleSuggestions(activeUsers)
} catch (e: RocketChatException) {
Timber.e(e)
}
}
launchUI(strategy) {
view.populatePeopleSuggestions(activeUsers)
}
}

fun spotlight(query: String, @AutoCompleteType type: Int, filterSelfOut: Boolean = false) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -421,25 +421,12 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
}
}

if (recycler_view.adapter == null) {
recycler_view.adapter = adapter
if (dataSet.size >= 30) {
recycler_view.addOnScrollListener(endlessRecyclerViewScrollListener)
}
recycler_view.addOnLayoutChangeListener(layoutChangeListener)
recycler_view.addOnScrollListener(onScrollListener)

// Load just once, on the first page...
presenter.loadActiveMembers(chatRoomId, chatRoomType, filterSelfOut = true)
}

val oldMessagesCount = adapter.itemCount
adapter.appendData(dataSet)
if (oldMessagesCount == 0 && dataSet.isNotEmpty()) {
recycler_view.scrollToPosition(0)
verticalScrollOffset.set(0)
}
presenter.loadActiveMembers(chatRoomId, chatRoomType, filterSelfOut = true)
empty_chat_view.isVisible = adapter.itemCount == 0
dismissEmojiKeyboard()
}
Expand All @@ -460,14 +447,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
setupToolbar(roomUiModel.name.toString())
setupMessageComposer(roomUiModel)
isBroadcastChannel = roomUiModel.broadcast
if (isBroadcastChannel && !roomUiModel.canModerate) {
disableMenu = true
activity?.invalidateOptionsMenu()
}
disableMenu = (roomUiModel.broadcast && !roomUiModel.canModerate)
activity?.invalidateOptionsMenu()
}
}


override fun sendMessage(text: String) {
ui {
if (!text.isBlank()) {
Expand Down Expand Up @@ -812,7 +796,12 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
presenter.loadMessages(chatRoomId, chatRoomType, page * 30L)
}
}

recycler_view.adapter = adapter
recycler_view.addOnScrollListener(fabScrollListener)
recycler_view.addOnScrollListener(endlessRecyclerViewScrollListener)
recycler_view.addOnLayoutChangeListener(layoutChangeListener)
recycler_view.addOnScrollListener(onScrollListener)
}

private fun setupFab() {
Expand Down

0 comments on commit dc6e47d

Please sign in to comment.