Skip to content

Commit e920a79

Browse files
authored
Merge pull request #4940 from nextcloud/attachment_attachment
Improve subline when last message is attachment
2 parents af12192 + f29793b commit e920a79

File tree

11 files changed

+255
-53
lines changed

11 files changed

+255
-53
lines changed

app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.kt

Lines changed: 85 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,18 @@ import android.annotation.SuppressLint
1313
import android.content.Context
1414
import android.content.res.ColorStateList
1515
import android.graphics.Typeface
16+
import android.text.SpannableStringBuilder
17+
import android.text.Spanned
1618
import android.text.TextUtils
1719
import android.text.format.DateUtils
20+
import android.text.style.ImageSpan
1821
import android.view.View
1922
import androidx.core.content.ContextCompat
2023
import androidx.core.content.res.ResourcesCompat
2124
import com.nextcloud.talk.R
2225
import com.nextcloud.talk.adapters.items.ConversationItem.ConversationItemViewHolder
2326
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
27+
import com.nextcloud.talk.chat.data.model.ChatMessage
2428
import com.nextcloud.talk.chat.data.model.ChatMessage.MessageType
2529
import com.nextcloud.talk.data.database.mappers.asModel
2630
import com.nextcloud.talk.data.user.model.User
@@ -209,7 +213,6 @@ class ConversationItem(
209213
R.drawable.ic_avatar_document
210214
)
211215
)
212-
213216
false
214217
}
215218

