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 82153f898c..da97321097 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -1059,7 +1059,7 @@ open class Storage @Inject constructor( } override fun insertGroupInviteControlMessage(sentTimestamp: Long, senderPublicKey: String, closedGroup: AccountId, groupName: String): Long? { - val updateData = UpdateMessageData(UpdateMessageData.Kind.GroupInvitation(senderPublicKey, groupName)) + val updateData = UpdateMessageData(UpdateMessageData.Kind.GroupInvitation(closedGroup.hexString, senderPublicKey, groupName)) return insertUpdateControlMessage(updateData, sentTimestamp, senderPublicKey, closedGroup) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java index 24580218e2..87d2ee34c4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java @@ -24,6 +24,7 @@ import android.text.style.StyleSpan; import androidx.annotation.NonNull; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.messaging.calls.CallMessageType; import org.session.libsession.messaging.sending_receiving.data_extraction.DataExtractionNotificationInfoMessage; import org.session.libsession.messaging.utilities.UpdateMessageBuilder; @@ -118,7 +119,16 @@ public abstract class MessageRecord extends DisplayRecord { public CharSequence getDisplayBody(@NonNull Context context) { if (isGroupUpdateMessage()) { UpdateMessageData updateMessageData = UpdateMessageData.Companion.fromJSON(getBody()); - return new SpannableString(UpdateMessageBuilder.INSTANCE.buildGroupUpdateMessage(context, updateMessageData, getIndividualRecipient().getAddress().serialize(), isOutgoing(), true)); + if (updateMessageData == null) { + return ""; + } + + return new SpannableString(UpdateMessageBuilder.buildGroupUpdateMessage( + context, + updateMessageData, + MessagingModuleConfiguration.getShared().getConfigFactory(), + isOutgoing()) + ); } else if (isExpirationTimerUpdate()) { int seconds = (int) (getExpiresIn() / 1000); boolean isGroup = DatabaseComponent.get(context).threadDatabase().getRecipientForThreadId(getThreadId()).isGroupRecipient(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2Impl.kt b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2Impl.kt index 513ac4525d..bb4620efa9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2Impl.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2Impl.kt @@ -556,7 +556,6 @@ class GroupManagerV2Impl @Inject constructor( val responseData = GroupUpdateMessage.newBuilder() .setInviteResponse(inviteResponse) val responseMessage = GroupUpdated(responseData.build()) - storage.clearMessages(threadId) // this will fail the first couple of times :) MessageSender.send( responseMessage, diff --git a/app/src/main/java/org/thoughtcrime/securesms/repository/ConversationRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/repository/ConversationRepository.kt index 49e8e083cc..be56c1f899 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/repository/ConversationRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/repository/ConversationRepository.kt @@ -404,11 +404,12 @@ class DefaultConversationRepository @Inject constructor( destination = Destination.from(recipient.address), isSyncMessage = recipient.isLocalNumber ).await() + + // add a control message for our user + storage.insertMessageRequestResponseFromYou(threadId) } threadDb.setHasSent(threadId, true) - // add a control message for our user - storage.insertMessageRequestResponseFromYou(threadId) } } 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 index ce3db51acb..1f49246325 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/utilities/UpdateMessageBuilder.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/utilities/UpdateMessageBuilder.kt @@ -14,6 +14,7 @@ import org.session.libsession.messaging.sending_receiving.data_extraction.DataEx import org.session.libsession.utilities.Address import org.session.libsession.messaging.sending_receiving.data_extraction.DataExtractionNotificationInfoMessage.Kind.MEDIA_SAVED import org.session.libsession.messaging.sending_receiving.data_extraction.DataExtractionNotificationInfoMessage.Kind.SCREENSHOT +import org.session.libsession.utilities.ConfigFactoryProtocol import org.session.libsession.utilities.ExpirationUtil import org.session.libsession.utilities.getExpirationTypeDisplayValue import org.session.libsession.utilities.recipients.Recipient @@ -25,6 +26,8 @@ import org.session.libsession.utilities.StringSubstitutionConstants.GROUP_NAME_K import org.session.libsession.utilities.StringSubstitutionConstants.NAME_KEY import org.session.libsession.utilities.StringSubstitutionConstants.OTHER_NAME_KEY import org.session.libsession.utilities.StringSubstitutionConstants.TIME_KEY +import org.session.libsession.utilities.getClosedGroup +import org.session.libsignal.utilities.AccountId object UpdateMessageBuilder { const val TAG = "UpdateMessageBuilder" @@ -37,7 +40,12 @@ object UpdateMessageBuilder { ?: truncateIdForDisplay(senderId) @JvmStatic - fun buildGroupUpdateMessage(context: Context, updateMessageData: UpdateMessageData, senderId: String? = null, isOutgoing: Boolean = false, isInConversation: Boolean): CharSequence { + fun buildGroupUpdateMessage( + context: Context, + updateMessageData: UpdateMessageData, + configFactory: ConfigFactoryProtocol, + isOutgoing: Boolean = false + ): CharSequence { val updateData = updateMessageData.kind ?: return "" return when (updateData) { @@ -177,31 +185,32 @@ object UpdateMessageBuilder { val userPublicKey = storage.getUserPublicKey()!! val number = updateData.sessionIds.size val containsUser = updateData.sessionIds.contains(userPublicKey) + val historyShared = updateData.historyShared when (updateData.type) { UpdateMessageData.MemberUpdateType.ADDED -> { when { number == 1 && containsUser -> Phrase.from(context, - R.string.groupInviteYou) + if (historyShared) R.string.groupInviteYouHistory else R.string.groupInviteYou) .format() number == 1 -> Phrase.from(context, - R.string.groupMemberNew) + if (historyShared) R.string.groupMemberNewHistory else R.string.groupMemberNew) .put(NAME_KEY, context.youOrSender(updateData.sessionIds.first())) .format() number == 2 && containsUser -> Phrase.from(context, - R.string.groupInviteYouAndOtherNew) + if (historyShared) R.string.groupMemberNewYouHistoryTwo else R.string.groupInviteYouAndOtherNew) .put(OTHER_NAME_KEY, context.youOrSender(updateData.sessionIds.first { it != userPublicKey })) .format() number == 2 -> Phrase.from(context, - R.string.groupMemberNewTwo) + if (historyShared) R.string.groupMemberNewHistoryTwo else R.string.groupMemberNewTwo) .put(NAME_KEY, context.youOrSender(updateData.sessionIds.first())) .put(OTHER_NAME_KEY, context.youOrSender(updateData.sessionIds.last())) .format() containsUser -> Phrase.from(context, - R.string.groupInviteYouAndMoreNew) + if (historyShared) R.string.groupMemberNewYouHistoryMultiple else R.string.groupInviteYouAndMoreNew) .put(COUNT_KEY, updateData.sessionIds.size - 1) .format() else -> Phrase.from(context, - R.string.groupMemberNewMultiple) + if (historyShared) R.string.groupMemberNewHistoryMultiple else R.string.groupMemberNewMultiple) .put(NAME_KEY, context.youOrSender(updateData.sessionIds.first())) .put(COUNT_KEY, updateData.sessionIds.size - 1) .format() @@ -272,7 +281,8 @@ object UpdateMessageBuilder { } is UpdateMessageData.Kind.GroupInvitation -> { val invitingAdmin = Recipient.from(context, Address.fromSerialized(updateData.invitingAdmin), false) - return if (invitingAdmin.name != null) { + val approved = configFactory.getClosedGroup(AccountId(updateData.groupAccountId))?.invited == false + return if (invitingAdmin.name != null && !approved) { Phrase.from(context, R.string.messageRequestGroupInvite) .put(NAME_KEY, invitingAdmin.name) .put(GROUP_NAME_KEY, updateData.groupName) diff --git a/libsession/src/main/java/org/session/libsession/messaging/utilities/UpdateMessageData.kt b/libsession/src/main/java/org/session/libsession/messaging/utilities/UpdateMessageData.kt index 0bdfeff815..7a50e4d08d 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/utilities/UpdateMessageData.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/utilities/UpdateMessageData.kt @@ -48,8 +48,13 @@ class UpdateMessageData () { class GroupMemberLeft(val updatedMembers: Collection, val groupName:String): Kind() { constructor(): this(Collections.emptyList(), "") } - class GroupMemberUpdated(val sessionIds: List, val type: MemberUpdateType?, val groupName: String): Kind() { - constructor(): this(emptyList(), null, "") + class GroupMemberUpdated( + val sessionIds: List, + val type: MemberUpdateType?, + val groupName: String, + val historyShared: Boolean + ): Kind() { + constructor(): this(emptyList(), null, "", false) } data object GroupAvatarUpdated: Kind() class GroupExpirationUpdated(val updatedExpiration: Int = 0): Kind() { @@ -60,8 +65,8 @@ class UpdateMessageData () { } data object GroupLeaving: Kind() data object GroupErrorQuit: Kind() - class GroupInvitation(val invitingAdmin: String, val groupName: String) : Kind() { - constructor(): this("", "") + class GroupInvitation(val groupAccountId: String, val invitingAdmin: String, val groupName: String) : Kind() { + constructor(): this("", "", "") } class GroupKicked(val groupName: String) : Kind() { @@ -117,7 +122,7 @@ class UpdateMessageData () { null -> null } val members = memberChange.memberSessionIdsList - UpdateMessageData(Kind.GroupMemberUpdated(members, type, groupName)) + UpdateMessageData(Kind.GroupMemberUpdated(members, type, groupName, memberChange.historyShared)) } inner.hasInfoChangeMessage() -> { val infoChange = inner.infoChangeMessage