Signed-off-by: Giacomo Pacini <giacomopacini98@gmail.com>
This commit is contained in:
Giacomo Pacini 2024-12-19 14:04:31 +01:00
parent 20a94f0ef3
commit fce785c734
No known key found for this signature in database
GPG Key ID: 2FBC97406B43D889
5 changed files with 60 additions and 36 deletions

View File

@ -155,10 +155,12 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) :
isBound = true isBound = true
} }
private fun showVoiceMessageDuration(message: ChatMessage) { private fun showVoiceMessageDuration(message: ChatMessage) {
if (message.voiceMessageDuration > 0) { if (message.voiceMessageDuration > 0) {
binding.voiceMessageDuration.text = android.text.format.DateUtils.formatElapsedTime( binding.voiceMessageDuration.text = android.text.format.DateUtils.formatElapsedTime(
message.voiceMessageDuration.toLong()) message.voiceMessageDuration.toLong()
)
binding.voiceMessageDuration.visibility = View.VISIBLE binding.voiceMessageDuration.visibility = View.VISIBLE
} else { } else {
binding.voiceMessageDuration.visibility = View.INVISIBLE binding.voiceMessageDuration.visibility = View.INVISIBLE
@ -291,8 +293,10 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) :
} }
private fun colorizeMessageBubble(message: ChatMessage) { private fun colorizeMessageBubble(message: ChatMessage) {
viewThemeUtils.talk.themeIncomingMessageBubble(bubble, message.isGrouped, viewThemeUtils.talk.themeIncomingMessageBubble(
message.isDeleted, message.wasPlayedVoiceMessage) bubble, message.isGrouped,
message.isDeleted, message.wasPlayedVoiceMessage
)
} }
@Suppress("Detekt.TooGenericExceptionCaught") @Suppress("Detekt.TooGenericExceptionCaught")

View File

@ -199,7 +199,8 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) :
private fun showVoiceMessageDuration(message: ChatMessage) { private fun showVoiceMessageDuration(message: ChatMessage) {
if (message.voiceMessageDuration > 0) { if (message.voiceMessageDuration > 0) {
binding.voiceMessageDuration.text = android.text.format.DateUtils.formatElapsedTime( binding.voiceMessageDuration.text = android.text.format.DateUtils.formatElapsedTime(
message.voiceMessageDuration.toLong()) message.voiceMessageDuration.toLong()
)
binding.voiceMessageDuration.visibility = View.VISIBLE binding.voiceMessageDuration.visibility = View.VISIBLE
} else { } else {
binding.voiceMessageDuration.visibility = View.INVISIBLE binding.voiceMessageDuration.visibility = View.INVISIBLE
@ -356,8 +357,10 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) :
} }
private fun colorizeMessageBubble(message: ChatMessage) { private fun colorizeMessageBubble(message: ChatMessage) {
viewThemeUtils.talk.themeOutgoingMessageBubble(bubble, message.isGrouped, viewThemeUtils.talk.themeOutgoingMessageBubble(
message.isDeleted, message.wasPlayedVoiceMessage) bubble, message.isGrouped,
message.isDeleted, message.wasPlayedVoiceMessage
)
} }
fun assignVoiceMessageInterface(voiceMessageInterface: VoiceMessageInterface) { fun assignVoiceMessageInterface(voiceMessageInterface: VoiceMessageInterface) {

View File

@ -1205,8 +1205,10 @@ class ChatActivity :
} }
} }
private fun setUpWaveform(message: ChatMessage, thenPlay: Boolean = true, private fun setUpWaveform(
backgroundPlayAllowed: Boolean = false) { message: ChatMessage, thenPlay: Boolean = true,
backgroundPlayAllowed: Boolean = false
) {
val filename = message.selectedIndividualHashMap!!["name"] val filename = message.selectedIndividualHashMap!!["name"]
val file = File(context.cacheDir, filename!!) val file = File(context.cacheDir, filename!!)
if (file.exists() && message.voiceMessageFloatArray == null) { if (file.exists() && message.voiceMessageFloatArray == null) {
@ -1615,8 +1617,10 @@ class ChatActivity :
} }
} }
private fun startPlayback(message: ChatMessage, doPlay: Boolean = true, private fun startPlayback(
backgroundPlayAllowed: Boolean = false) { message: ChatMessage, doPlay: Boolean = true,
backgroundPlayAllowed: Boolean = false
) {
if (!active && !backgroundPlayAllowed) { if (!active && !backgroundPlayAllowed) {
// don't begin to play voice message if screen is not visible anymore. // don't begin to play voice message if screen is not visible anymore.
// this situation might happen if file is downloading but user already left the chatview. // this situation might happen if file is downloading but user already left the chatview.
@ -1630,22 +1634,22 @@ class ChatActivity :
val id = message.id.toString() val id = message.id.toString()
val index = adapter?.getMessagePositionById(id) ?: 0 val index = adapter?.getMessagePositionById(id) ?: 0
var nextMessage : ChatMessage? = null var nextMessage: ChatMessage? = null
for (i in -5..5) { for (i in -5..5) {
if(index - i < 0){ if (index - i < 0) {
break break
} }
if(i == 0 || index - i >= (adapter?.items?.size?: 0) ){ if (i == 0 || index - i >= (adapter?.items?.size ?: 0)) {
continue continue
} }
val curMsg = adapter?.items?.getOrNull(index - i)?.item val curMsg = adapter?.items?.getOrNull(index - i)?.item
if(curMsg is ChatMessage) { if (curMsg is ChatMessage) {
if(nextMessage == null && i > 0) { if (nextMessage == null && i > 0) {
nextMessage = curMsg as ChatMessage nextMessage = curMsg as ChatMessage
} }
if(curMsg.isVoiceMessage){ if (curMsg.isVoiceMessage) {
if(curMsg.selectedIndividualHashMap == null){ if (curMsg.selectedIndividualHashMap == null) {
// WORKAROUND TO FETCH FILE INFO: // WORKAROUND TO FETCH FILE INFO:
curMsg.getImageUrl() curMsg.getImageUrl()
} }
@ -1657,27 +1661,33 @@ class ChatActivity :
curMsg.voiceMessageDuration = try { curMsg.voiceMessageDuration = try {
val retriever = MediaMetadataRetriever() val retriever = MediaMetadataRetriever()
retriever.setDataSource(file.absolutePath) // Set the audio file as the data source retriever.setDataSource(file.absolutePath) // Set the audio file as the data source
val durationStr = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION) val durationStr =
retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)
retriever.release() // Always release the retriever to free resources retriever.release() // Always release the retriever to free resources
(durationStr?.toIntOrNull() ?: 0 )/ 1000 // Convert to int (seconds) (durationStr?.toIntOrNull() ?: 0) / 1000 // Convert to int (seconds)
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "An exception occurred while computing " + Log.e(
"voice message duration for " + filename, e) TAG, "An exception occurred while computing " +
"voice message duration for " + filename, e
)
0 0
} }
adapter?.update(curMsg) adapter?.update(curMsg)
} }
}else{ } else {
if(curMsg.voiceMessageDuration == 0) { if (curMsg.voiceMessageDuration == 0) {
curMsg.voiceMessageDuration = try { curMsg.voiceMessageDuration = try {
val retriever = MediaMetadataRetriever() val retriever = MediaMetadataRetriever()
retriever.setDataSource(file.absolutePath) // Set the audio file as the data source retriever.setDataSource(file.absolutePath) // Set the audio file as the data source
val durationStr = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION) val durationStr =
retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)
retriever.release() // Always release the retriever to free resources retriever.release() // Always release the retriever to free resources
(durationStr?.toIntOrNull() ?: 0 )/ 1000 // Convert to int (seconds) (durationStr?.toIntOrNull() ?: 0) / 1000 // Convert to int (seconds)
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "An exception occurred while computing " + Log.e(
"voice message duration for " + filename, e) TAG, "An exception occurred while computing " +
"voice message duration for " + filename, e
)
0 0
} }
adapter?.update(curMsg) adapter?.update(curMsg)
@ -1687,7 +1697,7 @@ class ChatActivity :
} }
} }
val hasConsecutiveVoiceMessage = if(nextMessage != null) nextMessage.isVoiceMessage else false val hasConsecutiveVoiceMessage = if (nextMessage != null) nextMessage.isVoiceMessage else false
mediaPlayer?.let { mediaPlayer?.let {
@ -1710,7 +1720,7 @@ class ChatActivity :
lastRecordMediaPosition = mediaPlayer!!.currentPosition lastRecordMediaPosition = mediaPlayer!!.currentPosition
message.voiceMessagePlayedSeconds = pos.toInt() message.voiceMessagePlayedSeconds = pos.toInt()
message.voiceMessageSeekbarProgress = mediaPlayer!!.currentPosition message.voiceMessageSeekbarProgress = mediaPlayer!!.currentPosition
if(mediaPlayer!!.currentPosition * 20 > mediaPlayer!!.duration){ if (mediaPlayer!!.currentPosition * 20 > mediaPlayer!!.duration) {
// a voice message is marked as played when the mediaplayer position // a voice message is marked as played when the mediaplayer position
// is at least at 5% of its duration // is at least at 5% of its duration
message.wasPlayedVoiceMessage = true message.wasPlayedVoiceMessage = true
@ -1722,9 +1732,11 @@ class ChatActivity :
message.voiceMessageSeekbarProgress = 0 message.voiceMessageSeekbarProgress = 0
adapter?.update(message) adapter?.update(message)
stopMediaPlayer(message) stopMediaPlayer(message)
if(hasConsecutiveVoiceMessage){ if (hasConsecutiveVoiceMessage) {
val defaultMediaPlayer = MediaPlayer.create(context, R.raw val defaultMediaPlayer = MediaPlayer.create(
.next_voice_message_doodle) context, R.raw
.next_voice_message_doodle
)
defaultMediaPlayer.setOnCompletionListener { defaultMediaPlayer.setOnCompletionListener {
defaultMediaPlayer.release() defaultMediaPlayer.release()
setUpWaveform(nextMessage as ChatMessage, doPlay, true) setUpWaveform(nextMessage as ChatMessage, doPlay, true)
@ -3188,7 +3200,7 @@ class ChatActivity :
private fun isInfoMessageAboutDeletion(currentMessage: MutableMap.MutableEntry<String, ChatMessage>): Boolean = private fun isInfoMessageAboutDeletion(currentMessage: MutableMap.MutableEntry<String, ChatMessage>): Boolean =
currentMessage.value.parentMessageId != null && currentMessage.value.parentMessageId != null &&
currentMessage.value.systemMessageType == ChatMessage currentMessage.value.systemMessageType == ChatMessage
.SystemMessageType.MESSAGE_DELETED .SystemMessageType.MESSAGE_DELETED
private fun isReactionsMessage(currentMessage: MutableMap.MutableEntry<String, ChatMessage>): Boolean = private fun isReactionsMessage(currentMessage: MutableMap.MutableEntry<String, ChatMessage>): Boolean =
currentMessage.value.systemMessageType == ChatMessage.SystemMessageType.REACTION || currentMessage.value.systemMessageType == ChatMessage.SystemMessageType.REACTION ||
@ -3198,7 +3210,7 @@ class ChatActivity :
private fun isEditMessage(currentMessage: MutableMap.MutableEntry<String, ChatMessage>): Boolean = private fun isEditMessage(currentMessage: MutableMap.MutableEntry<String, ChatMessage>): Boolean =
currentMessage.value.parentMessageId != null && currentMessage.value.parentMessageId != null &&
currentMessage.value.systemMessageType == ChatMessage currentMessage.value.systemMessageType == ChatMessage
.SystemMessageType.MESSAGE_EDITED .SystemMessageType.MESSAGE_EDITED
private fun isPollVotedMessage(currentMessage: MutableMap.MutableEntry<String, ChatMessage>): Boolean = private fun isPollVotedMessage(currentMessage: MutableMap.MutableEntry<String, ChatMessage>): Boolean =
currentMessage.value.systemMessageType == ChatMessage.SystemMessageType.POLL_VOTED currentMessage.value.systemMessageType == ChatMessage.SystemMessageType.POLL_VOTED
@ -3493,7 +3505,7 @@ class ChatActivity :
val lon = data["longitude"]!! val lon = data["longitude"]!!
metaData = metaData =
"{\"type\":\"geo-location\",\"id\":\"geo:$lat,$lon\",\"latitude\":\"$lat\"," + "{\"type\":\"geo-location\",\"id\":\"geo:$lat,$lon\",\"latitude\":\"$lat\"," +
"\"longitude\":\"$lon\",\"name\":\"$name\"}" "\"longitude\":\"$lon\",\"name\":\"$name\"}"
} }
shareToNotes(shareUri, roomToken, message, objectId, metaData) shareToNotes(shareUri, roomToken, message, objectId, metaData)
@ -3724,6 +3736,7 @@ class ChatActivity :
callStarted = true callStarted = true
} }
} }
ChatMessage.SystemMessageType.CALL_ENDED, ChatMessage.SystemMessageType.CALL_ENDED,
ChatMessage.SystemMessageType.CALL_MISSED, ChatMessage.SystemMessageType.CALL_MISSED,
ChatMessage.SystemMessageType.CALL_TRIED, ChatMessage.SystemMessageType.CALL_TRIED,
@ -3731,6 +3744,7 @@ class ChatActivity :
callStarted = false callStarted = false
messageInputViewModel.showCallStartedIndicator(recent, false) messageInputViewModel.showCallStartedIndicator(recent, false)
} }
else -> {} else -> {}
} }
} }