@@ -229,7 +232,7 @@ class ConversationItem(
229232
if (!TextUtils.isEmpty(chatMessage?.systemMessage) ||
230233
ConversationEnums.ConversationType.ROOM_SYSTEM === model.type
231234
) {
232-
holder.binding.dialogLastMessage.text = chatMessage?.text
235+
holder.binding.dialogLastMessage.text = chatMessage.text
233236
} else {
234237
chatMessage?.activeUser = user
235238

@@ -249,7 +252,7 @@ class ConversationItem(
249252
}
250253
}
251254

252-
private fun calculateRegularLastMessageText(appContext: Context): String {
255+
private fun calculateRegularLastMessageText(appContext: Context): CharSequence {
253256
return if (chatMessage?.actorId == user.userId) {
254257
String.format(
255258
appContext.getString(R.string.nc_formatted_message_you),
@@ -331,7 +334,7 @@ class ConversationItem(
331334
this.header = header
332335
}
333336

334-
private val lastMessageDisplayText: String
337+
private val lastMessageDisplayText: CharSequence
335338
get() {
336339
if (chatMessage?.getCalculateMessageType() == MessageType.REGULAR_TEXT_MESSAGE ||
337340
chatMessage?.getCalculateMessageType() == MessageType.SYSTEM_MESSAGE ||
@@ -351,33 +354,21 @@ class ConversationItem(
351354
chatMessage?.getNullsafeActorDisplayName()
352355
)
353356
}
354-
} else if (MessageType.SINGLE_NC_ATTACHMENT_MESSAGE == chatMessage?.getCalculateMessageType()) {
355-
return if (chatMessage?.actorId == chatMessage?.activeUser!!.userId) {
356-
sharedApplication!!.getString(R.string.nc_sent_an_attachment_you)
357-
} else {
358-
String.format(
359-
sharedApplication!!.resources.getString(R.string.nc_sent_an_attachment),
360-
chatMessage?.getNullsafeActorDisplayName()
361-
)
362-
}
363357
} else if (MessageType.SINGLE_NC_GEOLOCATION_MESSAGE == chatMessage?.getCalculateMessageType()) {
364-
return if (chatMessage?.actorId == chatMessage?.activeUser!!.userId) {
365-
sharedApplication!!.getString(R.string.nc_sent_location_you)
366-
} else {
367-
String.format(
368-
sharedApplication!!.resources.getString(R.string.nc_sent_location),
369-
chatMessage?.getNullsafeActorDisplayName()
370-
)
371-
}
358+
var locationName = chatMessage.messageParameters?.get("object")?.get("name") ?: ""
359+
val author = authorName(chatMessage)
360+
val lastMessage =
361+
setLastNameForAttachmentMessage(author, R.drawable.baseline_location_pin_24, locationName)
362+
return lastMessage
372363
} else if (MessageType.VOICE_MESSAGE == chatMessage?.getCalculateMessageType()) {
373-
return if (chatMessage?.actorId == chatMessage?.activeUser!!.userId) {
374-
sharedApplication!!.getString(R.string.nc_sent_voice_you)
375-
} else {
376-
String.format(
377-
sharedApplication!!.resources.getString(R.string.nc_sent_voice),
378-
chatMessage?.getNullsafeActorDisplayName()
379-
)
380-
}
364+
var voiceMessageName = chatMessage.messageParameters?.get("file")?.get("name") ?: ""
365+
val author = authorName(chatMessage)
366+
val lastMessage = setLastNameForAttachmentMessage(
367+
author,
368+
R.drawable.baseline_mic_24,
369+
voiceMessageName
370+
)
371+
return lastMessage
381372
} else if (MessageType.SINGLE_LINK_AUDIO_MESSAGE == chatMessage?.getCalculateMessageType()) {
382373
return if (chatMessage?.actorId == chatMessage?.activeUser!!.userId) {
383374
sharedApplication!!.getString(R.string.nc_sent_an_audio_you)
@@ -406,28 +397,77 @@ class ConversationItem(
406397
)
407398
}
408399
} else if (MessageType.POLL_MESSAGE == chatMessage?.getCalculateMessageType()) {
409-
return if (chatMessage?.actorId == chatMessage?.activeUser!!.userId) {
410-
sharedApplication!!.getString(R.string.nc_sent_poll_you)
411-
} else {
412-
String.format(
413-
sharedApplication!!.resources.getString(R.string.nc_sent_poll),
414-
chatMessage?.getNullsafeActorDisplayName()
415-
)
400+
var pollMessageTitle = chatMessage.messageParameters?.get("object")?.get("name") ?: ""
401+
val author = authorName(chatMessage)
402+
val lastMessage = setLastNameForAttachmentMessage(
403+
author,
404+
R.drawable.baseline_bar_chart_24,
405+
pollMessageTitle
406+
)
407+
return lastMessage
408+
} else if (MessageType.SINGLE_NC_ATTACHMENT_MESSAGE == chatMessage?.getCalculateMessageType()) {
409+
var attachmentName = chatMessage.message
410+
if (attachmentName == "{file}") {
411+
attachmentName = chatMessage.messageParameters?.get("file")?.get("name")
416412
}
417-
} else if (MessageType.DECK_CARD == chatMessage?.getCalculateMessageType()) {
418-
return if (chatMessage?.actorId == chatMessage?.activeUser!!.userId) {
419-
sharedApplication!!.getString(R.string.nc_sent_deck_card_you)
420-
} else {
421-
String.format(
422-
sharedApplication!!.resources.getString(R.string.nc_sent_deck_card),
423-
chatMessage?.getNullsafeActorDisplayName()
424-
)
413+
val author = authorName(chatMessage)
414+
415+
val drawable = chatMessage.messageParameters?.get("file")?.get("mimetype")?.let {
416+
when {
417+
it.contains("image") -> R.drawable.baseline_image_24
418+
it.contains("video") -> R.drawable.baseline_video_24
419+
it.contains("application") -> R.drawable.baseline_insert_drive_file_24
420+
it.contains("audio") -> R.drawable.baseline_audiotrack_24
421+
it.contains("text/vcard") -> R.drawable.baseline_contacts_24
422+
else -> null
423+
}
425424
}
425+
val lastMessage = setLastNameForAttachmentMessage(author, drawable, attachmentName!!)
426+
return lastMessage
427+
} else if (MessageType.DECK_CARD == chatMessage?.getCalculateMessageType()) {
428+
var deckTitle = chatMessage.messageParameters?.get("object")?.get("name") ?: ""
429+
val author = authorName(chatMessage)
430+
val lastMessage = setLastNameForAttachmentMessage(author, R.drawable.baseline_article_24, deckTitle)
431+
return lastMessage
426432
}
427433
}
428434
return ""
429435
}
430436

437+
fun authorName(chatMessage: ChatMessage): String {
438+
val name = if (chatMessage.actorId == chatMessage.activeUser!!.userId) {
439+
sharedApplication!!.resources.getString(R.string.nc_current_user)
440+
} else {
441+
chatMessage.getNullsafeActorDisplayName()?.let { "$it:" } ?: ""
442+
}
443+
return name
444+
}
445+
446+
fun setLastNameForAttachmentMessage(actor: String, icon: Int?, attachmentName: String): SpannableStringBuilder {
447+
val builder = SpannableStringBuilder()
448+
builder.append(actor)
449+
450+
val drawable = icon?.let { it -> ContextCompat.getDrawable(context, it) }
451+
if (drawable != null) {
452+
viewThemeUtils.platform.colorDrawable(
453+
drawable,
454+
context.resources.getColor(R.color.low_emphasis_text, null)
455+
)
456+
val desiredWidth = (drawable.intrinsicWidth * IMAGE_SCALE_FACTOR).toInt()
457+
val desiredHeight = (drawable.intrinsicHeight * IMAGE_SCALE_FACTOR).toInt()
458+
drawable.setBounds(0, 0, desiredWidth, desiredHeight)
459+
460+
val imageSpan = ImageSpan(drawable, ImageSpan.ALIGN_BOTTOM)
461+
val startImage = builder.length
462+
builder.append(" ")
463+
builder.setSpan(imageSpan, startImage, startImage + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
464+
} else {
465+
builder.append(" ")
466+
}
467+
builder.append(attachmentName)
468+
return builder
469+
}
470+
431471
class ConversationItemViewHolder(view: View?, adapter: FlexibleAdapter<*>?) : FlexibleViewHolder(view, adapter) {
432472
var binding: RvItemConversationWithLastMessageBinding
433473

@@ -442,5 +482,6 @@ class ConversationItem(
442482
private const val STATUS_SIZE_IN_DP = 9f
443483
private const val UNREAD_BUBBLE_STROKE_WIDTH = 6.0f
444484
private const val UNREAD_MESSAGES_TRESHOLD = 1000
485+
private const val IMAGE_SCALE_FACTOR = 0.7f
445486
}
446487
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
<!--
3+
~ Nextcloud Talk - Android Client
4+
~
5+
~ SPDX-FileCopyrightText: 2025 Your Name <[email protected]>
6+
~ SPDX-License-Identifier: GPL-3.0-or-later
7+
-->
8+
9+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
10+
android:autoMirrored="true"
11+
android:height="24dp"
12+
android:tint="#969696"
13+
android:viewportHeight="24"
14+
android:viewportWidth="24"
15+
android:width="24dp">
16+
17+
<path android:fillColor="#969696"
18+
android:pathData="M19,3L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM14,17L7,17v-2h7v2zM17,13L7,13v-2h10v2zM17,9L7,9L7,7h10v2z"/>
19+
20+
</vector>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!--
2+
~ Nextcloud Talk - Android Client
3+
~
4+
~ SPDX-FileCopyrightText: 2025 Google LLC
5+
~ SPDX-License-Identifier: GPL-3.0-or-later
6+
-->
7+
8+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
9+
android:height="24dp"
10+
android:tint="#969696"
11+
android:viewportHeight="24"
12+
android:viewportWidth="24"
13+
android:width="24dp">
14+
15+
<path android:fillColor="#969696"
16+
android:pathData="M12,3v9.28c-0.47,-0.17 -0.97,-0.28 -1.5,-0.28C8.01,12 6,14.01 6,16.5S8.01,21 10.5,21c2.31,0 4.2,-1.75 4.45,-4H15V6h4V3h-7z"/>
17+
18+
</vector>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<!--
2+
~ Nextcloud Talk - Android Client
3+
~
4+
~ SPDX-FileCopyrightText: 2025 Google LLC
5+
~ SPDX-License-Identifier: GPL-3.0-or-later
6+
-->
7+
8+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
9+
android:height="24dp"
10+
android:tint="#969696"
11+
android:viewportHeight="24"
12+
android:viewportWidth="24"
13+
android:width="24dp">
14+
15+
<path android:fillColor="#969696" android:pathData="M4,9h4v11h-4z"/>
16+
17+
<path android:fillColor="#969696" android:pathData="M16,13h4v7h-4z"/>
18+
19+
<path android:fillColor="#969696" android:pathData="M10,4h4v16h-4z"/>
20+
21+
</vector>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!--
2+
~ Nextcloud Talk - Android Client
3+
~
4+
~ SPDX-FileCopyrightText: 2025 Google LLC
5+
~ SPDX-License-Identifier: GPL-3.0-or-later
6+
-->
7+
8+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
9+
android:height="24dp"
10+
android:tint="#969696"
11+
android:viewportHeight="24"
12+
android:viewportWidth="24"
13+
android:width="24dp">
14+
15+
<path android:fillColor="#969696"
16+
android:pathData="M20,0L4,0v2h16L20,0zM4,24h16v-2L4,22v2zM20,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2zM12,6.75c1.24,0 2.25,1.01 2.25,2.25s-1.01,2.25 -2.25,2.25S9.75,10.24 9.75,9 10.76,6.75 12,6.75zM17,17L7,17v-1.5c0,-1.67 3.33,-2.5 5,-2.5s5,0.83 5,2.5L17,17z"/>
17+
18+
</vector>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!--
2+
~ Nextcloud Talk - Android Client
3+
~
4+
~ SPDX-FileCopyrightText: 2025 Google LLC
5+
~ SPDX-License-Identifier: GPL-3.0-or-later
6+
-->
7+
8+
<vector
9+
xmlns:android="http://schemas.android.com/apk/res/android"
10+
android:height="24dp"
11+
android:tint="#969696"
12+
android:viewportHeight="24"
13+
android:viewportWidth="24"
14+
android:width="24dp">
15+
16+
<path android:fillColor="#969696"
17+
android:pathData="M21,19V5c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2zM8.5,13.5l2.5,3.01L14.5,12l4.5,6H5l3.5,-4.5z"/>
18+
19+
</vector>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!--
2+
~ Nextcloud Talk - Android Client
3+
~
4+
~ SPDX-FileCopyrightText: 2025 Google LLC
5+
~ SPDX-License-Identifier: GPL-3.0-or-later
6+
-->
7+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
8+
android:autoMirrored="true"
9+
android:height="24dp"
10+
android:tint="#969696"
11+
android:viewportHeight="24"
12+
android:viewportWidth="24"
13+
android:width="24dp">
14+
15+
<path android:fillColor="#969696"
16+
android:pathData="M6,2c-1.1,0 -1.99,0.9 -1.99,2L4,20c0,1.1 0.89,2 1.99,2L18,22c1.1,0 2,-0.9 2,-2L20,8l-6,-6L6,2zM13,9L13,3.5L18.5,9L13,9z"/>
17+
18+
</vector>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!--
2+
~ Nextcloud Talk - Android Client
3+
~
4+
~ SPDX-FileCopyrightText: 2025 Google LLC
5+
~ SPDX-License-Identifier: GPL-3.0-or-later
6+
-->
7+
8+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
9+
android:height="24dp"
10+
android:tint="#969696"
11+
android:viewportHeight="24"
12+
android:viewportWidth="24"
13+
android:width="24dp">
14+
15+
<path android:fillColor="#969696"
16+
android:pathData="M12,2L12,2C8.13,2 5,5.13 5,9c0,1.74 0.5,3.37 1.41,4.84c0.95,1.54 2.2,2.86 3.16,4.4c0.47,0.75 0.81,1.45 1.17,2.26C11,21.05 11.21,22 12,22h0c0.79,0 1,-0.95 1.25,-1.5c0.37,-0.81 0.7,-1.51 1.17,-2.26c0.96,-1.53 2.21,-2.85 3.16,-4.4C18.5,12.37 19,10.74 19,9C19,5.13 15.87,2 12,2zM12,11.75c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5s2.5,1.12 2.5,2.5S13.38,11.75 12,11.75z"/>
17+
18+
</vector>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!--
2+
~ Nextcloud Talk - Android Client
3+
~
4+
~ SPDX-FileCopyrightText: 2025 Google LLC
5+
~ SPDX-License-Identifier: GPL-3.0-or-later
6+
-->
7+
8+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
9+
android:height="24dp"
10+
android:tint="#969696"
11+
android:viewportHeight="24"
12+
android:viewportWidth="24"
13+
android:width="24dp">
14+
15+
<path android:fillColor="#969696"
16+
android:pathData="M12,14c1.66,0 2.99,-1.34 2.99,-3L15,5c0,-1.66 -1.34,-3 -3,-3S9,3.34 9,5v6c0,1.66 1.34,3 3,3zM17.3,11c0,3 -2.54,5.1 -5.3,5.1S6.7,14 6.7,11L5,11c0,3.41 2.72,6.23 6,6.72L11,21h2v-3.28c3.28,-0.48 6,-3.3 6,-6.72h-1.7z"/>
17+
18+
</vector>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!--
2+
~ Nextcloud Talk - Android Client
3+
~
4+
~ SPDX-FileCopyrightText: 2025 Google LLC
5+
~ SPDX-License-Identifier: GPL-3.0-or-later
6+
-->
7+
8+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
9+
android:height="24dp"
10+
android:tint="#969696"
11+
android:viewportHeight="24"
12+
android:viewportWidth="24"
13+
android:width="24dp">
14+
15+
<path android:fillColor="#969696"
16+
android:pathData="M18,4l2,4h-3l-2,-4h-2l2,4h-3l-2,-4H8l2,4H7L5,4H4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V4h-4z"/>
17+
18+
</vector>

0 commit comments

Comments
 (0)