Properly look up participants in MMS group conversations

Application was always picking first participant when tapping on avatars
in conversations. It was also using first participant for MMS notifications.

This stores sender's phone number in the database, so it can be used to look
up correct participant in the list of participants. If matching on number fails,
matching on name is attempted. If both of these fail, it falls back to previous
behavior, which is just picking the first participant.

This may also be connected to #32, but I am not sure, since this should just
be related to behavior when tapping on avatars. Mixing up avatars in the
conversation should be a different issue.

This closes #433, closes #500, closes #384
This commit is contained in:
Ensar Sarajčić 2023-07-07 10:48:35 +02:00
parent b0da7bad31
commit daf11dc6fd
7 changed files with 44 additions and 8 deletions

View File

@ -1606,6 +1606,7 @@ class ThreadActivity : SimpleActivity() {
threadId = threadId,
isMMS = isMmsMessage(text),
attachment = MessageAttachment(messageId, text, buildMessageAttachments(messageId)),
senderPhoneNumber = "",
senderName = "",
senderPhotoUri = "",
subscriptionId = subscriptionId,

View File

@ -283,7 +283,7 @@ class ThreadAdapter(
view.apply {
thread_message_sender_photo.beVisible()
thread_message_sender_photo.setOnClickListener {
val contact = message.participants.first()
val contact = message.getSender()!!
context.getContactFromAddress(contact.phoneNumbers.first().normalizedNumber) {
if (it != null) {
activity.startContactDetailsIntent(it)

View File

@ -17,7 +17,7 @@ import com.simplemobiletools.smsmessenger.models.Conversation
import com.simplemobiletools.smsmessenger.models.Message
import com.simplemobiletools.smsmessenger.models.MessageAttachment
@Database(entities = [Conversation::class, Attachment::class, MessageAttachment::class, Message::class], version = 6)
@Database(entities = [Conversation::class, Attachment::class, MessageAttachment::class, Message::class], version = 7)
@TypeConverters(Converters::class)
abstract class MessagesDatabase : RoomDatabase() {
@ -43,6 +43,7 @@ abstract class MessagesDatabase : RoomDatabase() {
.addMigrations(MIGRATION_3_4)
.addMigrations(MIGRATION_4_5)
.addMigrations(MIGRATION_5_6)
.addMigrations(MIGRATION_6_7)
.build()
}
}
@ -106,5 +107,13 @@ abstract class MessagesDatabase : RoomDatabase() {
}
}
}
private val MIGRATION_6_7 = object : Migration(6, 7) {
override fun migrate(database: SupportSQLiteDatabase) {
database.apply {
execSQL("ALTER TABLE messages ADD COLUMN sender_phone_number TEXT NOT NULL DEFAULT ''")
}
}
}
}
}

View File

@ -116,7 +116,8 @@ fun Context.getMessages(
SimpleContact(0, 0, participantPhoto.name, photoUri, arrayListOf(phoneNumber), ArrayList(), ArrayList())
}
val isMMS = false
val message = Message(id, body, type, status, ArrayList(participants), date, read, thread, isMMS, null, senderName, photoUri, subscriptionId)
val message =
Message(id, body, type, status, ArrayList(participants), date, read, thread, isMMS, null, senderNumber, senderName, photoUri, subscriptionId)
messages.add(message)
}
@ -189,17 +190,19 @@ fun Context.getMMS(threadId: Long? = null, getImageResolutions: Boolean = false,
val isMMS = true
val attachment = getMmsAttachment(mmsId, getImageResolutions)
val body = attachment.text
var senderNumber = ""
var senderName = ""
var senderPhotoUri = ""
if (type != Mms.MESSAGE_BOX_SENT && type != Mms.MESSAGE_BOX_FAILED) {
val number = getMMSSender(mmsId)
val namePhoto = getNameAndPhotoFromPhoneNumber(number)
senderNumber = getMMSSender(mmsId)
val namePhoto = getNameAndPhotoFromPhoneNumber(senderNumber)
senderName = namePhoto.name
senderPhotoUri = namePhoto.photoUri ?: ""
}
val message = Message(mmsId, body, type, status, participants, date, read, threadId, isMMS, attachment, senderName, senderPhotoUri, subscriptionId)
val message =
Message(mmsId, body, type, status, participants, date, read, threadId, isMMS, attachment, senderNumber, senderName, senderPhotoUri, subscriptionId)
messages.add(message)
participants.forEach {

View File

@ -18,6 +18,7 @@ data class Message(
@ColumnInfo(name = "thread_id") val threadId: Long,
@ColumnInfo(name = "is_mms") val isMMS: Boolean,
@ColumnInfo(name = "attachment") val attachment: MessageAttachment?,
@ColumnInfo(name = "sender_phone_number") val senderPhoneNumber: String,
@ColumnInfo(name = "sender_name") var senderName: String,
@ColumnInfo(name = "sender_photo_uri") val senderPhotoUri: String,
@ColumnInfo(name = "subscription_id") var subscriptionId: Int,
@ -28,6 +29,11 @@ data class Message(
fun millis() = date * 1000L
fun getSender(): SimpleContact? =
participants.firstOrNull { it.doesHavePhoneNumber(senderPhoneNumber) }
?: participants.firstOrNull { it.name == senderName }
?: participants.firstOrNull()
companion object {
fun getStableId(message: Message): Long {
@ -37,6 +43,7 @@ data class Message(
result = 31 * result + message.threadId.hashCode()
result = 31 * result + message.isMMS.hashCode()
result = 31 * result + (message.attachment?.hashCode() ?: 0)
result = 31 * result + message.senderPhoneNumber.hashCode()
result = 31 * result + message.senderName.hashCode()
result = 31 * result + message.senderPhotoUri.hashCode()
result = 31 * result + message.isScheduled.hashCode()
@ -53,6 +60,7 @@ data class Message(
old.date == new.date &&
old.isMMS == new.isMMS &&
old.attachment == new.attachment &&
old.senderPhoneNumber == new.senderPhoneNumber &&
old.senderName == new.senderName &&
old.senderPhotoUri == new.senderPhotoUri &&
old.isScheduled == new.isScheduled

View File

@ -22,7 +22,7 @@ class MmsReceiver : com.klinker.android.send_message.MmsReceivedReceiver() {
override fun onMessageReceived(context: Context, messageUri: Uri) {
val mms = context.getLatestMMS() ?: return
val address = mms.participants.firstOrNull()?.phoneNumbers?.first()?.normalizedNumber ?: ""
val address = mms.getSender()?.phoneNumbers?.first()?.normalizedNumber ?: ""
val size = context.resources.getDimension(R.dimen.notification_large_icon_size).toInt()
ensureBackgroundThread {

View File

@ -83,7 +83,22 @@ class SmsReceiver : BroadcastReceiver() {
val messageDate = (date / 1000).toInt()
val message =
Message(newMessageId, body, type, status, participants, messageDate, false, threadId, false, null, senderName, photoUri, subscriptionId)
Message(
newMessageId,
body,
type,
status,
participants,
messageDate,
false,
threadId,
false,
null,
address,
senderName,
photoUri,
subscriptionId
)
context.messagesDB.insertOrUpdate(message)
refreshMessages()
context.showReceivedMessageNotification(newMessageId, address, body, threadId, bitmap)