diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt
index 3a5fe5147f..03d86dd627 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt
@@ -19,6 +19,7 @@ import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel
import org.session.libsession.messaging.threads.Address
import org.session.libsession.messaging.threads.GroupRecord
import org.session.libsession.messaging.threads.recipients.Recipient
+import org.session.libsession.messaging.utilities.UpdateMessageBuilder
import org.session.libsession.utilities.GroupUtil
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsignal.libsignal.ecc.ECKeyPair
@@ -79,6 +80,11 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
return recipient.profileKey
}
+ override fun getDisplayNameForRecipient(recipientPublicKey: String): String? {
+ val database = DatabaseFactory.getLokiUserDatabase(context)
+ return database.getDisplayName(recipientPublicKey)
+ }
+
override fun getOrGenerateRegistrationID(): Int {
var registrationID = TextSecurePreferences.getLocalRegistrationId(context)
if (registrationID == null) {
@@ -397,7 +403,8 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
.addAllAdmins(admins)
val group = SignalServiceGroup(type1, GroupUtil.getDecodedGroupIDAsData(groupID), SignalServiceGroup.GroupType.SIGNAL, name, members.toList(), null, admins.toList())
val m = IncomingTextMessage(Address.fromSerialized(senderPublicKey), 1, System.currentTimeMillis(), "", Optional.of(group), 0, true)
- val infoMessage = IncomingGroupMessage(m, groupContextBuilder.build(), "")
+ val messageBody = UpdateMessageBuilder.buildGroupUpdateMessage(context, group, senderPublicKey)
+ val infoMessage = IncomingGroupMessage(m, groupContextBuilder.build(), messageBody)
val smsDB = DatabaseFactory.getSmsDatabase(context)
smsDB.insertMessageInbox(infoMessage)
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocolV2.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocolV2.kt
index 9fba4b66ef..9aa4ddd389 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocolV2.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocolV2.kt
@@ -33,6 +33,7 @@ import org.session.libsignal.utilities.Hex
import org.session.libsession.messaging.threads.Address
import org.session.libsession.messaging.threads.GroupRecord
import org.session.libsession.messaging.threads.recipients.Recipient
+import org.session.libsession.messaging.utilities.UpdateMessageBuilder
import org.session.libsession.utilities.GroupUtil
import org.session.libsession.utilities.TextSecurePreferences
@@ -361,7 +362,7 @@ object ClosedGroupsProtocolV2 {
apiDB.addClosedGroupEncryptionKeyPair(encryptionKeyPair, groupPublicKey)
// Notify the user (if we didn't make the group)
if (userPublicKey != senderPublicKey) {
- insertIncomingInfoMessage(context, senderPublicKey, groupID, GroupContext.Type.UPDATE, SignalServiceGroup.Type.UPDATE, name, members, admins, sentTimestamp)
+ insertIncomingInfoMessage(context, senderPublicKey, groupID, GroupContext.Type.UPDATE, SignalServiceGroup.Type.NEW_GROUP, name, members, admins, sentTimestamp)
} else if (prevGroup == null) {
// only notify if we created this group
val threadID = DatabaseFactory.getLokiThreadDatabase(context).getThreadID(groupID)
@@ -415,12 +416,12 @@ object ClosedGroupsProtocolV2 {
}
val (contextType, signalType) =
if (senderLeft) GroupContext.Type.QUIT to SignalServiceGroup.Type.QUIT
- else GroupContext.Type.UPDATE to SignalServiceGroup.Type.UPDATE
+ else GroupContext.Type.UPDATE to SignalServiceGroup.Type.MEMBER_REMOVED
if (userPublicKey == senderPublicKey) {
val threadID = DatabaseFactory.getLokiThreadDatabase(context).getThreadID(groupID)
insertOutgoingInfoMessage(context, groupID, contextType, name, members, admins, threadID, sentTimestamp)
} else {
- insertIncomingInfoMessage(context, senderPublicKey, groupID, contextType, signalType, name, members, admins, sentTimestamp)
+ insertIncomingInfoMessage(context, senderPublicKey, groupID, contextType, signalType, name, updateMembers, admins, sentTimestamp)
}
}
@@ -450,7 +451,7 @@ object ClosedGroupsProtocolV2 {
val threadID = DatabaseFactory.getLokiThreadDatabase(context).getThreadID(groupID)
insertOutgoingInfoMessage(context, groupID, GroupContext.Type.UPDATE, name, members, admins, threadID, sentTimestamp)
} else {
- insertIncomingInfoMessage(context, senderPublicKey, groupID, GroupContext.Type.UPDATE, SignalServiceGroup.Type.UPDATE, name, members, admins, sentTimestamp)
+ insertIncomingInfoMessage(context, senderPublicKey, groupID, GroupContext.Type.UPDATE, SignalServiceGroup.Type.MEMBER_ADDED, name, updateMembers, admins, sentTimestamp)
}
if (userPublicKey in admins) {
// send current encryption key to the latest added members
@@ -489,7 +490,7 @@ object ClosedGroupsProtocolV2 {
val threadID = DatabaseFactory.getLokiThreadDatabase(context).getThreadID(groupID)
insertOutgoingInfoMessage(context, groupID, GroupContext.Type.UPDATE, name, members, admins, threadID, sentTimestamp)
} else {
- insertIncomingInfoMessage(context, senderPublicKey, groupID, GroupContext.Type.UPDATE, SignalServiceGroup.Type.UPDATE, name, members, admins, sentTimestamp)
+ insertIncomingInfoMessage(context, senderPublicKey, groupID, GroupContext.Type.UPDATE, SignalServiceGroup.Type.NAME_CHANGE, name, members, admins, sentTimestamp)
}
}
@@ -608,7 +609,8 @@ object ClosedGroupsProtocolV2 {
.addAllAdmins(admins)
val group = SignalServiceGroup(type1, GroupUtil.getDecodedGroupIDAsData(groupID), SignalServiceGroup.GroupType.SIGNAL, name, members.toList(), null, admins.toList())
val m = IncomingTextMessage(Address.fromSerialized(senderPublicKey), 1, sentTimestamp, "", Optional.of(group), 0, true)
- val infoMessage = IncomingGroupMessage(m, groupContextBuilder.build(), "")
+ val messageBody = UpdateMessageBuilder.buildGroupUpdateMessage(context, group, senderPublicKey)
+ val infoMessage = IncomingGroupMessage(m, groupContextBuilder.build(), messageBody)
val smsDB = DatabaseFactory.getSmsDatabase(context)
smsDB.insertMessageInbox(infoMessage)
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 0ff4e7f611..09c7b0f1be 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -493,6 +493,14 @@
Received a message encrypted using an old version of Session that is no longer supported. Please ask the sender to update to the most recent version and resend the message.
You have left the group.
You updated the group.
+ You created a new group.
+ %1$s added you to the group.
+ You renamed the group to %1$s
+ %1$s renamed the group to: %2$s
+ You added %1$s to the group.
+ %1$s added %2$s to the group.
+ You removed %1$s from the group.
+ %1$s removed %2$s from the group.
You called
Contact called
Missed call
diff --git a/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt b/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt
index e3062f73ee..5c66b2bd06 100644
--- a/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt
+++ b/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt
@@ -34,6 +34,7 @@ interface StorageProtocol {
fun getUserProfilePictureURL(): String?
fun getProfileKeyForRecipient(recipientPublicKey: String): ByteArray?
+ fun getDisplayNameForRecipient(recipientPublicKey: String): String?
// Signal Protocol
diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt
index 530badd329..740c181798 100644
--- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt
+++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt
@@ -239,7 +239,7 @@ private fun handleNewClosedGroup(sender: String, groupPublicKey: String, name: S
storage.createGroup(groupID, name, LinkedList(members.map { Address.fromSerialized(it) }),
null, null, LinkedList(admins.map { Address.fromSerialized(it) }), formationTimestamp)
// Notify the user
- storage.insertIncomingInfoMessage(context, sender, groupID, SignalServiceProtos.GroupContext.Type.UPDATE, SignalServiceGroup.Type.UPDATE, name, members, admins)
+ storage.insertIncomingInfoMessage(context, sender, groupID, SignalServiceProtos.GroupContext.Type.UPDATE, SignalServiceGroup.Type.NEW_GROUP, name, members, admins)
}
storage.setProfileSharing(Address.fromSerialized(groupID), true)
// Add the group to the user's set of public keys to poll for
@@ -356,7 +356,7 @@ private fun MessageReceiver.handleClosedGroupNameChanged(message: ClosedGroupCon
val name = kind.name
storage.updateTitle(groupID, name)
- storage.insertIncomingInfoMessage(context, senderPublicKey, groupID, SignalServiceProtos.GroupContext.Type.UPDATE, SignalServiceGroup.Type.UPDATE, name, members, admins)
+ storage.insertIncomingInfoMessage(context, senderPublicKey, groupID, SignalServiceProtos.GroupContext.Type.UPDATE, SignalServiceGroup.Type.NAME_CHANGE, name, members, admins)
}
private fun MessageReceiver.handleClosedGroupMembersAdded(message: ClosedGroupControlMessage) {
@@ -388,7 +388,7 @@ private fun MessageReceiver.handleClosedGroupMembersAdded(message: ClosedGroupCo
MessageSender.sendLatestEncryptionKeyPair(member, groupPublicKey)
}
}
- storage.insertIncomingInfoMessage(context, senderPublicKey, groupID, SignalServiceProtos.GroupContext.Type.UPDATE, SignalServiceGroup.Type.UPDATE, name, members, admins)
+ storage.insertIncomingInfoMessage(context, senderPublicKey, groupID, SignalServiceProtos.GroupContext.Type.UPDATE, SignalServiceGroup.Type.MEMBER_ADDED, name, updateMembers, admins)
}
private fun MessageReceiver.handleClosedGroupMembersRemoved(message: ClosedGroupControlMessage) {
@@ -435,9 +435,9 @@ private fun MessageReceiver.handleClosedGroupMembersRemoved(message: ClosedGroup
}
val (contextType, signalType) =
if (senderLeft) SignalServiceProtos.GroupContext.Type.QUIT to SignalServiceGroup.Type.QUIT
- else SignalServiceProtos.GroupContext.Type.UPDATE to SignalServiceGroup.Type.UPDATE
+ else SignalServiceProtos.GroupContext.Type.UPDATE to SignalServiceGroup.Type.MEMBER_REMOVED
- storage.insertIncomingInfoMessage(context, senderPublicKey, groupID, contextType, signalType, name, members, admins)
+ storage.insertIncomingInfoMessage(context, senderPublicKey, groupID, contextType, signalType, name, updateMembers, admins)
}
private fun MessageReceiver.handleClosedGroupMemberLeft(message: ClosedGroupControlMessage) {
diff --git a/libsession/src/main/java/org/session/libsession/messaging/utilities/UpdateMessageBuilder.kt b/libsession/src/main/java/org/session/libsession/messaging/utilities/UpdateMessageBuilder.kt
new file mode 100644
index 0000000000..bcc0d4761b
--- /dev/null
+++ b/libsession/src/main/java/org/session/libsession/messaging/utilities/UpdateMessageBuilder.kt
@@ -0,0 +1,74 @@
+package org.session.libsession.messaging.utilities
+
+import android.content.Context
+import org.session.libsession.R
+import org.session.libsession.messaging.MessagingConfiguration
+import org.session.libsignal.service.api.messages.SignalServiceGroup
+import org.session.libsignal.service.internal.push.SignalServiceProtos
+
+object UpdateMessageBuilder {
+
+ fun buildGroupUpdateMessage(context: Context, groupInfo: SignalServiceGroup, sender: String, isOutgoing: Boolean = false): String {
+ val updateType = groupInfo.type
+ val senderName: String = if (!isOutgoing) {
+ MessagingConfiguration.shared.storage.getDisplayNameForRecipient(sender) ?: sender
+ } else { sender }
+ var message: String = ""
+ when (updateType) {
+ SignalServiceGroup.Type.NEW_GROUP -> {
+ message = if (isOutgoing) {
+ context.getString(R.string.MessageRecord_you_created_a_new_group)
+ } else {
+ context.getString(R.string.MessageRecord_s_added_you_to_the_group, senderName)
+ }
+ }
+ SignalServiceGroup.Type.NAME_CHANGE -> {
+ message = if (isOutgoing) {
+ context.getString(R.string.MessageRecord_you_renamed_the_group_to_s, groupInfo.name.get())
+ } else {
+ context.getString(R.string.MessageRecord_s_renamed_the_group_to_s, senderName, groupInfo.name.get())
+ }
+ }
+ SignalServiceGroup.Type.MEMBER_ADDED -> {
+ val members = groupInfo.members.get().joinToString(", ") {
+ MessagingConfiguration.shared.storage.getDisplayNameForRecipient(it) ?: it
+ }
+ message = if (isOutgoing) {
+ context.getString(R.string.MessageRecord_you_added_s_to_the_group, members)
+ } else {
+ context.getString(R.string.MessageRecord_s_added_s_to_the_group, senderName, members)
+ }
+ }
+ SignalServiceGroup.Type.MEMBER_REMOVED -> {
+ val members = groupInfo.members.get().joinToString(", ") {
+ MessagingConfiguration.shared.storage.getDisplayNameForRecipient(it) ?: it
+ }
+ message = if (isOutgoing) {
+ context.getString(R.string.MessageRecord_you_removed_s_from_the_group, members)
+ } else {
+ context.getString(R.string.MessageRecord_s_removed_s_from_the_group, senderName, members)
+ }
+ }
+ SignalServiceGroup.Type.QUIT -> {
+ message = if (isOutgoing) {
+ context.getString(R.string.MessageRecord_left_group)
+ } else {
+ context.getString(R.string.ConversationItem_group_action_left, senderName)
+ }
+ }
+ else -> {
+ message = context.getString(R.string.MessageRecord_s_updated_group, senderName)
+ }
+ }
+ return message
+ }
+
+ fun buildExpirationTimerMessage(): String {
+ return ""
+ }
+
+ fun buildDataExtractionMessage(): String {
+ return ""
+ }
+
+}
\ No newline at end of file
diff --git a/libsession/src/main/res/values/strings.xml b/libsession/src/main/res/values/strings.xml
index 70b424bd22..ea6a33b70b 100644
--- a/libsession/src/main/res/values/strings.xml
+++ b/libsession/src/main/res/values/strings.xml
@@ -487,6 +487,14 @@
Received a message encrypted using an old version of Session that is no longer supported. Please ask the sender to update to the most recent version and resend the message.
You have left the group.
You updated the group.
+ You created a new group.
+ %1$s added you to the group.
+ You renamed the group to %1$s
+ %1$s renamed the group to: %2$s
+ You added %1$s to the group.
+ %1$s added %2$s to the group.
+ You removed %1$s from the group.
+ %1$s removed %2$s from the group.
You called
Contact called
Missed call
diff --git a/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceGroup.java b/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceGroup.java
index b503531097..68856a87cd 100644
--- a/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceGroup.java
+++ b/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceGroup.java
@@ -37,7 +37,11 @@ public class SignalServiceGroup {
UPDATE,
DELIVER,
QUIT,
- REQUEST_INFO
+ REQUEST_INFO,
+ NEW_GROUP,
+ NAME_CHANGE,
+ MEMBER_ADDED,
+ MEMBER_REMOVED
}
private final byte[] groupId;