WIP move data to viewModel

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
Marcel Hibbe 2025-01-21 14:06:44 +01:00
parent d450c470fe
commit b412ff7bdb
No known key found for this signature in database
GPG Key ID: C793F8B59F43CE7B
7 changed files with 183 additions and 211 deletions

View File

@ -227,4 +227,7 @@ interface NcApiCoroutines {
@Header("Authorization") authorization: String,
@Url url: String
): UserAbsenceOverall
@GET
suspend fun getRoom(@Header("Authorization") authorization: String?, @Url url: String?): RoomOverall
}

View File

@ -311,7 +311,6 @@ class ChatActivity :
var adapter: TalkMessagesListAdapter<ChatMessage>? = null
var mentionAutocomplete: Autocomplete<*>? = null
var layoutManager: LinearLayoutManager? = null
var pullChatMessagesPending = false
var startCallFromNotification: Boolean = false
var startCallFromRoomSwitch: Boolean = false
@ -434,20 +433,22 @@ class ChatActivity :
super.onCreate(savedInstanceState)
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
chatViewModel = ViewModelProvider(this, viewModelFactory)[ChatViewModel::class.java]
binding = ActivityChatBinding.inflate(layoutInflater)
setupActionBar()
// setupActionBar()
setContentView(binding.root)
setupSystemColors()
conversationUser = currentUserProvider.currentUser.blockingGet()
handleIntent(intent)
conversationUser = currentUserProvider.currentUser.blockingGet() // TODO: -> ViewModel
handleIntent(intent) // TODO: -> ViewModel
messageInputFragment = getMessageInputFragment()
chatViewModel = ViewModelProvider(this, viewModelFactory)[ChatViewModel::class.java]
chatViewModel.getRoom(roomToken)
messageInputViewModel = ViewModelProvider(this, viewModelFactory)[MessageInputViewModel::class.java]
messageInputViewModel.setData(chatViewModel.getChatRepository())
messageInputViewModel.setData(chatViewModel.getChatRepository()) // TODO: -> ViewModel
this.lifecycleScope.launch {
delay(DELAY_TO_SHOW_PROGRESS_BAR)
@ -462,8 +463,6 @@ class ChatActivity :
chatViewModel.applyPlaybackSpeedPreferences(playbackSpeedPreferences)
}
initObservers()
if (savedInstanceState != null) {
// Restore value of members from saved state
var voiceMessageId = savedInstanceState.getString(CURRENT_AUDIO_MESSAGE_KEY, "")
@ -517,7 +516,7 @@ class ChatActivity :
}
}
private fun handleIntent(intent: Intent) {
private fun handleIntent(intent: Intent) { // TODO: -> ViewModel
val extras: Bundle? = intent.extras
roomToken = extras?.getString(KEY_ROOM_TOKEN).orEmpty()
@ -578,53 +577,16 @@ class ChatActivity :
private fun initObservers() {
Log.d(TAG, "initObservers Called")
this.lifecycleScope.launch {
chatViewModel.getConversationFlow
.onEach { conversationModel ->
currentConversation = conversationModel
val urlForChatting = ApiUtils.getUrlForChat(chatApiVersion, conversationUser?.baseUrl, roomToken)
val credentials = ApiUtils.getCredentials(conversationUser!!.username, conversationUser!!.token)
chatViewModel.setData(
currentConversation!!,
credentials!!,
urlForChatting
)
logConversationInfos("GetRoomSuccessState")
if (adapter == null) {
initAdapter()
binding.messagesListView.setAdapter(adapter)
layoutManager = binding.messagesListView.layoutManager as LinearLayoutManager?
}
chatViewModel.getCapabilities(conversationUser!!, roomToken, currentConversation!!)
}.collect()
}
chatViewModel.getRoomViewState.observe(this) { state ->
when (state) {
is ChatViewModel.GetRoomSuccessState -> {
// unused atm
}
is ChatViewModel.GetRoomErrorState -> {
Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
}
else -> {}
}
}
chatViewModel.getCapabilitiesViewState.observe(this) { state ->
when (state) {
is ChatViewModel.GetCapabilitiesUpdateState -> {
if (currentConversation != null) {
if (chatViewModel.currentConversation != null) {
spreedCapabilities = state.spreedCapabilities
chatApiVersion = ApiUtils.getChatApiVersion(spreedCapabilities, intArrayOf(1))
participantPermissions = ParticipantPermissions(spreedCapabilities, currentConversation!!)
participantPermissions = ParticipantPermissions(
spreedCapabilities,
chatViewModel.currentConversation!!
)
invalidateOptionsMenu()
checkShowCallButtons()
@ -639,10 +601,21 @@ class ChatActivity :
}
is ChatViewModel.GetCapabilitiesInitialLoadState -> {
if (currentConversation != null) {
setupActionBar()
if (adapter == null) {
initAdapter()
binding.messagesListView.setAdapter(adapter)
layoutManager = binding.messagesListView.layoutManager as LinearLayoutManager?
}
if (chatViewModel.currentConversation != null) {
spreedCapabilities = state.spreedCapabilities
chatApiVersion = ApiUtils.getChatApiVersion(spreedCapabilities, intArrayOf(1))
participantPermissions = ParticipantPermissions(spreedCapabilities, currentConversation!!)
participantPermissions = ParticipantPermissions(
spreedCapabilities,
chatViewModel.currentConversation!!
)
supportFragmentManager.commit {
setReorderingAllowed(true) // optimizes out redundant replace operations
@ -662,15 +635,16 @@ class ChatActivity :
setActionBarTitle()
checkShowCallButtons()
checkLobbyState()
if (currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL &&
currentConversation?.status == "dnd"
if (chatViewModel.currentConversation?.type ==
ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL &&
chatViewModel.currentConversation?.status == "dnd"
) {
conversationUser?.let { user ->
val credentials = ApiUtils.getCredentials(user.username, user.token)
chatViewModel.outOfOfficeStatusOfUser(
credentials!!,
user.baseUrl!!,
currentConversation!!.name
chatViewModel.currentConversation!!.name
)
}
}
@ -705,11 +679,13 @@ class ChatActivity :
chatViewModel.joinRoomViewState.observe(this) { state ->
when (state) {
is ChatViewModel.JoinRoomSuccessState -> {
currentConversation = state.conversationModel
chatViewModel.currentConversation = state.conversationModel
sessionIdAfterRoomJoined = currentConversation!!.sessionId
ApplicationWideCurrentRoomHolder.getInstance().session = currentConversation!!.sessionId
ApplicationWideCurrentRoomHolder.getInstance().currentRoomToken = currentConversation!!.token
sessionIdAfterRoomJoined = chatViewModel.currentConversation!!.sessionId
ApplicationWideCurrentRoomHolder.getInstance().session =
chatViewModel.currentConversation!!.sessionId
ApplicationWideCurrentRoomHolder.getInstance().currentRoomToken =
chatViewModel.currentConversation!!.token
ApplicationWideCurrentRoomHolder.getInstance().userInRoom = conversationUser
logConversationInfos("joinRoomWithPassword#onNext")
@ -744,7 +720,7 @@ class ChatActivity :
getRoomInfoTimerHandler?.removeCallbacksAndMessages(null)
}
if (webSocketInstance != null && currentConversation != null) {
if (webSocketInstance != null && chatViewModel.currentConversation != null) {
webSocketInstance?.joinRoomWithRoomTokenAndSession(
"",
sessionIdAfterRoomJoined
@ -1159,17 +1135,15 @@ class ChatActivity :
override fun onResume() {
super.onResume()
logConversationInfos("onResume")
initObservers()
pullChatMessagesPending = false
// logConversationInfos("onResume")
webSocketInstance?.getSignalingMessageReceiver()?.addListener(localParticipantMessageListener)
webSocketInstance?.getSignalingMessageReceiver()?.addListener(conversationMessageListener)
cancelNotificationsForCurrentConversation()
chatViewModel.getRoom(roomToken)
actionBar?.show()
setupSwipeToReply()
@ -1211,8 +1185,8 @@ class ChatActivity :
}
})
loadAvatarForStatusBar()
setActionBarTitle()
// loadAvatarForStatusBar()
// setActionBarTitle()
viewThemeUtils.material.colorToolbarOverflowIcon(binding.chatToolbar)
}
@ -1245,7 +1219,7 @@ class ChatActivity :
val senderId = if (!conversationUser!!.userId.equals("?")) {
"users/" + conversationUser!!.userId
} else {
currentConversation?.actorType + "/" + currentConversation?.actorId
chatViewModel.currentConversation?.actorType + "/" + chatViewModel.currentConversation?.actorId
}
Log.d(TAG, "Initialize TalkMessagesListAdapter with senderId: $senderId")
@ -1322,7 +1296,7 @@ class ChatActivity :
val payload = MessagePayload(
roomToken,
ConversationUtils.isParticipantOwnerOrModerator(currentConversation!!),
ConversationUtils.isParticipantOwnerOrModerator(chatViewModel.currentConversation!!),
profileBottomSheet
)
@ -1525,14 +1499,14 @@ class ChatActivity :
}
private fun loadAvatarForStatusBar() {
if (currentConversation == null) {
if (chatViewModel.currentConversation == null) {
return
}
if (isOneToOneConversation()) {
var url = ApiUtils.getUrlForAvatar(
conversationUser!!.baseUrl!!,
currentConversation!!.name,
chatViewModel.currentConversation!!.name,
true
)
@ -1549,7 +1523,7 @@ class ChatActivity :
if (drawable != null && avatarSize > 0) {
val bitmap = drawable.toBitmap(avatarSize, avatarSize)
val status = StatusDrawable(
currentConversation!!.status,
chatViewModel.currentConversation!!.status,
null,
size,
0,
@ -1561,7 +1535,7 @@ class ChatActivity :
binding.chatToolbar.findViewById<ImageView>(R.id.chat_toolbar_status)
.setImageDrawable(status)
binding.chatToolbar.findViewById<ImageView>(R.id.chat_toolbar_status).contentDescription =
currentConversation?.status
chatViewModel.currentConversation?.status
binding.chatToolbar.findViewById<FrameLayout>(R.id.chat_toolbar_avatar_container)
.visibility = View.VISIBLE
} else {
@ -1599,19 +1573,19 @@ class ChatActivity :
}
fun isOneToOneConversation() =
currentConversation != null &&
currentConversation?.type != null &&
currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
chatViewModel.currentConversation != null &&
chatViewModel.currentConversation?.type != null &&
chatViewModel.currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
private fun isGroupConversation() =
currentConversation != null &&
currentConversation?.type != null &&
currentConversation?.type == ConversationEnums.ConversationType.ROOM_GROUP_CALL
chatViewModel.currentConversation != null &&
chatViewModel.currentConversation?.type != null &&
chatViewModel.currentConversation?.type == ConversationEnums.ConversationType.ROOM_GROUP_CALL
private fun isPublicConversation() =
currentConversation != null &&
currentConversation?.type != null &&
currentConversation?.type == ConversationEnums.ConversationType.ROOM_PUBLIC_CALL
chatViewModel.currentConversation != null &&
chatViewModel.currentConversation?.type != null &&
chatViewModel.currentConversation?.type == ConversationEnums.ConversationType.ROOM_PUBLIC_CALL
private fun updateRoomTimerHandler(delay: Long = -1) {
val delayForRecursiveCall = if (shouldShowLobby()) {
@ -1634,7 +1608,7 @@ class ChatActivity :
private fun switchToRoom(token: String, startCallAfterRoomSwitch: Boolean, isVoiceOnlyCall: Boolean) {
if (conversationUser != null) {
runOnUiThread {
if (currentConversation?.objectType == ConversationEnums.ObjectType.ROOM) {
if (chatViewModel.currentConversation?.objectType == ConversationEnums.ObjectType.ROOM) {
Snackbar.make(
binding.root,
context.resources.getString(R.string.switch_to_main_room),
@ -2105,7 +2079,7 @@ class ChatActivity :
private fun checkShowCallButtons() {
if (isReadOnlyConversation() ||
shouldShowLobby() ||
ConversationUtils.isNoteToSelfConversation(currentConversation)
ConversationUtils.isNoteToSelfConversation(chatViewModel.currentConversation)
) {
disableCallButtons()
} else {
@ -2125,10 +2099,11 @@ class ChatActivity :
}
private fun shouldShowLobby(): Boolean {
if (currentConversation != null) {
if (chatViewModel.currentConversation != null) {
return CapabilitiesUtil.hasSpreedFeatureCapability(spreedCapabilities, SpreedFeatures.WEBINARY_LOBBY) &&
currentConversation?.lobbyState == ConversationEnums.LobbyState.LOBBY_STATE_MODERATORS_ONLY &&
!ConversationUtils.canModerate(currentConversation!!, spreedCapabilities) &&
chatViewModel.currentConversation?.lobbyState ==
ConversationEnums.LobbyState.LOBBY_STATE_MODERATORS_ONLY &&
!ConversationUtils.canModerate(chatViewModel.currentConversation!!, spreedCapabilities) &&
!participantPermissions.canIgnoreLobby()
}
return false
@ -2161,13 +2136,13 @@ class ChatActivity :
}
private fun isReadOnlyConversation(): Boolean =
currentConversation?.conversationReadOnlyState != null &&
currentConversation?.conversationReadOnlyState ==
chatViewModel.currentConversation?.conversationReadOnlyState != null &&
chatViewModel.currentConversation?.conversationReadOnlyState ==
ConversationEnums.ConversationReadOnlyState.CONVERSATION_READ_ONLY
private fun checkLobbyState() {
if (currentConversation != null &&
ConversationUtils.isLobbyViewApplicable(currentConversation!!, spreedCapabilities) &&
if (chatViewModel.currentConversation != null &&
ConversationUtils.isLobbyViewApplicable(chatViewModel.currentConversation!!, spreedCapabilities) &&
shouldShowLobby()
) {
showLobbyView()
@ -2188,11 +2163,11 @@ class ChatActivity :
sb.append(resources!!.getText(R.string.nc_lobby_waiting))
.append("\n\n")
if (currentConversation?.lobbyTimer != null &&
currentConversation?.lobbyTimer !=
if (chatViewModel.currentConversation?.lobbyTimer != null &&
chatViewModel.currentConversation?.lobbyTimer !=
0L
) {
val timestampMS = (currentConversation?.lobbyTimer ?: 0) * DateConstants.SECOND_DIVIDER
val timestampMS = (chatViewModel.currentConversation?.lobbyTimer ?: 0) * DateConstants.SECOND_DIVIDER
val stringWithStartDate = String.format(
resources!!.getString(R.string.nc_lobby_start_date),
dateUtils.getLocalDateTimeStringFromTimestamp(timestampMS)
@ -2203,7 +2178,7 @@ class ChatActivity :
.append("\n\n")
}
sb.append(currentConversation!!.description)
sb.append(chatViewModel.currentConversation!!.description)
binding.lobby.lobbyTextView.text = sb.toString()
}
@ -2503,7 +2478,7 @@ class ChatActivity :
if (token == "") room = roomToken else room = token
chatViewModel.uploadFile(fileUri, room, currentConversation?.displayName!!, metaData)
chatViewModel.uploadFile(fileUri, room, chatViewModel.currentConversation?.displayName!!, metaData)
}
private fun showLocalFilePicker() {
@ -2560,7 +2535,7 @@ class ChatActivity :
}
private fun validSessionId(): Boolean =
currentConversation != null &&
chatViewModel.currentConversation != null &&
sessionIdAfterRoomJoined?.isNotEmpty() == true &&
sessionIdAfterRoomJoined != "0"
@ -2628,32 +2603,32 @@ class ChatActivity :
viewThemeUtils.platform.colorTextView(title, ColorRole.ON_SURFACE)
title.text =
if (currentConversation?.displayName != null) {
if (chatViewModel.currentConversation?.displayName != null) {
try {
EmojiCompat.get().process(currentConversation?.displayName as CharSequence).toString()
EmojiCompat.get().process(chatViewModel.currentConversation?.displayName as CharSequence).toString()
} catch (e: java.lang.IllegalStateException) {
Log.e(TAG, "setActionBarTitle failed $e")
currentConversation?.displayName
chatViewModel.currentConversation?.displayName
}
} else {
""
}
if (currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL) {
if (chatViewModel.currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL) {
var statusMessage = ""
if (currentConversation?.statusIcon != null) {
statusMessage += currentConversation?.statusIcon
if (chatViewModel.currentConversation?.statusIcon != null) {
statusMessage += chatViewModel.currentConversation?.statusIcon
}
if (currentConversation?.statusMessage != null) {
statusMessage += currentConversation?.statusMessage
if (chatViewModel.currentConversation?.statusMessage != null) {
statusMessage += chatViewModel.currentConversation?.statusMessage
}
statusMessageViewContents(statusMessage)
} else {
if (currentConversation?.type == ConversationEnums.ConversationType.ROOM_GROUP_CALL ||
currentConversation?.type == ConversationEnums.ConversationType.ROOM_PUBLIC_CALL
if (chatViewModel.currentConversation?.type == ConversationEnums.ConversationType.ROOM_GROUP_CALL ||
chatViewModel.currentConversation?.type == ConversationEnums.ConversationType.ROOM_PUBLIC_CALL
) {
var descriptionMessage = ""
descriptionMessage += currentConversation?.description
descriptionMessage += chatViewModel.currentConversation?.description
statusMessageViewContents(descriptionMessage)
}
}
@ -2689,7 +2664,7 @@ class ChatActivity :
private fun joinRoomWithPassword() {
// if ApplicationWideCurrentRoomHolder contains a session (because a call is active), then keep the sessionId
if (ApplicationWideCurrentRoomHolder.getInstance().currentRoomToken ==
currentConversation!!.token
chatViewModel.currentConversation!!.token
) {
sessionIdAfterRoomJoined = ApplicationWideCurrentRoomHolder.getInstance().session
@ -2733,11 +2708,11 @@ class ChatActivity :
}
private fun setupWebsocket() {
if (currentConversation == null || conversationUser == null) {
if (chatViewModel.currentConversation == null || conversationUser == null) {
return
}
if (currentConversation!!.remoteServer?.isNotEmpty() == true) {
if (chatViewModel.currentConversation!!.remoteServer?.isNotEmpty() == true) {
val apiVersion = ApiUtils.getSignalingApiVersion(conversationUser!!, intArrayOf(ApiUtils.API_V3, 2, 1))
ncApi.getSignalingSettings(
credentials,
@ -2918,9 +2893,12 @@ class ChatActivity :
chatMessage.isGrouped = groupMessages(chatMessage, previousChatMessage)
}
chatMessage.isOneToOneConversation =
(currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL)
(
chatViewModel.currentConversation?.type ==
ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
)
chatMessage.isFormerOneToOneConversation =
(currentConversation?.type == ConversationEnums.ConversationType.FORMER_ONE_TO_ONE)
(chatViewModel.currentConversation?.type == ConversationEnums.ConversationType.FORMER_ONE_TO_ONE)
Log.d(TAG, "chatMessage to add:" + chatMessage.message)
it.addToStart(chatMessage, scrollToBottom)
}
@ -2965,9 +2943,9 @@ class ChatActivity :
val chatMessage = chatMessageList[i]
chatMessage.isOneToOneConversation =
currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
chatViewModel.currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
chatMessage.isFormerOneToOneConversation =
(currentConversation?.type == ConversationEnums.ConversationType.FORMER_ONE_TO_ONE)
(chatViewModel.currentConversation?.type == ConversationEnums.ConversationType.FORMER_ONE_TO_ONE)
chatMessage.activeUser = conversationUser
chatMessage.token = roomToken
}
@ -3120,7 +3098,7 @@ class ChatActivity :
withUrl = urlForChatting,
withCredentials = credentials!!,
withMessageLimit = MESSAGE_PULL_LIMIT,
roomToken = currentConversation!!.token
roomToken = chatViewModel.currentConversation!!.token
)
}
@ -3157,9 +3135,9 @@ class ChatActivity :
val searchItem = menu.findItem(R.id.conversation_search)
searchItem.isVisible = CapabilitiesUtil.isUnifiedSearchAvailable(spreedCapabilities) &&
currentConversation!!.remoteServer.isNullOrEmpty()
chatViewModel.currentConversation!!.remoteServer.isNullOrEmpty()
if (currentConversation!!.remoteServer != null ||
if (chatViewModel.currentConversation!!.remoteServer != null ||
!CapabilitiesUtil.isSharedItemsAvailable(spreedCapabilities)
) {
menu.removeItem(R.id.shared_items)
@ -3233,18 +3211,18 @@ class ChatActivity :
private fun showSharedItems() {
val intent = Intent(this, SharedItemsActivity::class.java)
intent.putExtra(KEY_CONVERSATION_NAME, currentConversation?.displayName)
intent.putExtra(KEY_CONVERSATION_NAME, chatViewModel.currentConversation?.displayName)
intent.putExtra(KEY_ROOM_TOKEN, roomToken)
intent.putExtra(
SharedItemsActivity.KEY_USER_IS_OWNER_OR_MODERATOR,
ConversationUtils.isParticipantOwnerOrModerator(currentConversation!!)
ConversationUtils.isParticipantOwnerOrModerator(chatViewModel.currentConversation!!)
)
startActivity(intent)
}
private fun startMessageSearch() {
val intent = Intent(this, MessageSearchActivity::class.java)
intent.putExtra(KEY_CONVERSATION_NAME, currentConversation?.displayName)
intent.putExtra(KEY_CONVERSATION_NAME, chatViewModel.currentConversation?.displayName)
intent.putExtra(KEY_ROOM_TOKEN, roomToken)
startMessageSearchForResult.launch(intent)
}
@ -3293,8 +3271,7 @@ class ChatActivity :
private fun isInfoMessageAboutDeletion(currentMessage: MutableMap.MutableEntry<String, ChatMessage>): Boolean =
currentMessage.value.parentMessageId != null &&
currentMessage.value.systemMessageType == ChatMessage
.SystemMessageType.MESSAGE_DELETED
currentMessage.value.systemMessageType == ChatMessage.SystemMessageType.MESSAGE_DELETED
private fun isReactionsMessage(currentMessage: MutableMap.MutableEntry<String, ChatMessage>): Boolean =
currentMessage.value.systemMessageType == ChatMessage.SystemMessageType.REACTION ||
@ -3303,17 +3280,16 @@ class ChatActivity :
private fun isEditMessage(currentMessage: MutableMap.MutableEntry<String, ChatMessage>): Boolean =
currentMessage.value.parentMessageId != null &&
currentMessage.value.systemMessageType == ChatMessage
.SystemMessageType.MESSAGE_EDITED
currentMessage.value.systemMessageType == ChatMessage.SystemMessageType.MESSAGE_EDITED
private fun isPollVotedMessage(currentMessage: MutableMap.MutableEntry<String, ChatMessage>): Boolean =
currentMessage.value.systemMessageType == ChatMessage.SystemMessageType.POLL_VOTED
private fun startACall(isVoiceOnlyCall: Boolean, callWithoutNotification: Boolean) {
currentConversation?.let {
chatViewModel.currentConversation?.let {
if (conversationUser != null) {
val pp = ParticipantPermissions(spreedCapabilities, it)
if (!pp.canStartCall() && currentConversation?.hasCall == false) {
if (!pp.canStartCall() && chatViewModel.currentConversation?.hasCall == false) {
Snackbar.make(binding.root, R.string.startCallForbidden, Snackbar.LENGTH_LONG).show()
} else {
ApplicationWideCurrentRoomHolder.getInstance().isDialing = true
@ -3327,7 +3303,7 @@ class ChatActivity :
}
private fun getIntentForCall(isVoiceOnlyCall: Boolean, callWithoutNotification: Boolean): Intent? {
currentConversation?.let {
chatViewModel.currentConversation?.let {
val bundle = Bundle()
bundle.putString(KEY_ROOM_TOKEN, roomToken)
bundle.putString(BundleKeys.KEY_CONVERSATION_PASSWORD, roomPassword)
@ -3411,7 +3387,7 @@ class ChatActivity :
this,
message,
conversationUser,
currentConversation,
chatViewModel.currentConversation,
isShowMessageDeletionButton(message),
participantPermissions.hasChatPermission(),
spreedCapabilities
@ -3693,8 +3669,8 @@ class ChatActivity :
conversationUser?.userId?.isNotEmpty() == true &&
conversationUser!!.userId != "?" &&
message.user.id.startsWith("users/") &&
message.user.id.substring(ACTOR_LENGTH) != currentConversation?.actorId &&
currentConversation?.type != ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL ||
message.user.id.substring(ACTOR_LENGTH) != chatViewModel.currentConversation?.actorId &&
chatViewModel.currentConversation?.type != ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL ||
isShowMessageDeletionButton(message) ||
// delete
ChatMessage.MessageType.REGULAR_TEXT_MESSAGE == message.getCalculateMessageType() ||
@ -3710,7 +3686,7 @@ class ChatActivity :
messageTemp.message = getString(R.string.message_deleted_by_you)
messageTemp.isOneToOneConversation =
currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
chatViewModel.currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
messageTemp.activeUser = conversationUser
adapter?.update(messageTemp)
@ -3728,7 +3704,7 @@ class ChatActivity :
}
messageTemp.isOneToOneConversation =
currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
chatViewModel.currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
messageTemp.activeUser = conversationUser
adapter?.update(messageTemp)
@ -3740,7 +3716,7 @@ class ChatActivity :
// TODO is this needed?
messageTemp.isOneToOneConversation =
currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
chatViewModel.currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
messageTemp.activeUser = conversationUser
adapter?.update(messageTemp)
@ -3815,7 +3791,7 @@ class ChatActivity :
val isUserAllowedByPrivileges = if (message.actorId == conversationUser!!.userId) {
true
} else {
ConversationUtils.canModerate(currentConversation!!, spreedCapabilities)
ConversationUtils.canModerate(chatViewModel.currentConversation!!, spreedCapabilities)
}
return isUserAllowedByPrivileges
}
@ -3877,8 +3853,8 @@ class ChatActivity :
@Subscribe(threadMode = ThreadMode.BACKGROUND)
fun onMessageEvent(userMentionClickEvent: UserMentionClickEvent) {
if (currentConversation?.type != ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL ||
currentConversation?.name != userMentionClickEvent.userId
if (chatViewModel.currentConversation?.type != ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL ||
chatViewModel.currentConversation?.name != userMentionClickEvent.userId
) {
var apiVersion = 1
// FIXME Fix API checking with guests?
@ -3980,7 +3956,10 @@ class ChatActivity :
Log.d(TAG, " | method: $methodName")
Log.d(TAG, " | ChatActivity: " + System.identityHashCode(this).toString())
Log.d(TAG, " | roomToken: $roomToken")
Log.d(TAG, " | currentConversation?.displayName: ${currentConversation?.displayName}")
Log.d(
TAG,
" | chatViewModel.currentConversation?.displayName: ${chatViewModel.currentConversation?.displayName}"
)
Log.d(TAG, " | sessionIdAfterRoomJoined: $sessionIdAfterRoomJoined")
Log.d(TAG, " |-----------------------------------------------")
}

View File

@ -21,6 +21,7 @@ import retrofit2.Response
@Suppress("LongParameterList", "TooManyFunctions")
interface ChatNetworkDataSource {
fun getRoom(user: User, roomToken: String): Observable<ConversationModel>
suspend fun getRoomCoroutines(user: User, roomToken: String): ConversationModel
fun getCapabilities(user: User, roomToken: String): Observable<SpreedCapability>
fun joinRoom(user: User, roomToken: String, roomPassword: String): Observable<ConversationModel>
fun setReminder(

View File

@ -36,6 +36,18 @@ class RetrofitChatNetwork(
).map { ConversationModel.mapToConversationModel(it.ocs?.data!!, user) }
}
override suspend fun getRoomCoroutines(user: User, roomToken: String): ConversationModel {
val credentials: String = ApiUtils.getCredentials(user.username, user.token)!!
val apiVersion = ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V3, 1))
val conversation = ncApiCoroutines.getRoom(
credentials,
ApiUtils.getUrlForRoom(apiVersion, user.baseUrl!!, roomToken)
).ocs?.data!!
return ConversationModel.mapToConversationModel(conversation, user)
}
override fun getCapabilities(user: User, roomToken: String): Observable<SpreedCapability> {
val credentials: String = ApiUtils.getCredentials(user.username, user.token)!!
val apiVersion = ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V3, 1))

View File

@ -38,6 +38,7 @@ import com.nextcloud.talk.models.json.reminder.Reminder
import com.nextcloud.talk.models.json.userAbsence.UserAbsenceData
import com.nextcloud.talk.repositories.reactions.ReactionsRepository
import com.nextcloud.talk.ui.PlaybackSpeed
import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.ConversationUtils
import com.nextcloud.talk.utils.bundle.BundleKeys
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
@ -67,6 +68,12 @@ class ChatViewModel @Inject constructor(
) : ViewModel(),
DefaultLifecycleObserver {
var chatApiVersion: Int = 1
val currentUser: User = userProvider.currentUser.blockingGet()
lateinit var currentConversation: ConversationModel
enum class LifeCycleFlag {
PAUSED,
RESUMED,
@ -145,13 +152,6 @@ class ChatViewModel @Inject constructor(
val getLastReadMessageFlow = chatRepository.lastReadMessageFlow
val getConversationFlow = conversationRepository.conversationFlow
.onEach {
_getRoomViewState.value = GetRoomSuccessState
}.catch {
_getRoomViewState.value = GetRoomErrorState
}
val getGeneralUIFlow = chatRepository.generalUIFlow
sealed interface ViewState
@ -172,14 +172,6 @@ class ChatViewModel @Inject constructor(
val getNoteToSelfAvailability: LiveData<ViewState>
get() = _getNoteToSelfAvailability
object GetRoomStartState : ViewState
object GetRoomErrorState : ViewState
object GetRoomSuccessState : ViewState
private val _getRoomViewState: MutableLiveData<ViewState> = MutableLiveData(GetRoomStartState)
val getRoomViewState: LiveData<ViewState>
get() = _getRoomViewState
object GetCapabilitiesStartState : ViewState
object GetCapabilitiesErrorState : ViewState
open class GetCapabilitiesInitialLoadState(val spreedCapabilities: SpreedCapability) : ViewState
@ -243,16 +235,31 @@ class ChatViewModel @Inject constructor(
val reactionDeletedViewState: LiveData<ViewState>
get() = _reactionDeletedViewState
fun setData(conversationModel: ConversationModel, credentials: String, urlForChatting: String) {
chatRepository.setData(conversationModel, credentials, urlForChatting)
}
fun getRoom(token: String) {
_getRoomViewState.value = GetRoomStartState
conversationRepository.getRoom(token)
viewModelScope.launch {
conversationRepository.getRoom(token).collect { conversation ->
currentConversation = conversation!!
// val chatApiVersion = ApiUtils.getChatApiVersion(spreedCapabilities, intArrayOf(1))
val urlForChatting = ApiUtils.getUrlForChat(chatApiVersion, currentUser.baseUrl, token)
val credentials = ApiUtils.getCredentials(currentUser.username, currentUser.token)
chatRepository.setData(currentConversation, credentials!!, urlForChatting)
// logConversationInfos("GetRoomSuccessState")
// if (adapter == null) { // do later when capabilities are fetched?
// initAdapter()
// binding.messagesListView.setAdapter(adapter)
// layoutManager = binding.messagesListView.layoutManager as LinearLayoutManager?
// }
getCapabilities(currentUser, currentConversation)
}
}
}
fun getCapabilities(user: User, token: String, conversationModel: ConversationModel) {
fun getCapabilities(user: User, conversationModel: ConversationModel) {
Log.d(TAG, "Remote server ${conversationModel.remoteServer}")
if (conversationModel.remoteServer.isNullOrEmpty()) {
if (_getCapabilitiesViewState.value == GetCapabilitiesStartState) {
@ -263,7 +270,7 @@ class ChatViewModel @Inject constructor(
_getCapabilitiesViewState.value = GetCapabilitiesUpdateState(user.capabilities!!.spreedCapability!!)
}
} else {
chatNetworkDataSource.getCapabilities(user, token)
chatNetworkDataSource.getCapabilities(user, conversationModel.token)
.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.subscribe(object : Observer<SpreedCapability> {
@ -362,7 +369,6 @@ class ChatViewModel @Inject constructor(
override fun onNext(t: GenericOverall) {
_leaveRoomViewState.value = LeaveRoomSuccessState(funToCallWhenLeaveSuccessful)
_getCapabilitiesViewState.value = GetCapabilitiesStartState
_getRoomViewState.value = GetRoomStartState
}
})
}

View File

@ -18,11 +18,6 @@ interface OfflineConversationsRepository {
*/
val roomListFlow: Flow<List<ConversationModel>>
/**
* Stream of a single conversation, for use in each conversations settings.
*/
val conversationFlow: Flow<ConversationModel>
/**
* Loads rooms from local storage. If the rooms are not found, then it
* synchronizes the database with the server, before retrying exactly once. Only
@ -35,5 +30,5 @@ interface OfflineConversationsRepository {
* Called once onStart to emit a conversation to [conversationFlow]
* to be handled asynchronously.
*/
fun getRoom(roomToken: String): Job
fun getRoom(roomToken: String): Flow<ConversationModel?>
}

View File

@ -20,9 +20,7 @@ import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.models.domain.ConversationModel
import com.nextcloud.talk.utils.CapabilitiesUtil.isUserStatusAvailable
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@ -30,9 +28,9 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import javax.inject.Inject
class OfflineFirstConversationsRepository @Inject constructor(
@ -46,10 +44,6 @@ class OfflineFirstConversationsRepository @Inject constructor(
get() = _roomListFlow
private val _roomListFlow: MutableSharedFlow<List<ConversationModel>> = MutableSharedFlow()
override val conversationFlow: Flow<ConversationModel>
get() = _conversationFlow
private val _conversationFlow: MutableSharedFlow<ConversationModel> = MutableSharedFlow()
private val scope = CoroutineScope(Dispatchers.IO)
private var user: User = currentUserProviderNew.currentUser.blockingGet()
@ -67,43 +61,25 @@ class OfflineFirstConversationsRepository @Inject constructor(
}
}
override fun getRoom(roomToken: String): Job =
scope.launch {
chatNetworkDataSource.getRoom(user, roomToken)
.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.subscribe(object : Observer<ConversationModel> {
override fun onSubscribe(p0: Disposable) {
// unused atm
}
override fun onError(e: Throwable) {
runBlocking {
override fun getRoom(roomToken: String): Flow<ConversationModel?> =
flow {
try {
val conversationModel = chatNetworkDataSource.getRoomCoroutines(user, roomToken)
emit(conversationModel)
val entityList = listOf(conversationModel.asEntity())
dao.upsertConversations(entityList)
} catch (e: Exception) {
// In case network is offline or call fails
val id = user.id!!
val model = getConversation(id, roomToken)
if (model != null) {
_conversationFlow.emit(model)
emit(model)
} else {
Log.e(TAG, "Conversation model not found on device database")
}
}
}
override fun onComplete() {
// unused atm
}
override fun onNext(model: ConversationModel) {
runBlocking {
_conversationFlow.emit(model)
val entityList = listOf(model.asEntity())
dao.upsertConversations(entityList)
}
}
})
}
@Suppress("Detekt.TooGenericExceptionCaught")
private suspend fun getRoomsFromServer(): List<ConversationEntity>? {
var conversationsFromSync: List<ConversationEntity>? = null