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 3ace986ef..3cd1013b5 100644
--- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt
+++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt
@@ -2682,8 +2682,9 @@ class ChatActivity :
}
}
- private fun uploadFile(fileUri: String, isVoiceMessage: Boolean, caption: String = "") {
+ private fun uploadFile(fileUri: String, isVoiceMessage: Boolean, caption: String = "", token: String = "") {
var metaData = ""
+ var room = ""
if (!participantPermissions.hasChatPermission()) {
Log.w(TAG, "uploading file(s) is forbidden because of missing attendee permissions")
@@ -2698,11 +2699,13 @@ class ChatActivity :
metaData = "{\"caption\":\"$caption\"}"
}
+ if (token == "") room = roomToken else room = token
+
try {
require(fileUri.isNotEmpty())
UploadAndShareFilesWorker.upload(
fileUri,
- roomToken,
+ room,
currentConversation?.displayName!!,
metaData
)
@@ -4171,6 +4174,82 @@ class ChatActivity :
}
}
+ fun shareToNotes(message: ChatMessage, roomToken: String) {
+ val apiVersion = ApiUtils.getChatApiVersion(conversationUser, intArrayOf(1))
+ val type = message.getCalculateMessageType()
+ var shareUri: Uri? = null
+ var data: HashMap?
+ var metaData: String = ""
+ var objectId: String = ""
+ if (message.hasFileAttachment()) {
+ val filename = message.selectedIndividualHashMap!!["name"]
+ path = applicationContext.cacheDir.absolutePath + "/" + filename
+ shareUri = FileProvider.getUriForFile(
+ this,
+ BuildConfig.APPLICATION_ID,
+ File(path)
+ )
+
+ this.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.get("name")!!
+ val lat = data.get("latitude")!!
+ val lon = data.get("longitude")!!
+ metaData =
+ "{\"type\":\"geo-location\",\"id\":\"geo:$lat,$lon\",\"latitude\":\"$lat\"," +
+ "\"longitude\":\"$lon\",\"name\":\"$name\"}"
+ }
+
+ when (type) {
+ ChatMessage.MessageType.VOICE_MESSAGE -> {
+ uploadFile(shareUri.toString(), true, token = roomToken)
+ Snackbar.make(binding.root, R.string.nc_message_sent, Snackbar.LENGTH_SHORT).show()
+ }
+ ChatMessage.MessageType.SINGLE_NC_ATTACHMENT_MESSAGE -> {
+ val caption = if (message.message != "{file}") message.message else ""
+ if (null != shareUri) {
+ try {
+ context.contentResolver.openInputStream(shareUri)?.close()
+ uploadFile(shareUri.toString(), false, caption!!, roomToken)
+ Snackbar.make(binding.root, R.string.nc_message_sent, Snackbar.LENGTH_SHORT).show()
+ } catch (e: java.lang.Exception) {
+ Log.w(TAG, "File corresponding to the uri does not exist " + shareUri.toString())
+ downloadFileToCache(message, false) {
+ uploadFile(shareUri.toString(), false, caption!!, roomToken)
+ Snackbar.make(binding.root, R.string.nc_message_sent, Snackbar.LENGTH_SHORT).show()
+ }
+ }
+ }
+ }
+ ChatMessage.MessageType.SINGLE_NC_GEOLOCATION_MESSAGE -> {
+ chatViewModel.shareLocationToNotes(
+ credentials!!,
+ ApiUtils.getUrlToSendLocation(apiVersion, conversationUser!!.baseUrl, roomToken),
+ "geo-location",
+ objectId,
+ metaData
+ )
+ Snackbar.make(binding.root, R.string.nc_message_sent, Snackbar.LENGTH_SHORT).show()
+ }
+ ChatMessage.MessageType.REGULAR_TEXT_MESSAGE -> {
+ chatViewModel.shareToNotes(
+ credentials!!,
+ ApiUtils.getUrlForChat(apiVersion, conversationUser!!.baseUrl, roomToken),
+ message.message!!,
+ conversationUser!!.displayName!!
+ )
+ Snackbar.make(binding.root, R.string.nc_message_sent, Snackbar.LENGTH_SHORT).show()
+ }
+ else -> {}
+ }
+ }
+
fun openInFilesApp(message: ChatMessage) {
val keyID = message.selectedIndividualHashMap!![PreviewMessageViewHolder.KEY_ID]
val link = message.selectedIndividualHashMap!!["link"]
diff --git a/app/src/main/java/com/nextcloud/talk/chat/data/ChatRepository.kt b/app/src/main/java/com/nextcloud/talk/chat/data/ChatRepository.kt
index 7c85caa15..1cd1860d7 100644
--- a/app/src/main/java/com/nextcloud/talk/chat/data/ChatRepository.kt
+++ b/app/src/main/java/com/nextcloud/talk/chat/data/ChatRepository.kt
@@ -22,6 +22,7 @@ package com.nextcloud.talk.chat.data
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.models.domain.ConversationModel
+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 io.reactivex.Observable
@@ -32,4 +33,18 @@ interface ChatRepository {
fun setReminder(user: User, roomToken: String, messageId: String, timeStamp: Int): Observable
fun getReminder(user: User, roomToken: String, messageId: String): Observable
fun deleteReminder(user: User, roomToken: String, messageId: String): Observable
+ fun shareToNotes(
+ credentials: String,
+ url: String,
+ message: String,
+ displayName: String
+ ): Observable // last two fields are false
+ fun checkForNoteToSelf(credentials: String, url: String, includeStatus: Boolean): Observable
+ fun shareLocationToNotes(
+ credentials: String,
+ url: String,
+ objectType: String,
+ objectId: String,
+ metadata: String
+ ): Observable
}
diff --git a/app/src/main/java/com/nextcloud/talk/chat/data/ChatRepositoryImpl.kt b/app/src/main/java/com/nextcloud/talk/chat/data/ChatRepositoryImpl.kt
index 488aaece3..5a2d22485 100644
--- a/app/src/main/java/com/nextcloud/talk/chat/data/ChatRepositoryImpl.kt
+++ b/app/src/main/java/com/nextcloud/talk/chat/data/ChatRepositoryImpl.kt
@@ -23,6 +23,7 @@ package com.nextcloud.talk.chat.data
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.models.domain.ConversationModel
+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.utils.ApiUtils
@@ -83,4 +84,40 @@ class ChatRepositoryImpl(private val ncApi: NcApi) : ChatRepository {
it
}
}
+
+ override fun shareToNotes(
+ credentials: String,
+ url: String,
+ message: String,
+ displayName: String
+ ): Observable {
+ return ncApi.sendChatMessage(
+ credentials,
+ url,
+ message,
+ displayName,
+ null,
+ false
+ ).map {
+ it
+ }
+ }
+
+ override fun checkForNoteToSelf(
+ credentials: String,
+ url: String,
+ includeStatus: Boolean
+ ): Observable {
+ return ncApi.getRooms(credentials, url, includeStatus).map { it }
+ }
+
+ override fun shareLocationToNotes(
+ credentials: String,
+ url: String,
+ objectType: String,
+ objectId: String,
+ metadata: String
+ ): Observable {
+ return ncApi.sendLocation(credentials, url, objectType, objectId, metadata).map { it }
+ }
}
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 a6d9db80f..d285f112a 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
@@ -27,8 +27,10 @@ import androidx.lifecycle.ViewModel
import com.nextcloud.talk.chat.data.ChatRepository
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.models.domain.ConversationModel
+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.utils.ConversationUtils
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
@@ -49,6 +51,13 @@ class ChatViewModel @Inject constructor(private val repository: ChatRepository)
val getReminderExistState: LiveData
get() = _getReminderExistState
+ object NoteToSelfNotAvaliableState : ViewState
+ open class NoteToSelfAvaliableState(val roomToken: String) : ViewState
+
+ private val _getNoteToSelfAvaliability: MutableLiveData = MutableLiveData(NoteToSelfNotAvaliableState)
+ val getNoteToSelfAvaliability: LiveData
+ get() = _getNoteToSelfAvaliability
+
open class GetRoomSuccessState(val conversationModel: ConversationModel) : ViewState
private val _getRoomViewState: MutableLiveData = MutableLiveData(GetRoomStartState)
@@ -117,6 +126,58 @@ class ChatViewModel @Inject constructor(private val repository: ChatRepository)
})
}
+ fun shareToNotes(credentials: String, url: String, message: String, displayName: String) {
+ repository.shareToNotes(credentials, url, message, displayName)
+ .subscribeOn(Schedulers.io())
+ ?.observeOn(AndroidSchedulers.mainThread())
+ ?.subscribe(object : Observer {
+ override fun onSubscribe(d: Disposable) {
+ // unused atm
+ }
+
+ override fun onNext(genericOverall: GenericOverall) {
+ // unused atm
+ }
+
+ override fun onError(e: Throwable) {
+ Log.d(TAG, "Error when sharing to notes $e")
+ }
+
+ override fun onComplete() {
+ // unused atm
+ }
+ })
+ }
+
+ fun checkForNoteToSelf(credentials: String, baseUrl: String, includeStatus: Boolean) {
+ repository.checkForNoteToSelf(credentials, baseUrl, includeStatus).subscribeOn(Schedulers.io())
+ ?.observeOn(AndroidSchedulers.mainThread())
+ ?.subscribe(CheckForNoteToSelfObserver())
+ }
+
+ fun shareLocationToNotes(credentials: String, url: String, objectType: String, objectId: String, metadata: String) {
+ repository.shareLocationToNotes(credentials, url, objectType, objectId, metadata)
+ .subscribeOn(Schedulers.io())
+ ?.observeOn(AndroidSchedulers.mainThread())
+ ?.subscribe(object : Observer {
+ override fun onSubscribe(d: Disposable) {
+ // unused atm
+ }
+
+ override fun onNext(genericOverall: GenericOverall) {
+ // unused atm
+ }
+
+ override fun onError(e: Throwable) {
+ Log.e(TAG, "Error when sharing location to notes $e")
+ }
+
+ override fun onComplete() {
+ // unused atm
+ }
+ })
+ }
+
inner class GetRoomObserver : Observer {
override fun onSubscribe(d: Disposable) {
// unused atm
@@ -192,6 +253,36 @@ class ChatViewModel @Inject constructor(private val repository: ChatRepository)
}
}
+ inner class CheckForNoteToSelfObserver : Observer {
+ override fun onSubscribe(d: Disposable) {
+ // unused atm
+ }
+
+ override fun onNext(roomsOverall: RoomsOverall) {
+ val rooms = roomsOverall.ocs?.data
+ rooms?.let {
+ try {
+ val noteToSelf = rooms.first {
+ val model = ConversationModel.mapToConversationModel(it)
+ ConversationUtils.isNoteToSelfConversation(model)
+ }
+ _getNoteToSelfAvaliability.value = NoteToSelfAvaliableState(noteToSelf.token!!)
+ } catch (e: NoSuchElementException) {
+ _getNoteToSelfAvaliability.value = NoteToSelfNotAvaliableState
+ 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
+ }
+ }
+
companion object {
private val TAG = ChatViewModel::class.simpleName
const val JOIN_ROOM_RETRY_COUNT: Long = 3
diff --git a/app/src/main/java/com/nextcloud/talk/jobs/UploadAndShareFilesWorker.kt b/app/src/main/java/com/nextcloud/talk/jobs/UploadAndShareFilesWorker.kt
index ee24bd099..404352225 100644
--- a/app/src/main/java/com/nextcloud/talk/jobs/UploadAndShareFilesWorker.kt
+++ b/app/src/main/java/com/nextcloud/talk/jobs/UploadAndShareFilesWorker.kt
@@ -152,7 +152,7 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
remotePath
)
} else {
- Log.d(TAG, "starting normal upload (not chunked)")
+ Log.d(TAG, "starting normal upload (not chunked) of $fileName")
uploadSuccess = FileUploader(
context,
diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/MessageActionsDialog.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/MessageActionsDialog.kt
index 7414a36ae..16023ca15 100644
--- a/app/src/main/java/com/nextcloud/talk/ui/dialog/MessageActionsDialog.kt
+++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/MessageActionsDialog.kt
@@ -38,6 +38,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialog
import com.nextcloud.talk.R
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.chat.ChatActivity
+import com.nextcloud.talk.chat.viewmodels.ChatViewModel
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.DialogMessageActionsBinding
import com.nextcloud.talk.models.domain.ConversationModel
@@ -48,6 +49,8 @@ import com.nextcloud.talk.models.domain.ReactionDeletedModel
import com.nextcloud.talk.models.json.chat.ChatMessage
import com.nextcloud.talk.repositories.reactions.ReactionsRepository
import com.nextcloud.talk.ui.theme.ViewThemeUtils
+import com.nextcloud.talk.utils.ApiUtils
+import com.nextcloud.talk.utils.ConversationUtils
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
import com.vanniktech.emoji.EmojiPopup
import com.vanniktech.emoji.EmojiTextView
@@ -96,6 +99,31 @@ class MessageActionsDialog(
viewThemeUtils.platform.themeDialog(dialogMessageActionsBinding.root)
initEmojiBar(hasChatPermission)
initMenuItemCopy(!message.isDeleted)
+ val apiVersion = ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.APIv4, ApiUtils.APIv3, 1))
+ chatActivity.chatViewModel.checkForNoteToSelf(
+ ApiUtils.getCredentials(user!!.username, user.token),
+ ApiUtils.getUrlForRooms(
+ apiVersion,
+ user.baseUrl
+ ),
+ false
+ )
+ chatActivity.chatViewModel.getNoteToSelfAvaliability.observe(this) { state ->
+ when (state) {
+ is ChatViewModel.NoteToSelfAvaliableState -> {
+ initMenuAddToNote(
+ !message.isDeleted && !ConversationUtils.isNoteToSelfConversation(currentConversation),
+ state.roomToken
+ )
+ }
+ else -> {
+ initMenuAddToNote(
+ false
+ )
+ }
+ }
+ }
+
initMenuItemTranslate(
!message.isDeleted &&
ChatMessage.MessageType.REGULAR_TEXT_MESSAGE == message.getCalculateMessageType() &&
@@ -374,6 +402,16 @@ class MessageActionsDialog(
dialogMessageActionsBinding.menuSaveMessage.visibility = getVisibility(visible)
}
+ private fun initMenuAddToNote(visible: Boolean, roomToken: String = "") {
+ if (visible) {
+ dialogMessageActionsBinding.menuShareToNote.setOnClickListener {
+ chatActivity.shareToNotes(message, roomToken)
+ dismiss()
+ }
+ }
+ dialogMessageActionsBinding.menuShareToNote.visibility = getVisibility(visible)
+ }
+
private fun getVisibility(visible: Boolean): Int {
return if (visible) {
View.VISIBLE
diff --git a/app/src/main/res/drawable/ic_edit_note_24.xml b/app/src/main/res/drawable/ic_edit_note_24.xml
new file mode 100644
index 000000000..aa2553c27
--- /dev/null
+++ b/app/src/main/res/drawable/ic_edit_note_24.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/dialog_message_actions.xml b/app/src/main/res/layout/dialog_message_actions.xml
index 7b201b247..34b286d4d 100644
--- a/app/src/main/res/layout/dialog_message_actions.xml
+++ b/app/src/main/res/layout/dialog_message_actions.xml
@@ -358,6 +358,39 @@
+
+
+
+
+
+
+
+
Caption
Retrieval failed
Languages could not be retrieved
+ Add to Notes