View File

@ -296,9 +296,11 @@ data class ChatMessage(
activeUser == null -> { activeUser == null -> {
null null
} }
actorType == "users" -> { actorType == "users" -> {
ApiUtils.getUrlForAvatar(activeUser!!.baseUrl!!, actorId, true) ApiUtils.getUrlForAvatar(activeUser!!.baseUrl!!, actorId, true)
} }
actorType == "bridged" -> { actorType == "bridged" -> {
ApiUtils.getUrlForAvatar( ApiUtils.getUrlForAvatar(
activeUser!!.baseUrl!!, activeUser!!.baseUrl!!,
@ -306,6 +308,7 @@ data class ChatMessage(
true true
) )
} }
else -> { else -> {
var apiId: String? = sharedApplication!!.getString(R.string.nc_guest) var apiId: String? = sharedApplication!!.getString(R.string.nc_guest)
if (!TextUtils.isEmpty(actorDisplayName)) { if (!TextUtils.isEmpty(actorDisplayName)) {

View File

@ -99,7 +99,7 @@ class TalkSpecificViewThemeUtils @Inject constructor(
withScheme(bubble) { scheme -> withScheme(bubble) { scheme ->
val bgBubbleColor = if (deleted) { val bgBubbleColor = if (deleted) {
ColorUtils.setAlphaComponent(dynamicColor.surfaceVariant().getArgb(scheme), HALF_ALPHA_INT) ColorUtils.setAlphaComponent(dynamicColor.surfaceVariant().getArgb(scheme), HALF_ALPHA_INT)
} else if(isPlayed){ } else if (isPlayed) {
ContextCompat.getColor(bubble.context, R.color.bg_message_list_outgoing_bubble_audio_played) ContextCompat.getColor(bubble.context, R.color.bg_message_list_outgoing_bubble_audio_played)
} else { } else {
dynamicColor.surfaceVariant().getArgb(scheme) dynamicColor.surfaceVariant().getArgb(scheme)