From 8fdd1478bf0c569c1a26dc5ad3059b4015eaf879 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Wed, 4 Dec 2024 15:42:34 +0100 Subject: [PATCH 01/23] add model Signed-off-by: sowjanyakch --- .../json/userAbsence/UserAbsenceData.kt | 38 +++++++++++++++++++ .../models/json/userAbsence/UserAbsenceOCS.kt | 27 +++++++++++++ .../json/userAbsence/UserAbsenceOverall.kt | 24 ++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceData.kt create mode 100644 app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceOCS.kt create mode 100644 app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceOverall.kt diff --git a/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceData.kt b/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceData.kt new file mode 100644 index 000000000..45bd997e1 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceData.kt @@ -0,0 +1,38 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2024 Sowjanya Kota + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.nextcloud.talk.models.json.userAbsence + +import android.os.Parcelable +import com.bluelinelabs.logansquare.annotation.JsonField +import com.bluelinelabs.logansquare.annotation.JsonObject +import kotlinx.parcelize.Parcelize + +@Parcelize +@JsonObject +data class UserAbsenceData( + @JsonField(name = ["id"]) + var id: Int, + @JsonField(name = ["userId"]) + var userId: String, + @JsonField(name = ["firstDay"]) + var firstDay: String, + @JsonField(name = ["lastDay"]) + var lastDay: String, + @JsonField(name = ["status"]) + var status: String, + @JsonField(name = ["message"]) + var message: String, + @JsonField(name = ["replacementUserId"]) + var replacementUserId: String?, + @JsonField(name = ["replacementUserDisplayName"]) + var replacementUserDisplayName: String?, +) : Parcelable { + // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject' + constructor() : + this(0, "", "", "", "", "", null, null) +} diff --git a/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceOCS.kt b/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceOCS.kt new file mode 100644 index 000000000..30d41eba3 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceOCS.kt @@ -0,0 +1,27 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2024 Sowjanya Kota + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.nextcloud.talk.models.json.userAbsence + +import android.os.Parcelable +import com.bluelinelabs.logansquare.annotation.JsonField +import com.bluelinelabs.logansquare.annotation.JsonObject +import com.nextcloud.talk.models.json.generic.GenericMeta +import kotlinx.parcelize.Parcelize + +@Parcelize +@JsonObject +data class UserAbsenceOCS( + @JsonField(name = ["meta"]) + var meta: GenericMeta?, + @JsonField(name = ["data"]) + var data: UserAbsenceData? +) : Parcelable { + // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject' + constructor() : this(null, null) +} + diff --git a/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceOverall.kt b/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceOverall.kt new file mode 100644 index 000000000..c6c79626a --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceOverall.kt @@ -0,0 +1,24 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2024 Sowjanya Kota + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.nextcloud.talk.models.json.userAbsence + +import android.os.Parcelable +import com.bluelinelabs.logansquare.annotation.JsonField +import com.bluelinelabs.logansquare.annotation.JsonObject +import kotlinx.parcelize.Parcelize + +@Parcelize +@JsonObject +data class UserAbsenceOverall( + @JsonField(name = ["ocs"]) + var ocs: UserAbsenceOCS? +) : Parcelable { + // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject' + constructor() : this(null) +} + From 24ca0d6def524221f16f814c9911be8f821baf86 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Wed, 4 Dec 2024 15:51:29 +0100 Subject: [PATCH 02/23] Modify ViewModel and Repository Signed-off-by: sowjanyakch --- .../com/nextcloud/talk/api/NcApiCoroutines.kt | 9 +++++++ .../data/network/ChatNetworkDataSource.kt | 3 +++ .../chat/data/network/RetrofitChatNetwork.kt | 10 +++++++- .../talk/chat/viewmodels/ChatViewModel.kt | 25 +++++++++++++++++++ .../talk/dagger/modules/RepositoryModule.kt | 4 +-- .../java/com/nextcloud/talk/utils/ApiUtils.kt | 4 +++ 6 files changed, 52 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/api/NcApiCoroutines.kt b/app/src/main/java/com/nextcloud/talk/api/NcApiCoroutines.kt index 3bbdf0f90..5505998cf 100644 --- a/app/src/main/java/com/nextcloud/talk/api/NcApiCoroutines.kt +++ b/app/src/main/java/com/nextcloud/talk/api/NcApiCoroutines.kt @@ -13,6 +13,7 @@ import com.nextcloud.talk.models.json.generic.GenericOverall import com.nextcloud.talk.models.json.participants.AddParticipantOverall import com.nextcloud.talk.models.json.participants.TalkBan import com.nextcloud.talk.models.json.participants.TalkBanOverall +import com.nextcloud.talk.models.json.userAbsence.UserAbsenceOverall import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.http.Body @@ -197,4 +198,12 @@ interface NcApiCoroutines { @Url url: String, @Field("seconds") seconds: Int ): GenericOverall + + @GET + suspend fun getOutOfOfficeStatusForUser( + @Header("Authorization") authorization:String, + @Url url:String + ): UserAbsenceOverall + + } diff --git a/app/src/main/java/com/nextcloud/talk/chat/data/network/ChatNetworkDataSource.kt b/app/src/main/java/com/nextcloud/talk/chat/data/network/ChatNetworkDataSource.kt index 3b52c0a41..8769753d6 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/data/network/ChatNetworkDataSource.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/data/network/ChatNetworkDataSource.kt @@ -14,6 +14,7 @@ import com.nextcloud.talk.models.json.conversations.RoomOverall import com.nextcloud.talk.models.json.conversations.RoomsOverall import com.nextcloud.talk.models.json.generic.GenericOverall import com.nextcloud.talk.models.json.reminder.Reminder +import com.nextcloud.talk.models.json.userAbsence.UserAbsenceOverall import io.reactivex.Observable import retrofit2.Response @@ -63,4 +64,6 @@ interface ChatNetworkDataSource { fun createRoom(credentials: String, url: String, map: Map): Observable fun setChatReadMarker(credentials: String, url: String, previousMessageId: Int): Observable fun editChatMessage(credentials: String, url: String, text: String): Observable + suspend fun getOutOfOfficeStatusForUser (credentials:String,baseUrl:String, userId:String): UserAbsenceOverall + } diff --git a/app/src/main/java/com/nextcloud/talk/chat/data/network/RetrofitChatNetwork.kt b/app/src/main/java/com/nextcloud/talk/chat/data/network/RetrofitChatNetwork.kt index 080b0706f..590c3ba50 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/data/network/RetrofitChatNetwork.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/data/network/RetrofitChatNetwork.kt @@ -7,6 +7,7 @@ package com.nextcloud.talk.chat.data.network import com.nextcloud.talk.api.NcApi +import com.nextcloud.talk.api.NcApiCoroutines import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.models.domain.ConversationModel import com.nextcloud.talk.models.json.capabilities.SpreedCapability @@ -15,11 +16,12 @@ import com.nextcloud.talk.models.json.conversations.RoomOverall import com.nextcloud.talk.models.json.conversations.RoomsOverall import com.nextcloud.talk.models.json.generic.GenericOverall import com.nextcloud.talk.models.json.reminder.Reminder +import com.nextcloud.talk.models.json.userAbsence.UserAbsenceOverall import com.nextcloud.talk.utils.ApiUtils import io.reactivex.Observable import retrofit2.Response -class RetrofitChatNetwork(private val ncApi: NcApi) : ChatNetworkDataSource { +class RetrofitChatNetwork(private val ncApi: NcApi, private val ncApiCoroutines:NcApiCoroutines) : ChatNetworkDataSource { override fun getRoom(user: User, roomToken: String): Observable { val credentials: String = ApiUtils.getCredentials(user.username, user.token)!! val apiVersion = ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V3, 1)) @@ -178,4 +180,10 @@ class RetrofitChatNetwork(private val ncApi: NcApi) : ChatNetworkDataSource { override fun editChatMessage(credentials: String, url: String, text: String): Observable { return ncApi.editChatMessage(credentials, url, text).map { it } } + + override suspend fun getOutOfOfficeStatusForUser(credentials: String, baseUrl: String, userId:String): + UserAbsenceOverall { + return ncApiCoroutines.getOutOfOfficeStatusForUser(credentials, + ApiUtils.getUrlForOutOfOffice(baseUrl,userId)) + } } diff --git a/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt b/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt index 1798d7403..71821d1d5 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt @@ -16,6 +16,7 @@ import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope import com.nextcloud.talk.chat.data.ChatMessageRepository import com.nextcloud.talk.chat.data.io.AudioFocusRequestManager import com.nextcloud.talk.chat.data.io.MediaRecorderManager @@ -33,6 +34,7 @@ import com.nextcloud.talk.models.json.conversations.RoomOverall import com.nextcloud.talk.models.json.conversations.RoomsOverall import com.nextcloud.talk.models.json.generic.GenericOverall 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.ConversationUtils @@ -47,6 +49,7 @@ import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch import java.io.File import javax.inject.Inject @@ -109,6 +112,10 @@ class ChatViewModel @Inject constructor( val getVoiceRecordingLocked: LiveData get() = _getVoiceRecordingLocked + private val _outOfOfficeViewState = MutableLiveData(OutOfOfficeUIState.None) + val outOfOfficeViewState: LiveData + get() = _outOfOfficeViewState + private val _voiceMessagePlaybackSpeedPreferences: MutableLiveData> = MutableLiveData() val voiceMessagePlaybackSpeedPreferences: LiveData> get() = _voiceMessagePlaybackSpeedPreferences @@ -764,8 +771,26 @@ class ChatViewModel @Inject constructor( } } + fun outOfOfficeStatusOfUser(credentials:String, baseUrl: String, userId: String) { + viewModelScope.launch { + try { + val response = chatNetworkDataSource.getOutOfOfficeStatusForUser(credentials, baseUrl, userId) + _outOfOfficeViewState.value = OutOfOfficeUIState.Success(response.ocs?.data!!) + } catch (exception: Exception) { + _outOfOfficeViewState.value = OutOfOfficeUIState.Error(exception) + } + } + } + companion object { private val TAG = ChatViewModel::class.simpleName const val JOIN_ROOM_RETRY_COUNT: Long = 3 } + + + sealed class OutOfOfficeUIState { + data object None : OutOfOfficeUIState() + data class Success(val userAbsence: UserAbsenceData) : OutOfOfficeUIState() + data class Error(val exception: Exception) : OutOfOfficeUIState() + } } diff --git a/app/src/main/java/com/nextcloud/talk/dagger/modules/RepositoryModule.kt b/app/src/main/java/com/nextcloud/talk/dagger/modules/RepositoryModule.kt index b33c9ffbb..6d2bdda9d 100644 --- a/app/src/main/java/com/nextcloud/talk/dagger/modules/RepositoryModule.kt +++ b/app/src/main/java/com/nextcloud/talk/dagger/modules/RepositoryModule.kt @@ -147,8 +147,8 @@ class RepositoryModule { } @Provides - fun provideChatNetworkDataSource(ncApi: NcApi): ChatNetworkDataSource { - return RetrofitChatNetwork(ncApi) + fun provideChatNetworkDataSource(ncApi: NcApi, ncApiCoroutines: NcApiCoroutines): ChatNetworkDataSource { + return RetrofitChatNetwork(ncApi,ncApiCoroutines) } @Provides diff --git a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt index 5440e6bb1..f6b4b60d5 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt @@ -601,4 +601,8 @@ object ApiUtils { fun getUrlForArchive(version: Int, baseUrl: String?, token: String?): String { return "${getUrlForRoom(version, baseUrl, token)}/archive" } + + fun getUrlForOutOfOffice(baseUrl:String, userId:String):String{ + return "$baseUrl$OCS_API_VERSION/apps/dav/api/v1/outOfOffice/$userId/now" + } } From 6bcd24bf561de5135f9ad337ed018c0007c07f84 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Wed, 4 Dec 2024 15:59:17 +0100 Subject: [PATCH 03/23] add out_of_office_view.xml Signed-off-by: sowjanyakch --- app/src/main/res/layout/activity_chat.xml | 11 ++++ .../main/res/layout/out_of_office_view.xml | 53 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 app/src/main/res/layout/out_of_office_view.xml diff --git a/app/src/main/res/layout/activity_chat.xml b/app/src/main/res/layout/activity_chat.xml index 23e4c9de8..a6936ce88 100644 --- a/app/src/main/res/layout/activity_chat.xml +++ b/app/src/main/res/layout/activity_chat.xml @@ -127,6 +127,16 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file From 10e88f1e178f6c697a8f942ba08a93d815a5e540 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Wed, 4 Dec 2024 17:05:47 +0100 Subject: [PATCH 04/23] display out of office message in ChatActivity Signed-off-by: sowjanyakch --- .../com/nextcloud/talk/chat/ChatActivity.kt | 46 +++++++++++++++++-- app/src/main/res/values/strings.xml | 3 ++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 00706c42e..fabc4e9d1 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -616,6 +616,12 @@ class ChatActivity : urlForChatting ) + if(currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL){ + conversationUser?.let{ user -> + chatViewModel.outOfOfficeStatusOfUser(credentials, user.baseUrl!!, currentConversation!!.displayName) + } + } + logConversationInfos("GetRoomSuccessState") if (adapter == null) { @@ -687,6 +693,14 @@ class ChatActivity : checkShowCallButtons() checkLobbyState() + if(currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL){ + conversationUser?.let{ user -> + val credentials = ApiUtils.getCredentials(user.username, user.token) + chatViewModel.outOfOfficeStatusOfUser(credentials!!, user.baseUrl!!, + currentConversation!!.displayName) + } + } + updateRoomTimerHandler() val urlForChatting = @@ -1053,6 +1067,31 @@ class ChatActivity : chatViewModel.recordTouchObserver.observe(this) { y -> binding.voiceRecordingLock.y -= y } + + chatViewModel.outOfOfficeViewState.observe(this){uiState -> + when(uiState){ + is ChatViewModel.OutOfOfficeUIState.Error -> { + Log.e(TAG, "Error in outOfOfficeState",uiState.exception) + + } + ChatViewModel.OutOfOfficeUIState.None -> { + + } + is ChatViewModel.OutOfOfficeUIState.Success -> { + binding.outOfOfficeContainer.visibility = View.VISIBLE + binding.outOfOfficeContainer.findViewById(R.id.status).text = String.format( + context.resources.getString(R.string.user_absence), + uiState.userAbsence.userId + ) + binding.outOfOfficeContainer.findViewById(R.id.replacement).text = String.format( + context.resources.getString(R.string.user_absence_replacement), + uiState.userAbsence.replacementUserDisplayName + ) + binding.outOfOfficeContainer.findViewById(R.id.message).text = uiState.userAbsence.message + } + } + + } } private fun removeUnreadMessagesMarker() { @@ -3108,7 +3147,7 @@ class ChatActivity : private fun isInfoMessageAboutDeletion(currentMessage: MutableMap.MutableEntry): Boolean = currentMessage.value.parentMessageId != null && currentMessage.value.systemMessageType == ChatMessage - .SystemMessageType.MESSAGE_DELETED + .SystemMessageType.MESSAGE_DELETED private fun isReactionsMessage(currentMessage: MutableMap.MutableEntry): Boolean = currentMessage.value.systemMessageType == ChatMessage.SystemMessageType.REACTION || @@ -3118,7 +3157,7 @@ class ChatActivity : private fun isEditMessage(currentMessage: MutableMap.MutableEntry): Boolean = currentMessage.value.parentMessageId != null && currentMessage.value.systemMessageType == ChatMessage - .SystemMessageType.MESSAGE_EDITED + .SystemMessageType.MESSAGE_EDITED private fun isPollVotedMessage(currentMessage: MutableMap.MutableEntry): Boolean = currentMessage.value.systemMessageType == ChatMessage.SystemMessageType.POLL_VOTED @@ -3413,7 +3452,7 @@ class ChatActivity : val lon = data["longitude"]!! metaData = "{\"type\":\"geo-location\",\"id\":\"geo:$lat,$lon\",\"latitude\":\"$lat\"," + - "\"longitude\":\"$lon\",\"name\":\"$name\"}" + "\"longitude\":\"$lon\",\"name\":\"$name\"}" } shareToNotes(shareUri, roomToken, message, objectId, metaData) @@ -3875,3 +3914,4 @@ class ChatActivity : const val NO_OFFLINE_MESSAGES_FOUND = "NO_OFFLINE_MESSAGES_FOUND" } } + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 700af1ab2..f5a5849e9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -839,4 +839,7 @@ How to translate with transifex: Failed to set conversation Read-only Status Reverted Your status was set automatically + + %1$s is out of office and might not respond + Replacement: %1$s From e6e294096b50d8d781d0b3a6c3b013fca6227eee Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Wed, 4 Dec 2024 17:13:32 +0100 Subject: [PATCH 05/23] call API only when status is in DND mode Signed-off-by: sowjanyakch --- app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index fabc4e9d1..f2f5dcb7d 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -616,7 +616,8 @@ class ChatActivity : urlForChatting ) - if(currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL){ + if(currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL && + currentConversation?.status == "dnd"){ conversationUser?.let{ user -> chatViewModel.outOfOfficeStatusOfUser(credentials, user.baseUrl!!, currentConversation!!.displayName) } From 07accbb2b96a7dec07aab55a125832a466dd2e4a Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Wed, 4 Dec 2024 17:15:52 +0100 Subject: [PATCH 06/23] Use conversation name as userId in API call Signed-off-by: sowjanyakch --- app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index f2f5dcb7d..17237cd13 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -619,7 +619,7 @@ class ChatActivity : if(currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL && currentConversation?.status == "dnd"){ conversationUser?.let{ user -> - chatViewModel.outOfOfficeStatusOfUser(credentials, user.baseUrl!!, currentConversation!!.displayName) + chatViewModel.outOfOfficeStatusOfUser(credentials, user.baseUrl!!, currentConversation!!.name) } } From f7f73136d83e924d3a3616147b0cb8de5421d62b Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Wed, 4 Dec 2024 17:31:22 +0100 Subject: [PATCH 07/23] modify data class UserAbsenceData Signed-off-by: sowjanyakch --- .../models/json/userAbsence/UserAbsenceData.kt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceData.kt b/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceData.kt index 45bd997e1..044082703 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceData.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceData.kt @@ -16,15 +16,15 @@ import kotlinx.parcelize.Parcelize @JsonObject data class UserAbsenceData( @JsonField(name = ["id"]) - var id: Int, + var id: String, @JsonField(name = ["userId"]) var userId: String, - @JsonField(name = ["firstDay"]) - var firstDay: String, - @JsonField(name = ["lastDay"]) - var lastDay: String, - @JsonField(name = ["status"]) - var status: String, + @JsonField(name = ["startDate"]) + var startDate: Int, + @JsonField(name = ["endDate"]) + var endDate: Int, + @JsonField(name = ["shortMessage"]) + var shortMessage: String, @JsonField(name = ["message"]) var message: String, @JsonField(name = ["replacementUserId"]) @@ -34,5 +34,5 @@ data class UserAbsenceData( ) : Parcelable { // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject' constructor() : - this(0, "", "", "", "", "", null, null) + this("", "", 0, 0, "", "", null, null) } From 083f0de0639fe00c498aba8d206bf176c251ff16 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Thu, 5 Dec 2024 08:46:59 +0100 Subject: [PATCH 08/23] use proper naming Signed-off-by: sowjanyakch --- .../java/com/nextcloud/talk/chat/ChatActivity.kt | 13 +++++++------ app/src/main/res/layout/out_of_office_view.xml | 6 +++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 17237cd13..869f51f88 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -1080,15 +1080,16 @@ class ChatActivity : } is ChatViewModel.OutOfOfficeUIState.Success -> { binding.outOfOfficeContainer.visibility = View.VISIBLE - binding.outOfOfficeContainer.findViewById(R.id.status).text = String.format( + binding.outOfOfficeContainer.findViewById(R.id.userAbsenceShortMessage).text = String.format( context.resources.getString(R.string.user_absence), uiState.userAbsence.userId ) - binding.outOfOfficeContainer.findViewById(R.id.replacement).text = String.format( - context.resources.getString(R.string.user_absence_replacement), - uiState.userAbsence.replacementUserDisplayName - ) - binding.outOfOfficeContainer.findViewById(R.id.message).text = uiState.userAbsence.message + binding.outOfOfficeContainer.findViewById(R.id.absenceReplacement).text = String.format( + context.resources.getString(R.string.user_absence_replacement), + uiState.userAbsence.replacementUserDisplayName + ) + + binding.outOfOfficeContainer.findViewById(R.id.userAbsenceLongMessage).text = uiState.userAbsence.message } } diff --git a/app/src/main/res/layout/out_of_office_view.xml b/app/src/main/res/layout/out_of_office_view.xml index 2d416a83b..075672008 100644 --- a/app/src/main/res/layout/out_of_office_view.xml +++ b/app/src/main/res/layout/out_of_office_view.xml @@ -23,7 +23,7 @@ app:cornerRadius="8dp"> Date: Thu, 5 Dec 2024 08:49:33 +0100 Subject: [PATCH 09/23] show replacement only if the user set a replacement Signed-off-by: sowjanyakch --- app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 869f51f88..257925efc 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -1084,11 +1084,14 @@ class ChatActivity : context.resources.getString(R.string.user_absence), uiState.userAbsence.userId ) + if(uiState.userAbsence.replacementUserDisplayName != null){ binding.outOfOfficeContainer.findViewById(R.id.absenceReplacement).text = String.format( context.resources.getString(R.string.user_absence_replacement), uiState.userAbsence.replacementUserDisplayName ) - + }else{ + binding.outOfOfficeContainer.findViewById(R.id.absenceReplacement).visibility = View.GONE + } binding.outOfOfficeContainer.findViewById(R.id.userAbsenceLongMessage).text = uiState.userAbsence.message } } From ecd5bfdf412613ba9e9edf8fe0cab3321e3fd2a7 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Thu, 5 Dec 2024 10:09:59 +0100 Subject: [PATCH 10/23] apply styling Signed-off-by: sowjanyakch --- app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt | 1 + app/src/main/res/layout/out_of_office_view.xml | 8 ++++---- app/src/main/res/values-night/colors.xml | 3 +++ app/src/main/res/values/colors.xml | 3 +++ app/src/main/res/values/styles.xml | 4 ++++ 5 files changed, 15 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 257925efc..72f1b69a4 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -46,6 +46,7 @@ import android.widget.AbsListView import android.widget.FrameLayout import android.widget.ImageView import android.widget.PopupMenu +import android.widget.ScrollView import android.widget.TextView import androidx.activity.OnBackPressedCallback import androidx.activity.result.ActivityResult diff --git a/app/src/main/res/layout/out_of_office_view.xml b/app/src/main/res/layout/out_of_office_view.xml index 075672008..7b6bbc0a1 100644 --- a/app/src/main/res/layout/out_of_office_view.xml +++ b/app/src/main/res/layout/out_of_office_view.xml @@ -11,7 +11,7 @@ android:layout_height="150dp" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/out_of_office_view" - android:background="#333399"> + style="@style/ScrollViewStyle"> @@ -36,7 +36,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" - android:textColor="#FFFFFF" + android:textColor="@color/scrollview_out_of_office_text" android:textSize="14sp" android:textStyle="bold" tools:text="Replacement: Bob"/> @@ -46,7 +46,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="12dp" - android:textColor="#FFFFFF" + android:textColor="@color/scrollview_out_of_office_text" android:textSize="14sp" tools:text="Hi, I am out of office this week. Please contact ....., ..........write very very very very very very very very very very very very very very very long message..................................................................................................................................if you have any issues."/> diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index 7b4c18f30..36bacfe12 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -61,4 +61,7 @@ #99FFFFFF + #cee7fe + #5e95b4 + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index a49e2de29..5b6cc5b30 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -93,4 +93,7 @@ #EF3B02 #DBE2E9 + #cee5fd + #08486e + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 7c9821c63..8a68fa32d 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -288,4 +288,8 @@ 50% + + From 4bdedfbc0ded2378bc98678610d269ea62b6b2a5 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Thu, 5 Dec 2024 15:19:55 +0100 Subject: [PATCH 11/23] show userAbsence period Signed-off-by: sowjanyakch --- .../com/nextcloud/talk/chat/ChatActivity.kt | 41 ++++++++++++++++--- .../main/res/layout/out_of_office_view.xml | 16 +++++--- app/src/main/res/values/strings.xml | 1 + 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 72f1b69a4..a5a3175ed 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -206,6 +206,7 @@ import java.io.File import java.io.IOException import java.net.HttpURLConnection import java.text.SimpleDateFormat +import java.util.Calendar import java.util.Date import java.util.Locale import java.util.concurrent.ExecutionException @@ -569,7 +570,7 @@ class ChatActivity : this.lifecycle.removeObserver(chatViewModel) } - @SuppressLint("NotifyDataSetChanged") + @SuppressLint("NotifyDataSetChanged", "SetTextI18n") @Suppress("LongMethod") private fun initObservers() { Log.d(TAG, "initObservers Called") @@ -1081,10 +1082,40 @@ class ChatActivity : } is ChatViewModel.OutOfOfficeUIState.Success -> { binding.outOfOfficeContainer.visibility = View.VISIBLE - binding.outOfOfficeContainer.findViewById(R.id.userAbsenceShortMessage).text = String.format( - context.resources.getString(R.string.user_absence), - uiState.userAbsence.userId - ) + + + val startDateTimestamp:Long = uiState.userAbsence.startDate.toLong() + val endDateTimestamp:Long = uiState.userAbsence.endDate.toLong() + + val startDate = Date(startDateTimestamp * 1000) + val endDate = Date(endDateTimestamp * 1000) + + val date1 = Calendar.getInstance().apply{time = startDate} + val date2 = Calendar.getInstance().apply{time = endDate} + + val isSameDay = date1.get(Calendar.YEAR) == date2.get(Calendar.YEAR) && + date1.get(Calendar.DAY_OF_YEAR) == date2.get(Calendar.DAY_OF_YEAR) + + if (isSameDay) { + binding.outOfOfficeContainer.findViewById(R.id.userAbsenceShortMessage).text = String.format( + context.resources.getString(R.string.user_absence_for_one_day), + uiState.userAbsence.userId + ) + binding.outOfOfficeContainer.findViewById(R.id.userAbsencePeriod).visibility = + View.GONE + } else { + val dateFormatter = SimpleDateFormat("MMM d, yyyy", Locale.getDefault()) + val startDateString = dateFormatter.format(startDate) + val endDateString = dateFormatter.format(endDate) + binding.outOfOfficeContainer.findViewById(R.id.userAbsenceShortMessage).text = String.format( + context.resources.getString(R.string.user_absence), + uiState.userAbsence.userId + ) + + binding.outOfOfficeContainer.findViewById(R.id.userAbsencePeriod).text = "$startDateString - $endDateString" + } + + if(uiState.userAbsence.replacementUserDisplayName != null){ binding.outOfOfficeContainer.findViewById(R.id.absenceReplacement).text = String.format( context.resources.getString(R.string.user_absence_replacement), diff --git a/app/src/main/res/layout/out_of_office_view.xml b/app/src/main/res/layout/out_of_office_view.xml index 7b6bbc0a1..4d3639768 100644 --- a/app/src/main/res/layout/out_of_office_view.xml +++ b/app/src/main/res/layout/out_of_office_view.xml @@ -18,7 +18,6 @@ android:layout_height="wrap_content" android:orientation="vertical" android:padding="8dp" - android:layout_margin="8dp" android:elevation="4dp" app:cornerRadius="8dp"> @@ -26,27 +25,32 @@ android:id="@+id/userAbsenceShortMessage" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textColor="@color/scrollview_out_of_office_text" android:textSize="16sp" android:textStyle="bold" + android:layout_marginTop ="8dp" tools:text="Jane is out of office"/> + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f5a5849e9..2357fd8ef 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -841,5 +841,6 @@ How to translate with transifex: Your status was set automatically %1$s is out of office and might not respond + %1$s is out of office today Replacement: %1$s From e7c540870b8cbc01b414477e66d6a8baaeed6c66 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Thu, 5 Dec 2024 15:34:42 +0100 Subject: [PATCH 12/23] ui changes to out_of_office_view Signed-off-by: sowjanyakch --- .../main/java/com/nextcloud/talk/chat/ChatActivity.kt | 1 - app/src/main/res/layout/out_of_office_view.xml | 9 ++++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index a5a3175ed..91f5feff1 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -46,7 +46,6 @@ import android.widget.AbsListView import android.widget.FrameLayout import android.widget.ImageView import android.widget.PopupMenu -import android.widget.ScrollView import android.widget.TextView import androidx.activity.OnBackPressedCallback import androidx.activity.result.ActivityResult diff --git a/app/src/main/res/layout/out_of_office_view.xml b/app/src/main/res/layout/out_of_office_view.xml index 4d3639768..354541450 100644 --- a/app/src/main/res/layout/out_of_office_view.xml +++ b/app/src/main/res/layout/out_of_office_view.xml @@ -8,7 +8,9 @@ @@ -16,10 +18,7 @@ + android:orientation="vertical"> Date: Thu, 5 Dec 2024 15:36:51 +0100 Subject: [PATCH 13/23] remove unused namespace declaration Signed-off-by: sowjanyakch --- app/src/main/res/layout/out_of_office_view.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/res/layout/out_of_office_view.xml b/app/src/main/res/layout/out_of_office_view.xml index 354541450..e4f8dc825 100644 --- a/app/src/main/res/layout/out_of_office_view.xml +++ b/app/src/main/res/layout/out_of_office_view.xml @@ -6,7 +6,6 @@ ~ SPDX-License-Identifier: GPL-3.0-or-later --> Date: Thu, 5 Dec 2024 15:51:27 +0100 Subject: [PATCH 14/23] format code Signed-off-by: sowjanyakch --- .../com/nextcloud/talk/api/NcApiCoroutines.kt | 6 +- .../com/nextcloud/talk/chat/ChatActivity.kt | 96 ++++++++++--------- .../data/network/ChatNetworkDataSource.kt | 3 +- .../chat/data/network/RetrofitChatNetwork.kt | 15 ++- .../talk/chat/viewmodels/ChatViewModel.kt | 3 +- .../talk/dagger/modules/RepositoryModule.kt | 2 +- .../json/userAbsence/UserAbsenceData.kt | 2 +- .../models/json/userAbsence/UserAbsenceOCS.kt | 1 - .../json/userAbsence/UserAbsenceOverall.kt | 1 - .../java/com/nextcloud/talk/utils/ApiUtils.kt | 2 +- 10 files changed, 66 insertions(+), 65 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/api/NcApiCoroutines.kt b/app/src/main/java/com/nextcloud/talk/api/NcApiCoroutines.kt index 5505998cf..26e67f261 100644 --- a/app/src/main/java/com/nextcloud/talk/api/NcApiCoroutines.kt +++ b/app/src/main/java/com/nextcloud/talk/api/NcApiCoroutines.kt @@ -201,9 +201,7 @@ interface NcApiCoroutines { @GET suspend fun getOutOfOfficeStatusForUser( - @Header("Authorization") authorization:String, - @Url url:String + @Header("Authorization") authorization: String, + @Url url: String ): UserAbsenceOverall - - } diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 91f5feff1..d5de6a60d 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -617,10 +617,15 @@ class ChatActivity : urlForChatting ) - if(currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL && - currentConversation?.status == "dnd"){ - conversationUser?.let{ user -> - chatViewModel.outOfOfficeStatusOfUser(credentials, user.baseUrl!!, currentConversation!!.name) + if (currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL && + currentConversation?.status == "dnd" + ) { + conversationUser?.let { user -> + chatViewModel.outOfOfficeStatusOfUser( + credentials, + user.baseUrl!!, + currentConversation!!.name + ) } } @@ -695,11 +700,14 @@ class ChatActivity : checkShowCallButtons() checkLobbyState() - if(currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL){ - conversationUser?.let{ user -> + if (currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL) { + conversationUser?.let { user -> val credentials = ApiUtils.getCredentials(user.username, user.token) - chatViewModel.outOfOfficeStatusOfUser(credentials!!, user.baseUrl!!, - currentConversation!!.displayName) + chatViewModel.outOfOfficeStatusOfUser( + credentials!!, + user.baseUrl!!, + currentConversation!!.displayName + ) } } @@ -1070,63 +1078,58 @@ class ChatActivity : binding.voiceRecordingLock.y -= y } - chatViewModel.outOfOfficeViewState.observe(this){uiState -> - when(uiState){ + chatViewModel.outOfOfficeViewState.observe(this) { uiState -> + when (uiState) { is ChatViewModel.OutOfOfficeUIState.Error -> { - Log.e(TAG, "Error in outOfOfficeState",uiState.exception) - + Log.e(TAG, "Error in outOfOfficeState", uiState.exception) } ChatViewModel.OutOfOfficeUIState.None -> { - } is ChatViewModel.OutOfOfficeUIState.Success -> { binding.outOfOfficeContainer.visibility = View.VISIBLE + val startDateTimestamp: Long = uiState.userAbsence.startDate.toLong() + val endDateTimestamp: Long = uiState.userAbsence.endDate.toLong() - val startDateTimestamp:Long = uiState.userAbsence.startDate.toLong() - val endDateTimestamp:Long = uiState.userAbsence.endDate.toLong() + val startDate = Date(startDateTimestamp * 1000) + val endDate = Date(endDateTimestamp * 1000) - val startDate = Date(startDateTimestamp * 1000) - val endDate = Date(endDateTimestamp * 1000) + val date1 = Calendar.getInstance().apply { time = startDate } + val date2 = Calendar.getInstance().apply { time = endDate } - val date1 = Calendar.getInstance().apply{time = startDate} - val date2 = Calendar.getInstance().apply{time = endDate} + val isSameDay = date1.get(Calendar.YEAR) == date2.get(Calendar.YEAR) && + date1.get(Calendar.DAY_OF_YEAR) == date2.get(Calendar.DAY_OF_YEAR) - val isSameDay = date1.get(Calendar.YEAR) == date2.get(Calendar.YEAR) && - date1.get(Calendar.DAY_OF_YEAR) == date2.get(Calendar.DAY_OF_YEAR) + if (isSameDay) { + binding.outOfOfficeContainer.findViewById(R.id.userAbsenceShortMessage).text = String.format( + context.resources.getString(R.string.user_absence_for_one_day), + uiState.userAbsence.userId + ) + binding.outOfOfficeContainer.findViewById(R.id.userAbsencePeriod).visibility = + View.GONE + } else { + val dateFormatter = SimpleDateFormat("MMM d, yyyy", Locale.getDefault()) + val startDateString = dateFormatter.format(startDate) + val endDateString = dateFormatter.format(endDate) + binding.outOfOfficeContainer.findViewById(R.id.userAbsenceShortMessage).text = String.format( + context.resources.getString(R.string.user_absence), + uiState.userAbsence.userId + ) - if (isSameDay) { - binding.outOfOfficeContainer.findViewById(R.id.userAbsenceShortMessage).text = String.format( - context.resources.getString(R.string.user_absence_for_one_day), - uiState.userAbsence.userId - ) - binding.outOfOfficeContainer.findViewById(R.id.userAbsencePeriod).visibility = - View.GONE - } else { - val dateFormatter = SimpleDateFormat("MMM d, yyyy", Locale.getDefault()) - val startDateString = dateFormatter.format(startDate) - val endDateString = dateFormatter.format(endDate) - binding.outOfOfficeContainer.findViewById(R.id.userAbsenceShortMessage).text = String.format( - context.resources.getString(R.string.user_absence), - uiState.userAbsence.userId - ) + binding.outOfOfficeContainer.findViewById(R.id.userAbsencePeriod).text = "$startDateString - $endDateString" + } - binding.outOfOfficeContainer.findViewById(R.id.userAbsencePeriod).text = "$startDateString - $endDateString" - } - - - if(uiState.userAbsence.replacementUserDisplayName != null){ + if (uiState.userAbsence.replacementUserDisplayName != null) { binding.outOfOfficeContainer.findViewById(R.id.absenceReplacement).text = String.format( context.resources.getString(R.string.user_absence_replacement), uiState.userAbsence.replacementUserDisplayName ) - }else{ + } else { binding.outOfOfficeContainer.findViewById(R.id.absenceReplacement).visibility = View.GONE } binding.outOfOfficeContainer.findViewById(R.id.userAbsenceLongMessage).text = uiState.userAbsence.message } } - } } @@ -3183,7 +3186,7 @@ class ChatActivity : private fun isInfoMessageAboutDeletion(currentMessage: MutableMap.MutableEntry): Boolean = currentMessage.value.parentMessageId != null && currentMessage.value.systemMessageType == ChatMessage - .SystemMessageType.MESSAGE_DELETED + .SystemMessageType.MESSAGE_DELETED private fun isReactionsMessage(currentMessage: MutableMap.MutableEntry): Boolean = currentMessage.value.systemMessageType == ChatMessage.SystemMessageType.REACTION || @@ -3193,7 +3196,7 @@ class ChatActivity : private fun isEditMessage(currentMessage: MutableMap.MutableEntry): Boolean = currentMessage.value.parentMessageId != null && currentMessage.value.systemMessageType == ChatMessage - .SystemMessageType.MESSAGE_EDITED + .SystemMessageType.MESSAGE_EDITED private fun isPollVotedMessage(currentMessage: MutableMap.MutableEntry): Boolean = currentMessage.value.systemMessageType == ChatMessage.SystemMessageType.POLL_VOTED @@ -3488,7 +3491,7 @@ class ChatActivity : val lon = data["longitude"]!! metaData = "{\"type\":\"geo-location\",\"id\":\"geo:$lat,$lon\",\"latitude\":\"$lat\"," + - "\"longitude\":\"$lon\",\"name\":\"$name\"}" + "\"longitude\":\"$lon\",\"name\":\"$name\"}" } shareToNotes(shareUri, roomToken, message, objectId, metaData) @@ -3950,4 +3953,3 @@ class ChatActivity : const val NO_OFFLINE_MESSAGES_FOUND = "NO_OFFLINE_MESSAGES_FOUND" } } - diff --git a/app/src/main/java/com/nextcloud/talk/chat/data/network/ChatNetworkDataSource.kt b/app/src/main/java/com/nextcloud/talk/chat/data/network/ChatNetworkDataSource.kt index 8769753d6..81a6ec6c8 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/data/network/ChatNetworkDataSource.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/data/network/ChatNetworkDataSource.kt @@ -64,6 +64,5 @@ interface ChatNetworkDataSource { fun createRoom(credentials: String, url: String, map: Map): Observable fun setChatReadMarker(credentials: String, url: String, previousMessageId: Int): Observable fun editChatMessage(credentials: String, url: String, text: String): Observable - suspend fun getOutOfOfficeStatusForUser (credentials:String,baseUrl:String, userId:String): UserAbsenceOverall - + suspend fun getOutOfOfficeStatusForUser(credentials: String, baseUrl: String, userId: String): UserAbsenceOverall } diff --git a/app/src/main/java/com/nextcloud/talk/chat/data/network/RetrofitChatNetwork.kt b/app/src/main/java/com/nextcloud/talk/chat/data/network/RetrofitChatNetwork.kt index 590c3ba50..19b067608 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/data/network/RetrofitChatNetwork.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/data/network/RetrofitChatNetwork.kt @@ -21,7 +21,7 @@ import com.nextcloud.talk.utils.ApiUtils import io.reactivex.Observable import retrofit2.Response -class RetrofitChatNetwork(private val ncApi: NcApi, private val ncApiCoroutines:NcApiCoroutines) : ChatNetworkDataSource { +class RetrofitChatNetwork(private val ncApi: NcApi, private val ncApiCoroutines: NcApiCoroutines) : ChatNetworkDataSource { override fun getRoom(user: User, roomToken: String): Observable { val credentials: String = ApiUtils.getCredentials(user.username, user.token)!! val apiVersion = ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V3, 1)) @@ -181,9 +181,14 @@ class RetrofitChatNetwork(private val ncApi: NcApi, private val ncApiCoroutines: return ncApi.editChatMessage(credentials, url, text).map { it } } - override suspend fun getOutOfOfficeStatusForUser(credentials: String, baseUrl: String, userId:String): - UserAbsenceOverall { - return ncApiCoroutines.getOutOfOfficeStatusForUser(credentials, - ApiUtils.getUrlForOutOfOffice(baseUrl,userId)) + override suspend fun getOutOfOfficeStatusForUser( + credentials: String, + baseUrl: String, + userId: String + ): UserAbsenceOverall { + return ncApiCoroutines.getOutOfOfficeStatusForUser( + credentials, + ApiUtils.getUrlForOutOfOffice(baseUrl, userId) + ) } } diff --git a/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt b/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt index 71821d1d5..328170b34 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt @@ -771,7 +771,7 @@ class ChatViewModel @Inject constructor( } } - fun outOfOfficeStatusOfUser(credentials:String, baseUrl: String, userId: String) { + fun outOfOfficeStatusOfUser(credentials: String, baseUrl: String, userId: String) { viewModelScope.launch { try { val response = chatNetworkDataSource.getOutOfOfficeStatusForUser(credentials, baseUrl, userId) @@ -787,7 +787,6 @@ class ChatViewModel @Inject constructor( const val JOIN_ROOM_RETRY_COUNT: Long = 3 } - sealed class OutOfOfficeUIState { data object None : OutOfOfficeUIState() data class Success(val userAbsence: UserAbsenceData) : OutOfOfficeUIState() diff --git a/app/src/main/java/com/nextcloud/talk/dagger/modules/RepositoryModule.kt b/app/src/main/java/com/nextcloud/talk/dagger/modules/RepositoryModule.kt index 6d2bdda9d..0efa202ce 100644 --- a/app/src/main/java/com/nextcloud/talk/dagger/modules/RepositoryModule.kt +++ b/app/src/main/java/com/nextcloud/talk/dagger/modules/RepositoryModule.kt @@ -148,7 +148,7 @@ class RepositoryModule { @Provides fun provideChatNetworkDataSource(ncApi: NcApi, ncApiCoroutines: NcApiCoroutines): ChatNetworkDataSource { - return RetrofitChatNetwork(ncApi,ncApiCoroutines) + return RetrofitChatNetwork(ncApi, ncApiCoroutines) } @Provides diff --git a/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceData.kt b/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceData.kt index 044082703..77e71e8c7 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceData.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceData.kt @@ -30,7 +30,7 @@ data class UserAbsenceData( @JsonField(name = ["replacementUserId"]) var replacementUserId: String?, @JsonField(name = ["replacementUserDisplayName"]) - var replacementUserDisplayName: String?, + var replacementUserDisplayName: String? ) : Parcelable { // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject' constructor() : diff --git a/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceOCS.kt b/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceOCS.kt index 30d41eba3..06a80c4ca 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceOCS.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceOCS.kt @@ -24,4 +24,3 @@ data class UserAbsenceOCS( // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject' constructor() : this(null, null) } - diff --git a/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceOverall.kt b/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceOverall.kt index c6c79626a..7f6fada53 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceOverall.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/userAbsence/UserAbsenceOverall.kt @@ -21,4 +21,3 @@ data class UserAbsenceOverall( // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject' constructor() : this(null) } - diff --git a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt index f6b4b60d5..f46c6ea0e 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt @@ -602,7 +602,7 @@ object ApiUtils { return "${getUrlForRoom(version, baseUrl, token)}/archive" } - fun getUrlForOutOfOffice(baseUrl:String, userId:String):String{ + fun getUrlForOutOfOffice(baseUrl: String, userId: String): String { return "$baseUrl$OCS_API_VERSION/apps/dav/api/v1/outOfOffice/$userId/now" } } From ca4ace687c33e6ec3ea61ece5d5be00369577873 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Fri, 6 Dec 2024 18:40:50 +0100 Subject: [PATCH 15/23] use proper color for out of office view Signed-off-by: sowjanyakch --- .../com/nextcloud/talk/chat/ChatActivity.kt | 7 ++++++- app/src/main/res/layout/activity_chat.xml | 15 ++++++++++----- app/src/main/res/layout/out_of_office_view.xml | 17 +++++++++++++---- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index d5de6a60d..55535f91f 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -51,9 +51,11 @@ import androidx.activity.OnBackPressedCallback import androidx.activity.result.ActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.view.ContextThemeWrapper +import androidx.core.content.ContextCompat import androidx.core.content.FileProvider import androidx.core.content.PermissionChecker import androidx.core.content.PermissionChecker.PERMISSION_GRANTED +import androidx.core.graphics.ColorUtils import androidx.core.graphics.drawable.toBitmap import androidx.core.text.bold import androidx.emoji2.text.EmojiCompat @@ -569,7 +571,7 @@ class ChatActivity : this.lifecycle.removeObserver(chatViewModel) } - @SuppressLint("NotifyDataSetChanged", "SetTextI18n") + @SuppressLint("NotifyDataSetChanged", "SetTextI18n", "ResourceAsColor") @Suppress("LongMethod") private fun initObservers() { Log.d(TAG, "initObservers Called") @@ -1087,6 +1089,9 @@ class ChatActivity : } is ChatViewModel.OutOfOfficeUIState.Success -> { binding.outOfOfficeContainer.visibility = View.VISIBLE + val backgroundColor = ContextCompat.getColor(this, R.color.colorPrimary) + val setAlpha = ColorUtils.setAlphaComponent(backgroundColor, (0.2f * 255).toInt()) + binding.outOfOfficeContainer.setCardBackgroundColor(setAlpha) val startDateTimestamp: Long = uiState.userAbsence.startDate.toLong() val endDateTimestamp: Long = uiState.userAbsence.endDate.toLong() diff --git a/app/src/main/res/layout/activity_chat.xml b/app/src/main/res/layout/activity_chat.xml index a6936ce88..87b8c58f1 100644 --- a/app/src/main/res/layout/activity_chat.xml +++ b/app/src/main/res/layout/activity_chat.xml @@ -127,15 +127,18 @@ - + tools:visibility="visible" + android:layout_margin="8dp" + app:cardCornerRadius="12dp"> - - + + + + android:id="@+id/out_of_office_view"> + + + + + \ No newline at end of file From 9a481aefc8b32b2be9dcc40fe5acd20b66e7cfd2 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Mon, 9 Dec 2024 09:11:08 +0100 Subject: [PATCH 16/23] create chip for avatar icon and name Signed-off-by: sowjanyakch --- .../com/nextcloud/talk/chat/ChatActivity.kt | 21 ++++++-- .../java/com/nextcloud/talk/utils/ApiUtils.kt | 6 +++ .../main/res/layout/out_of_office_view.xml | 54 ++++++++++++++++--- app/src/main/res/values/strings.xml | 2 +- 4 files changed, 72 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 55535f91f..1690aaac2 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -72,6 +72,7 @@ import androidx.work.WorkInfo import androidx.work.WorkManager import autodagger.AutoInjector import coil.imageLoader +import coil.load import coil.request.CachePolicy import coil.request.ImageRequest import coil.target.Target @@ -1125,10 +1126,24 @@ class ChatActivity : } if (uiState.userAbsence.replacementUserDisplayName != null) { - binding.outOfOfficeContainer.findViewById(R.id.absenceReplacement).text = String.format( - context.resources.getString(R.string.user_absence_replacement), + var imageUri = Uri.parse(ApiUtils.getUrlForAvatar(conversationUser?.baseUrl, uiState.userAbsence + .replacementUserId, false)) + if (DisplayUtils.isDarkModeOn(context)) { + imageUri = Uri.parse(ApiUtils.getUrlForAvatarDarkTheme(conversationUser?.baseUrl, uiState + .userAbsence + .replacementUserId, false)) + } + binding.outOfOfficeContainer.findViewById(R.id.absenceReplacement).text = context.resources.getString(R.string.user_absence_replacement) + binding.outOfOfficeContainer.findViewById(R.id.replacement_user_avatar) + .load(imageUri){ + transformations(CircleCropTransformation()) + placeholder(R.drawable.account_circle_96dp) + error(R.drawable.account_circle_96dp) + crossfade(true) + } + binding.outOfOfficeContainer.findViewById(R.id.replacement_user_name).text = uiState.userAbsence.replacementUserDisplayName - ) + } else { binding.outOfOfficeContainer.findViewById(R.id.absenceReplacement).visibility = View.GONE } diff --git a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt index f46c6ea0e..b192c881a 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt @@ -372,6 +372,12 @@ object ApiUtils { return baseUrl + "/index.php/avatar/" + Uri.encode(name) + "/" + avatarSize } + @JvmStatic + fun getUrlForAvatarDarkTheme(baseUrl: String?, name: String?, requestBigSize: Boolean): String { + val avatarSize = if (requestBigSize) AVATAR_SIZE_BIG else AVATAR_SIZE_SMALL + return baseUrl + "/index.php/avatar/" + Uri.encode(name) + "/" + avatarSize + "/dark" + } + @JvmStatic fun getUrlForFederatedAvatar( baseUrl: String, diff --git a/app/src/main/res/layout/out_of_office_view.xml b/app/src/main/res/layout/out_of_office_view.xml index 1037b627b..cfdc30ea5 100644 --- a/app/src/main/res/layout/out_of_office_view.xml +++ b/app/src/main/res/layout/out_of_office_view.xml @@ -7,8 +7,8 @@ --> @@ -44,13 +44,53 @@ android:textSize="14sp" tools:text="Dec 5, 2024 - Dec 15, 2024"/> - + android:orientation="horizontal" + android:layout_marginTop ="8dp" + android:gravity="center_vertical"> + + + + + + + + + + + + %1$s is out of office and might not respond %1$s is out of office today - Replacement: %1$s + Replacement From cadb12cd0fd2dab1d71eabe6a1e65b88c263a9ee Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Mon, 9 Dec 2024 11:16:43 +0100 Subject: [PATCH 17/23] join 1:1 conversation with replacement user Signed-off-by: sowjanyakch --- .../com/nextcloud/talk/chat/ChatActivity.kt | 47 ++++++++++++++++--- .../java/com/nextcloud/talk/utils/ApiUtils.kt | 2 +- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 1690aaac2..9b0d42557 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -51,6 +51,7 @@ import androidx.activity.OnBackPressedCallback import androidx.activity.result.ActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.view.ContextThemeWrapper +import androidx.cardview.widget.CardView import androidx.core.content.ContextCompat import androidx.core.content.FileProvider import androidx.core.content.PermissionChecker @@ -1126,16 +1127,28 @@ class ChatActivity : } if (uiState.userAbsence.replacementUserDisplayName != null) { - var imageUri = Uri.parse(ApiUtils.getUrlForAvatar(conversationUser?.baseUrl, uiState.userAbsence - .replacementUserId, false)) + var imageUri = Uri.parse( + ApiUtils.getUrlForAvatar( + conversationUser?.baseUrl, + uiState.userAbsence + .replacementUserId, + false + ) + ) if (DisplayUtils.isDarkModeOn(context)) { - imageUri = Uri.parse(ApiUtils.getUrlForAvatarDarkTheme(conversationUser?.baseUrl, uiState - .userAbsence - .replacementUserId, false)) + imageUri = Uri.parse( + ApiUtils.getUrlForAvatarDarkTheme( + conversationUser?.baseUrl, + uiState + .userAbsence + .replacementUserId, + false + ) + ) } binding.outOfOfficeContainer.findViewById(R.id.absenceReplacement).text = context.resources.getString(R.string.user_absence_replacement) binding.outOfOfficeContainer.findViewById(R.id.replacement_user_avatar) - .load(imageUri){ + .load(imageUri) { transformations(CircleCropTransformation()) placeholder(R.drawable.account_circle_96dp) error(R.drawable.account_circle_96dp) @@ -1143,11 +1156,13 @@ class ChatActivity : } binding.outOfOfficeContainer.findViewById(R.id.replacement_user_name).text = uiState.userAbsence.replacementUserDisplayName - } else { binding.outOfOfficeContainer.findViewById(R.id.absenceReplacement).visibility = View.GONE } binding.outOfOfficeContainer.findViewById(R.id.userAbsenceLongMessage).text = uiState.userAbsence.message + binding.outOfOfficeContainer.findViewById(R.id.avatar_chip).setOnClickListener { + joinOneToOneConversation(uiState.userAbsence.replacementUserId!!) + } } } } @@ -3917,6 +3932,24 @@ class ChatActivity : startActivity(shareIntent) } + fun joinOneToOneConversation(userId: String) { + val apiVersion = + ApiUtils.getConversationApiVersion(conversationUser!!, intArrayOf(ApiUtils.API_V4, 1)) + val retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom( + apiVersion, + conversationUser?.baseUrl!!, + "1", + "users", + userId, + null + ) + chatViewModel.createRoom( + credentials!!, + retrofitBucket.url!!, + retrofitBucket.queryMap!! + ) + } + companion object { val TAG = ChatActivity::class.simpleName private const val CONTENT_TYPE_CALL_STARTED: Byte = 1 diff --git a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt index b192c881a..755e8959b 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt @@ -608,7 +608,7 @@ object ApiUtils { return "${getUrlForRoom(version, baseUrl, token)}/archive" } - fun getUrlForOutOfOffice(baseUrl: String, userId: String): String { + fun getUrlForOutOfOffice(baseUrl: String, userId: String): String { return "$baseUrl$OCS_API_VERSION/apps/dav/api/v1/outOfOffice/$userId/now" } } From 3eab18472fc6f30846ad7e1ef096c2e1c049bebb Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Mon, 9 Dec 2024 13:50:40 +0100 Subject: [PATCH 18/23] format code and remove unused colors Signed-off-by: sowjanyakch --- .../com/nextcloud/talk/chat/ChatActivity.kt | 59 ++++++++----------- .../com/nextcloud/talk/utils/DateUtils.kt | 8 +++ app/src/main/res/values-night/colors.xml | 3 - app/src/main/res/values/colors.xml | 3 - app/src/main/res/values/strings.xml | 2 +- app/src/main/res/values/styles.xml | 4 -- 6 files changed, 32 insertions(+), 47 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 9b0d42557..946dd4209 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -209,12 +209,10 @@ import java.io.File import java.io.IOException import java.net.HttpURLConnection import java.text.SimpleDateFormat -import java.util.Calendar import java.util.Date import java.util.Locale import java.util.concurrent.ExecutionException import javax.inject.Inject -import kotlin.String import kotlin.collections.set import kotlin.math.roundToInt @@ -621,18 +619,6 @@ class ChatActivity : urlForChatting ) - if (currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL && - currentConversation?.status == "dnd" - ) { - conversationUser?.let { user -> - chatViewModel.outOfOfficeStatusOfUser( - credentials, - user.baseUrl!!, - currentConversation!!.name - ) - } - } - logConversationInfos("GetRoomSuccessState") if (adapter == null) { @@ -701,16 +687,17 @@ class ChatActivity : loadAvatarForStatusBar() setupSwipeToReply() setActionBarTitle() - checkShowCallButtons() checkLobbyState() - if (currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL) { + if (currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL && + currentConversation?.status == "dnd" + ) { conversationUser?.let { user -> val credentials = ApiUtils.getCredentials(user.username, user.token) chatViewModel.outOfOfficeStatusOfUser( credentials!!, user.baseUrl!!, - currentConversation!!.displayName + currentConversation!!.name ) } } @@ -1101,29 +1088,26 @@ class ChatActivity : val startDate = Date(startDateTimestamp * 1000) val endDate = Date(endDateTimestamp * 1000) - val date1 = Calendar.getInstance().apply { time = startDate } - val date2 = Calendar.getInstance().apply { time = endDate } - - val isSameDay = date1.get(Calendar.YEAR) == date2.get(Calendar.YEAR) && - date1.get(Calendar.DAY_OF_YEAR) == date2.get(Calendar.DAY_OF_YEAR) - - if (isSameDay) { - binding.outOfOfficeContainer.findViewById(R.id.userAbsenceShortMessage).text = String.format( - context.resources.getString(R.string.user_absence_for_one_day), - uiState.userAbsence.userId - ) + if (dateUtils.isSameDate(startDate, endDate)) { + binding.outOfOfficeContainer.findViewById(R.id.userAbsenceShortMessage).text = + String.format( + context.resources.getString(R.string.user_absence_for_one_day), + uiState.userAbsence.userId + ) binding.outOfOfficeContainer.findViewById(R.id.userAbsencePeriod).visibility = View.GONE } else { val dateFormatter = SimpleDateFormat("MMM d, yyyy", Locale.getDefault()) val startDateString = dateFormatter.format(startDate) val endDateString = dateFormatter.format(endDate) - binding.outOfOfficeContainer.findViewById(R.id.userAbsenceShortMessage).text = String.format( - context.resources.getString(R.string.user_absence), - uiState.userAbsence.userId - ) + binding.outOfOfficeContainer.findViewById(R.id.userAbsenceShortMessage).text = + String.format( + context.resources.getString(R.string.user_absence), + uiState.userAbsence.userId + ) - binding.outOfOfficeContainer.findViewById(R.id.userAbsencePeriod).text = "$startDateString - $endDateString" + binding.outOfOfficeContainer.findViewById(R.id.userAbsencePeriod).text = + "$startDateString - $endDateString" } if (uiState.userAbsence.replacementUserDisplayName != null) { @@ -1146,7 +1130,8 @@ class ChatActivity : ) ) } - binding.outOfOfficeContainer.findViewById(R.id.absenceReplacement).text = context.resources.getString(R.string.user_absence_replacement) + binding.outOfOfficeContainer.findViewById(R.id.absenceReplacement).text = + context.resources.getString(R.string.user_absence_replacement) binding.outOfOfficeContainer.findViewById(R.id.replacement_user_avatar) .load(imageUri) { transformations(CircleCropTransformation()) @@ -1157,9 +1142,11 @@ class ChatActivity : binding.outOfOfficeContainer.findViewById(R.id.replacement_user_name).text = uiState.userAbsence.replacementUserDisplayName } else { - binding.outOfOfficeContainer.findViewById(R.id.absenceReplacement).visibility = View.GONE + binding.outOfOfficeContainer.findViewById(R.id.absenceReplacement).visibility = + View.GONE } - binding.outOfOfficeContainer.findViewById(R.id.userAbsenceLongMessage).text = uiState.userAbsence.message + binding.outOfOfficeContainer.findViewById(R.id.userAbsenceLongMessage).text = + uiState.userAbsence.message binding.outOfOfficeContainer.findViewById(R.id.avatar_chip).setOnClickListener { joinOneToOneConversation(uiState.userAbsence.replacementUserId!!) } diff --git a/app/src/main/java/com/nextcloud/talk/utils/DateUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/DateUtils.kt index 1d302d487..852c5a54e 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/DateUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/DateUtils.kt @@ -51,6 +51,14 @@ class DateUtils(val context: Context) { return formatTime.format(Date(timestampSeconds * DateConstants.SECOND_DIVIDER)) } + fun isSameDate(date1: Date, date2: Date): Boolean { + val startDateCalendar = Calendar.getInstance().apply { time = date1 } + val endDateCalendar = Calendar.getInstance().apply { time = date2 } + val isSameDay = startDateCalendar.get(Calendar.YEAR) == endDateCalendar.get(Calendar.YEAR) && + startDateCalendar.get(Calendar.DAY_OF_YEAR) == endDateCalendar.get(Calendar.DAY_OF_YEAR) + return isSameDay + } + fun getTimeDifferenceInSeconds(time2: Long, time1: Long): Long { val difference = (time2 - time1) return abs(difference) diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index 36bacfe12..7b4c18f30 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -61,7 +61,4 @@ #99FFFFFF - #cee7fe - #5e95b4 - diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 5b6cc5b30..a49e2de29 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -93,7 +93,4 @@ #EF3B02 #DBE2E9 - #cee5fd - #08486e - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c69bbfb4b..75ff70baa 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -842,5 +842,5 @@ How to translate with transifex: %1$s is out of office and might not respond %1$s is out of office today - Replacement + Replacement: diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 8a68fa32d..7c9821c63 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -288,8 +288,4 @@ 50% - - From 8ca769832d9146a757cbead68701077c1353599b Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Mon, 9 Dec 2024 17:50:43 +0100 Subject: [PATCH 19/23] use theming from server Signed-off-by: sowjanyakch --- .../java/com/nextcloud/talk/chat/ChatActivity.kt | 14 +++++++++++--- app/src/main/res/layout/activity_chat.xml | 1 - app/src/main/res/layout/out_of_office_view.xml | 6 +++--- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 946dd4209..3685bd724 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -52,7 +52,6 @@ import androidx.activity.result.ActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.view.ContextThemeWrapper import androidx.cardview.widget.CardView -import androidx.core.content.ContextCompat import androidx.core.content.FileProvider import androidx.core.content.PermissionChecker import androidx.core.content.PermissionChecker.PERMISSION_GRANTED @@ -79,6 +78,7 @@ import coil.request.ImageRequest import coil.target.Target import coil.transform.CircleCropTransformation import com.google.android.material.snackbar.Snackbar +import com.nextcloud.android.common.ui.color.ColorUtil import com.nextcloud.android.common.ui.theme.utils.ColorRole import com.nextcloud.talk.BuildConfig import com.nextcloud.talk.R @@ -243,6 +243,9 @@ class ChatActivity : @Inject lateinit var dateUtils: DateUtils + @Inject + lateinit var colorUtil: ColorUtil + @Inject lateinit var viewModelFactory: ViewModelProvider.Factory @@ -1078,8 +1081,13 @@ class ChatActivity : } is ChatViewModel.OutOfOfficeUIState.Success -> { binding.outOfOfficeContainer.visibility = View.VISIBLE - val backgroundColor = ContextCompat.getColor(this, R.color.colorPrimary) - val setAlpha = ColorUtils.setAlphaComponent(backgroundColor, (0.2f * 255).toInt()) + + + val backgroundColor = colorUtil.getNullSafeColorWithFallbackRes(conversationUser!!.capabilities + !!.themingCapability!!.color, R.color.colorPrimary) + + binding.outOfOfficeContainer.findViewById(R.id.verticalLine).setBackgroundColor(backgroundColor) + val setAlpha = ColorUtils.setAlphaComponent(backgroundColor, (0.3f * 255).toInt()) binding.outOfOfficeContainer.setCardBackgroundColor(setAlpha) val startDateTimestamp: Long = uiState.userAbsence.startDate.toLong() diff --git a/app/src/main/res/layout/activity_chat.xml b/app/src/main/res/layout/activity_chat.xml index 87b8c58f1..a69daec52 100644 --- a/app/src/main/res/layout/activity_chat.xml +++ b/app/src/main/res/layout/activity_chat.xml @@ -136,7 +136,6 @@ android:layout_margin="8dp" app:cardCornerRadius="12dp"> - diff --git a/app/src/main/res/layout/out_of_office_view.xml b/app/src/main/res/layout/out_of_office_view.xml index cfdc30ea5..98c7a885f 100644 --- a/app/src/main/res/layout/out_of_office_view.xml +++ b/app/src/main/res/layout/out_of_office_view.xml @@ -18,9 +18,9 @@ android:orientation="horizontal"> + android:id="@+id/verticalLine" + android:layout_width="6dp" + android:layout_height="match_parent" /> Date: Tue, 10 Dec 2024 13:00:50 +0100 Subject: [PATCH 20/23] ktlintFormat Signed-off-by: sowjanyakch --- .../main/java/com/nextcloud/talk/chat/ChatActivity.kt | 11 +++++++---- .../talk/chat/data/network/RetrofitChatNetwork.kt | 5 ++++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 3685bd724..9b8541064 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -1082,11 +1082,14 @@ class ChatActivity : is ChatViewModel.OutOfOfficeUIState.Success -> { binding.outOfOfficeContainer.visibility = View.VISIBLE + val backgroundColor = colorUtil.getNullSafeColorWithFallbackRes( + conversationUser!!.capabilities!!.themingCapability!!.color, + R.color.colorPrimary + ) - val backgroundColor = colorUtil.getNullSafeColorWithFallbackRes(conversationUser!!.capabilities - !!.themingCapability!!.color, R.color.colorPrimary) - - binding.outOfOfficeContainer.findViewById(R.id.verticalLine).setBackgroundColor(backgroundColor) + binding.outOfOfficeContainer.findViewById( + R.id.verticalLine + ).setBackgroundColor(backgroundColor) val setAlpha = ColorUtils.setAlphaComponent(backgroundColor, (0.3f * 255).toInt()) binding.outOfOfficeContainer.setCardBackgroundColor(setAlpha) diff --git a/app/src/main/java/com/nextcloud/talk/chat/data/network/RetrofitChatNetwork.kt b/app/src/main/java/com/nextcloud/talk/chat/data/network/RetrofitChatNetwork.kt index 19b067608..eafab6484 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/data/network/RetrofitChatNetwork.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/data/network/RetrofitChatNetwork.kt @@ -21,7 +21,10 @@ import com.nextcloud.talk.utils.ApiUtils import io.reactivex.Observable import retrofit2.Response -class RetrofitChatNetwork(private val ncApi: NcApi, private val ncApiCoroutines: NcApiCoroutines) : ChatNetworkDataSource { +class RetrofitChatNetwork( + private val ncApi: NcApi, + private val ncApiCoroutines: NcApiCoroutines +) : ChatNetworkDataSource { override fun getRoom(user: User, roomToken: String): Observable { val credentials: String = ApiUtils.getCredentials(user.username, user.token)!! val apiVersion = ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V3, 1)) From f7078990d911afdc0a5834042b6b707ab01dcd54 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Fri, 13 Dec 2024 13:51:36 +0100 Subject: [PATCH 21/23] use constants Signed-off-by: sowjanyakch --- app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 9b8541064..a7a703229 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -1075,7 +1075,7 @@ class ChatActivity : chatViewModel.outOfOfficeViewState.observe(this) { uiState -> when (uiState) { is ChatViewModel.OutOfOfficeUIState.Error -> { - Log.e(TAG, "Error in outOfOfficeState", uiState.exception) + Log.e(TAG, "Error fetching/ no user absence data", uiState.exception) } ChatViewModel.OutOfOfficeUIState.None -> { } @@ -3936,8 +3936,8 @@ class ChatActivity : val retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom( apiVersion, conversationUser?.baseUrl!!, - "1", - "users", + ROOM_TYPE_ONE_TO_ONE, + ACTOR_TYPE, userId, null ) @@ -4000,6 +4000,8 @@ class ChatActivity : private const val FIVE_MINUTES_IN_SECONDS: Long = 300 private const val TEMPORARY_MESSAGE_ID_INT: Int = -3 private const val TEMPORARY_MESSAGE_ID_STRING: String = "-3" + private const val ROOM_TYPE_ONE_TO_ONE = "1" + private const val ACTOR_TYPE = "users" const val CONVERSATION_INTERNAL_ID = "CONVERSATION_INTERNAL_ID" const val NO_OFFLINE_MESSAGES_FOUND = "NO_OFFLINE_MESSAGES_FOUND" } From 74bf9f2e9119072404379b1a558195aa61c6a622 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Fri, 13 Dec 2024 16:04:45 +0100 Subject: [PATCH 22/23] hide replacement view when there is no replacement set Signed-off-by: sowjanyakch --- .../com/nextcloud/talk/chat/ChatActivity.kt | 5 +++-- .../talk/chat/viewmodels/ChatViewModel.kt | 1 + .../main/res/layout/out_of_office_view.xml | 19 ++++++++++++++----- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index a7a703229..3c244ac7d 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -45,6 +45,7 @@ import android.view.animation.AccelerateDecelerateInterpolator import android.widget.AbsListView import android.widget.FrameLayout import android.widget.ImageView +import android.widget.LinearLayout import android.widget.PopupMenu import android.widget.TextView import androidx.activity.OnBackPressedCallback @@ -1153,8 +1154,8 @@ class ChatActivity : binding.outOfOfficeContainer.findViewById(R.id.replacement_user_name).text = uiState.userAbsence.replacementUserDisplayName } else { - binding.outOfOfficeContainer.findViewById(R.id.absenceReplacement).visibility = - View.GONE + binding.outOfOfficeContainer.findViewById(R.id.userAbsenceReplacement) + .visibility = View.GONE } binding.outOfOfficeContainer.findViewById(R.id.userAbsenceLongMessage).text = uiState.userAbsence.message diff --git a/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt b/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt index 328170b34..ed349b5fc 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt @@ -771,6 +771,7 @@ class ChatViewModel @Inject constructor( } } + @Suppress("Detekt.TooGenericExceptionCaught") fun outOfOfficeStatusOfUser(credentials: String, baseUrl: String, userId: String) { viewModelScope.launch { try { diff --git a/app/src/main/res/layout/out_of_office_view.xml b/app/src/main/res/layout/out_of_office_view.xml index 98c7a885f..ed208ee9f 100644 --- a/app/src/main/res/layout/out_of_office_view.xml +++ b/app/src/main/res/layout/out_of_office_view.xml @@ -5,12 +5,19 @@ ~ SPDX-FileCopyrightText: 2024 Sowjanya Kota ~ SPDX-License-Identifier: GPL-3.0-or-later --> - + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + - \ No newline at end of file + + \ No newline at end of file From cd50115e06aca5a417042d438bd57507bca3bdda Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Fri, 20 Dec 2024 14:47:37 +0100 Subject: [PATCH 23/23] fix detekt warnings Signed-off-by: Marcel Hibbe --- app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 3c244ac7d..85760a07f 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -1091,14 +1091,14 @@ class ChatActivity : binding.outOfOfficeContainer.findViewById( R.id.verticalLine ).setBackgroundColor(backgroundColor) - val setAlpha = ColorUtils.setAlphaComponent(backgroundColor, (0.3f * 255).toInt()) + val setAlpha = ColorUtils.setAlphaComponent(backgroundColor, OUT_OF_OFFICE_ALPHA) binding.outOfOfficeContainer.setCardBackgroundColor(setAlpha) val startDateTimestamp: Long = uiState.userAbsence.startDate.toLong() val endDateTimestamp: Long = uiState.userAbsence.endDate.toLong() - val startDate = Date(startDateTimestamp * 1000) - val endDate = Date(endDateTimestamp * 1000) + val startDate = Date(startDateTimestamp * ONE_SECOND_IN_MILLIS) + val endDate = Date(endDateTimestamp * ONE_SECOND_IN_MILLIS) if (dateUtils.isSameDate(startDate, endDate)) { binding.outOfOfficeContainer.findViewById(R.id.userAbsenceShortMessage).text = @@ -4005,5 +4005,6 @@ class ChatActivity : private const val ACTOR_TYPE = "users" const val CONVERSATION_INTERNAL_ID = "CONVERSATION_INTERNAL_ID" const val NO_OFFLINE_MESSAGES_FOUND = "NO_OFFLINE_MESSAGES_FOUND" + const val OUT_OF_OFFICE_ALPHA = 76 } }