Merge pull request #4935 from nextcloud/bugfix/4883/fixJumpingNoteToSelfEntry

Bugfix/4883/fix jumping note to self entry
This commit is contained in:
Sowjanya Kota 2025-05-05 18:18:59 +02:00 committed by GitHub
commit d8db5079ea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 77 additions and 112 deletions

View File

@ -251,4 +251,7 @@ interface NcApiCoroutines {
@Url url: String, @Url url: String,
@Query("limit") limit: Int @Query("limit") limit: Int
): ChatOverall ): ChatOverall
@GET
suspend fun getNoteToSelfRoom(@Header("Authorization") authorization: String, @Url url: String): RoomOverall
} }

View File

@ -3295,37 +3295,56 @@ class ChatActivity :
} }
} }
fun shareToNotes(message: ChatMessage, roomToken: String) { fun shareToNotes(message: ChatMessage) {
var shareUri: Uri? = null val apiVersion = ApiUtils.getConversationApiVersion(
val data: HashMap<String?, String?>? conversationUser!!,
var metaData: String = "" intArrayOf(ApiUtils.API_V4, ApiUtils.API_V3, 1)
var objectId: String = "" )
if (message.hasFileAttachment()) {
val filename = message.selectedIndividualHashMap!!["name"] this.lifecycleScope.launch {
path = applicationContext.cacheDir.absolutePath + "/" + filename val noteToSelfConversation = chatViewModel.checkForNoteToSelf(
shareUri = FileProvider.getUriForFile( ApiUtils.getCredentials(conversationUser!!.username, conversationUser!!.token)!!,
this, ApiUtils.getUrlForNoteToSelf(
BuildConfig.APPLICATION_ID, apiVersion,
File(path) conversationUser!!.baseUrl
)
) )
this.grantUriPermission( if (noteToSelfConversation != null) {
applicationContext.packageName, var shareUri: Uri? = null
shareUri, val data: HashMap<String?, String?>?
Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION var metaData = ""
) var objectId = ""
} else if (message.hasGeoLocation()) { if (message.hasFileAttachment()) {
data = message.messageParameters?.get("object") val filename = message.selectedIndividualHashMap!!["name"]
objectId = data?.get("id")!! path = applicationContext.cacheDir.absolutePath + "/" + filename
val name = data["name"]!! shareUri = FileProvider.getUriForFile(
val lat = data["latitude"]!! context,
val lon = data["longitude"]!! BuildConfig.APPLICATION_ID,
metaData = File(path)
"{\"type\":\"geo-location\",\"id\":\"geo:$lat,$lon\",\"latitude\":\"$lat\"," + )
"\"longitude\":\"$lon\",\"name\":\"$name\"}"
grantUriPermission(
applicationContext.packageName,
shareUri,
Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION
)
} else if (message.hasGeoLocation()) {
data = message.messageParameters?.get("object")
objectId = data?.get("id")!!
val name = data["name"]!!
val lat = data["latitude"]!!
val lon = data["longitude"]!!
metaData =
"{\"type\":\"geo-location\",\"id\":\"geo:$lat,$lon\",\"latitude\":\"$lat\"," +
"\"longitude\":\"$lon\",\"name\":\"$name\"}"
}
shareToNotes(shareUri, noteToSelfConversation.token, message, objectId, metaData)
} else {
Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
}
} }
shareToNotes(shareUri, roomToken, message, objectId, metaData)
} }
private fun shareToNotes( private fun shareToNotes(

View File

@ -12,7 +12,6 @@ import com.nextcloud.talk.models.json.capabilities.SpreedCapability
import com.nextcloud.talk.models.json.chat.ChatMessageJson import com.nextcloud.talk.models.json.chat.ChatMessageJson
import com.nextcloud.talk.models.json.chat.ChatOverallSingleMessage import com.nextcloud.talk.models.json.chat.ChatOverallSingleMessage
import com.nextcloud.talk.models.json.conversations.RoomOverall 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.generic.GenericOverall
import com.nextcloud.talk.models.json.opengraph.Reference import com.nextcloud.talk.models.json.opengraph.Reference
import com.nextcloud.talk.models.json.reminder.Reminder import com.nextcloud.talk.models.json.reminder.Reminder
@ -42,7 +41,8 @@ interface ChatNetworkDataSource {
displayName: String displayName: String
): Observable<ChatOverallSingleMessage> ): Observable<ChatOverallSingleMessage>
fun checkForNoteToSelf(credentials: String, url: String, includeStatus: Boolean): Observable<RoomsOverall> suspend fun checkForNoteToSelf(credentials: String, url: String): RoomOverall
fun shareLocationToNotes( fun shareLocationToNotes(
credentials: String, credentials: String,
url: String, url: String,

View File

@ -14,7 +14,6 @@ import com.nextcloud.talk.models.json.capabilities.SpreedCapability
import com.nextcloud.talk.models.json.chat.ChatMessageJson import com.nextcloud.talk.models.json.chat.ChatMessageJson
import com.nextcloud.talk.models.json.chat.ChatOverallSingleMessage import com.nextcloud.talk.models.json.chat.ChatOverallSingleMessage
import com.nextcloud.talk.models.json.conversations.RoomOverall 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.generic.GenericOverall
import com.nextcloud.talk.models.json.opengraph.Reference import com.nextcloud.talk.models.json.opengraph.Reference
import com.nextcloud.talk.models.json.reminder.Reminder import com.nextcloud.talk.models.json.reminder.Reminder
@ -124,11 +123,8 @@ class RetrofitChatNetwork(
it it
} }
override fun checkForNoteToSelf( override suspend fun checkForNoteToSelf(credentials: String, url: String): RoomOverall =
credentials: String, ncApiCoroutines.getNoteToSelfRoom(credentials, url)
url: String,
includeStatus: Boolean
): Observable<RoomsOverall> = ncApi.getRooms(credentials, url, includeStatus).map { it }
override fun shareLocationToNotes( override fun shareLocationToNotes(
credentials: String, credentials: String,

View File

@ -34,14 +34,12 @@ import com.nextcloud.talk.models.json.capabilities.SpreedCapability
import com.nextcloud.talk.models.json.chat.ChatMessageJson import com.nextcloud.talk.models.json.chat.ChatMessageJson
import com.nextcloud.talk.models.json.chat.ChatOverallSingleMessage import com.nextcloud.talk.models.json.chat.ChatOverallSingleMessage
import com.nextcloud.talk.models.json.conversations.RoomOverall 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.generic.GenericOverall
import com.nextcloud.talk.models.json.opengraph.Reference import com.nextcloud.talk.models.json.opengraph.Reference
import com.nextcloud.talk.models.json.reminder.Reminder import com.nextcloud.talk.models.json.reminder.Reminder
import com.nextcloud.talk.models.json.userAbsence.UserAbsenceData import com.nextcloud.talk.models.json.userAbsence.UserAbsenceData
import com.nextcloud.talk.repositories.reactions.ReactionsRepository import com.nextcloud.talk.repositories.reactions.ReactionsRepository
import com.nextcloud.talk.ui.PlaybackSpeed import com.nextcloud.talk.ui.PlaybackSpeed
import com.nextcloud.talk.utils.ConversationUtils
import com.nextcloud.talk.utils.bundle.BundleKeys import com.nextcloud.talk.utils.bundle.BundleKeys
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
import com.nextcloud.talk.utils.preferences.AppPreferences import com.nextcloud.talk.utils.preferences.AppPreferences
@ -199,13 +197,6 @@ class ChatViewModel @Inject constructor(
val getReminderExistState: LiveData<ViewState> val getReminderExistState: LiveData<ViewState>
get() = _getReminderExistState get() = _getReminderExistState
object NoteToSelfNotAvailableState : ViewState
open class NoteToSelfAvailableState(val roomToken: String) : ViewState
private val _getNoteToSelfAvailability: MutableLiveData<ViewState> = MutableLiveData(NoteToSelfNotAvailableState)
val getNoteToSelfAvailability: LiveData<ViewState>
get() = _getNoteToSelfAvailability
object GetRoomStartState : ViewState object GetRoomStartState : ViewState
object GetRoomErrorState : ViewState object GetRoomErrorState : ViewState
object GetRoomSuccessState : ViewState object GetRoomSuccessState : ViewState
@ -538,10 +529,17 @@ class ChatViewModel @Inject constructor(
}) })
} }
fun checkForNoteToSelf(credentials: String, baseUrl: String, includeStatus: Boolean) { suspend fun checkForNoteToSelf(credentials: String, baseUrl: String): ConversationModel? {
chatNetworkDataSource.checkForNoteToSelf(credentials, baseUrl, includeStatus).subscribeOn(Schedulers.io()) val response = chatNetworkDataSource.checkForNoteToSelf(credentials, baseUrl)
?.observeOn(AndroidSchedulers.mainThread()) if (response.ocs?.meta?.statusCode == HTTP_CODE_OK) {
?.subscribe(CheckForNoteToSelfObserver()) val noteToSelfConversation = ConversationModel.mapToConversationModel(
response.ocs?.data!!,
userProvider.currentUser.blockingGet()
)
return noteToSelfConversation
} else {
return null
}
} }
fun shareLocationToNotes(credentials: String, url: String, objectType: String, objectId: String, metadata: String) { fun shareLocationToNotes(credentials: String, url: String, objectType: String, objectId: String, metadata: String) {
@ -784,36 +782,6 @@ class ChatViewModel @Inject constructor(
} }
} }
inner class CheckForNoteToSelfObserver : Observer<RoomsOverall> {
override fun onSubscribe(d: Disposable) {
disposableSet.add(d)
}
override fun onNext(roomsOverall: RoomsOverall) {
val rooms = roomsOverall.ocs?.data
rooms?.let {
try {
val noteToSelf = rooms.first {
val model = ConversationModel.mapToConversationModel(it, userProvider.currentUser.blockingGet())
ConversationUtils.isNoteToSelfConversation(model)
}
_getNoteToSelfAvailability.value = NoteToSelfAvailableState(noteToSelf.token)
} catch (e: NoSuchElementException) {
_getNoteToSelfAvailability.value = NoteToSelfNotAvailableState
Log.e(TAG, "Note to self not found $e")
}
}
}
override fun onError(e: Throwable) {
Log.d(TAG, "Error when getting rooms for Note to Self Observer $e")
}
override fun onComplete() {
// unused atm
}
}
@Suppress("Detekt.TooGenericExceptionCaught") @Suppress("Detekt.TooGenericExceptionCaught")
fun outOfOfficeStatusOfUser(credentials: String, baseUrl: String, userId: String) { fun outOfOfficeStatusOfUser(credentials: String, baseUrl: String, userId: String) {
viewModelScope.launch { viewModelScope.launch {
@ -875,6 +843,7 @@ class ChatViewModel @Inject constructor(
companion object { companion object {
private val TAG = ChatViewModel::class.simpleName private val TAG = ChatViewModel::class.simpleName
const val JOIN_ROOM_RETRY_COUNT: Long = 3 const val JOIN_ROOM_RETRY_COUNT: Long = 3
const val HTTP_CODE_OK: Int = 200
} }
sealed class OutOfOfficeUIState { sealed class OutOfOfficeUIState {

View File

@ -25,7 +25,6 @@ import com.nextcloud.talk.R
import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.chat.ChatActivity import com.nextcloud.talk.chat.ChatActivity
import com.nextcloud.talk.chat.data.model.ChatMessage import com.nextcloud.talk.chat.data.model.ChatMessage
import com.nextcloud.talk.chat.viewmodels.ChatViewModel
import com.nextcloud.talk.data.network.NetworkMonitor import com.nextcloud.talk.data.network.NetworkMonitor
import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.DialogMessageActionsBinding import com.nextcloud.talk.databinding.DialogMessageActionsBinding
@ -36,7 +35,6 @@ import com.nextcloud.talk.models.json.capabilities.SpreedCapability
import com.nextcloud.talk.models.json.conversations.ConversationEnums import com.nextcloud.talk.models.json.conversations.ConversationEnums
import com.nextcloud.talk.repositories.reactions.ReactionsRepository import com.nextcloud.talk.repositories.reactions.ReactionsRepository
import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.ui.theme.ViewThemeUtils
import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.CapabilitiesUtil import com.nextcloud.talk.utils.CapabilitiesUtil
import com.nextcloud.talk.utils.CapabilitiesUtil.hasSpreedFeatureCapability import com.nextcloud.talk.utils.CapabilitiesUtil.hasSpreedFeatureCapability
import com.nextcloud.talk.utils.ConversationUtils import com.nextcloud.talk.utils.ConversationUtils
@ -123,35 +121,6 @@ class MessageActionsDialog(
viewThemeUtils.material.colorBottomSheetDragHandle(dialogMessageActionsBinding.bottomSheetDragHandle) viewThemeUtils.material.colorBottomSheetDragHandle(dialogMessageActionsBinding.bottomSheetDragHandle)
initEmojiBar(hasChatPermission) initEmojiBar(hasChatPermission)
initMenuItemCopy(!message.isDeleted) initMenuItemCopy(!message.isDeleted)
val apiVersion = ApiUtils.getConversationApiVersion(user!!, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V3, 1))
chatActivity.chatViewModel.checkForNoteToSelf(
ApiUtils.getCredentials(user.username, user.token)!!,
ApiUtils.getUrlForRooms(
apiVersion,
user.baseUrl
),
false
)
chatActivity.chatViewModel.getNoteToSelfAvailability.observe(this) { state ->
when (state) {
is ChatViewModel.NoteToSelfAvailableState -> {
this.lifecycleScope.launch {
initMenuAddToNote(
!message.isDeleted &&
!ConversationUtils.isNoteToSelfConversation(currentConversation) &&
networkMonitor.isOnline.value,
state.roomToken
)
}
}
else -> {
initMenuAddToNote(
false
)
}
}
}
initMenuItems(networkMonitor.isOnline.value) initMenuItems(networkMonitor.isOnline.value)
} }
@ -195,6 +164,11 @@ class MessageActionsDialog(
isOnline isOnline
) )
initMenuItemSave(message.getCalculateMessageType() == ChatMessage.MessageType.SINGLE_NC_ATTACHMENT_MESSAGE) initMenuItemSave(message.getCalculateMessageType() == ChatMessage.MessageType.SINGLE_NC_ATTACHMENT_MESSAGE)
initMenuAddToNote(
!message.isDeleted &&
!ConversationUtils.isNoteToSelfConversation(currentConversation) &&
networkMonitor.isOnline.value
)
} }
} }
@ -472,10 +446,10 @@ class MessageActionsDialog(
dialogMessageActionsBinding.menuSaveMessage.visibility = getVisibility(visible) dialogMessageActionsBinding.menuSaveMessage.visibility = getVisibility(visible)
} }
private fun initMenuAddToNote(visible: Boolean, roomToken: String = "") { private fun initMenuAddToNote(visible: Boolean) {
if (visible) { if (visible) {
dialogMessageActionsBinding.menuShareToNote.setOnClickListener { dialogMessageActionsBinding.menuShareToNote.setOnClickListener {
chatActivity.shareToNotes(message, roomToken) chatActivity.shareToNotes(message)
dismiss() dismiss()
} }
} }

View File

@ -181,6 +181,10 @@ object ApiUtils {
return getUrlForApi(version, baseUrl) + "/room" return getUrlForApi(version, baseUrl) + "/room"
} }
fun getUrlForNoteToSelf(version: Int, baseUrl: String?): String {
return getUrlForApi(version, baseUrl) + "/room/note-to-self"
}
@JvmStatic @JvmStatic
fun getUrlForRoom(version: Int, baseUrl: String?, token: String?): String { fun getUrlForRoom(version: Int, baseUrl: String?, token: String?): String {
return getUrlForRooms(version, baseUrl) + "/" + token return getUrlForRooms(version, baseUrl) + "/" + token