Skip to content

Commit b28a48c

Browse files
Merge branch 'dev' into release/1.25.2
2 parents 61a99ba + 55514c3 commit b28a48c

File tree

200 files changed

+9689
-23379
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

200 files changed

+9689
-23379
lines changed

.github/workflows/build_and_test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737
with:
3838
submodules: 'recursive'
3939
- name: Set up JDK 21
40-
uses: actions/setup-java@v2
40+
uses: actions/setup-java@v4
4141
with:
4242
distribution: 'temurin'
4343
java-version: '21'

app/src/main/AndroidManifest.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO"/>
5454
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
5555
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
56+
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED"/>
5657
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
5758
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
5859
<uses-permission android:name="android.permission.RECORD_AUDIO" />
@@ -279,7 +280,6 @@
279280
<activity
280281
android:name="org.thoughtcrime.securesms.MediaPreviewActivity"
281282
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
282-
android:screenOrientation="portrait"
283283
android:theme="@style/Theme.Session.DayNight.NoActionBar"
284284
android:launchMode="singleTask"
285285
android:windowSoftInputMode="stateHidden" />
@@ -382,7 +382,7 @@
382382
android:exported="false" />
383383

384384
<provider
385-
android:name="org.thoughtcrime.securesms.providers.PartProvider"
385+
android:name="org.thoughtcrime.securesms.providers.PartAndBlobProvider"
386386
android:authorities="network.loki.provider.securesms"
387387
android:exported="false"
388388
android:grantUriPermissions="true" />

app/src/main/java/org/session/libsession/database/CallDataProvider.kt

Lines changed: 0 additions & 7 deletions
This file was deleted.

app/src/main/java/org/session/libsession/database/StorageProtocol.kt

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import org.session.libsession.messaging.jobs.Job
1111
import org.session.libsession.messaging.jobs.MessageSendJob
1212
import org.session.libsession.messaging.messages.ExpirationConfiguration
1313
import org.session.libsession.messaging.messages.Message
14-
import org.session.libsession.messaging.messages.control.ConfigurationMessage
1514
import org.session.libsession.messaging.messages.control.GroupUpdated
1615
import org.session.libsession.messaging.messages.control.MessageRequestResponse
1716
import org.session.libsession.messaging.messages.visible.Attachment
@@ -37,6 +36,7 @@ import org.session.libsignal.messages.SignalServiceGroup
3736
import org.session.libsignal.utilities.AccountId
3837
import org.thoughtcrime.securesms.database.model.MessageId
3938
import org.thoughtcrime.securesms.database.model.MessageRecord
39+
import org.thoughtcrime.securesms.database.model.ReactionRecord
4040
import network.loki.messenger.libsession_util.util.Contact as LibSessionContact
4141
import network.loki.messenger.libsession_util.util.GroupMember as LibSessionGroupMember
4242

@@ -159,16 +159,17 @@ interface StorageProtocol {
159159
// Closed Groups
160160
fun getMembers(groupPublicKey: String): List<LibSessionGroupMember>
161161
fun getClosedGroupDisplayInfo(groupAccountId: String): GroupDisplayInfo?
162-
fun insertGroupInfoChange(message: GroupUpdated, closedGroup: AccountId): Long?
163-
fun insertGroupInfoLeaving(closedGroup: AccountId): Long?
164-
fun insertGroupInfoErrorQuit(closedGroup: AccountId): Long?
162+
fun insertGroupInfoChange(message: GroupUpdated, closedGroup: AccountId)
163+
fun insertGroupInfoLeaving(closedGroup: AccountId)
164+
fun insertGroupInfoErrorQuit(closedGroup: AccountId)
165165
fun insertGroupInviteControlMessage(
166166
sentTimestamp: Long,
167167
senderPublicKey: String,
168168
senderName: String?,
169169
closedGroup: AccountId,
170170
groupName: String
171-
): Long?
171+
)
172+
172173
fun updateGroupInfoChange(messageId: Long, newType: UpdateMessageData.Kind)
173174
fun deleteGroupInfoMessages(groupId: AccountId, kind: Class<out UpdateMessageData.Kind>)
174175

@@ -208,7 +209,6 @@ interface StorageProtocol {
208209
fun getRecipientSettings(address: Address): RecipientSettings?
209210
fun syncLibSessionContacts(contacts: List<LibSessionContact>, timestamp: Long?)
210211
fun hasAutoDownloadFlagBeenSet(recipient: Recipient): Boolean
211-
fun addContacts(contacts: List<ConfigurationMessage.Contact>)
212212
fun shouldAutoDownloadAttachments(recipient: Recipient): Boolean
213213
fun setAutoDownloadAttachments(recipient: Recipient, shouldAutoDownloadAttachments: Boolean)
214214

@@ -259,12 +259,17 @@ interface StorageProtocol {
259259
* Add reaction to a specific message. This is preferable to the timestamp lookup.
260260
*/
261261
fun addReaction(messageId: MessageId, reaction: Reaction, messageSender: String, notifyUnread: Boolean)
262+
263+
/**
264+
* Add reactions into the database. If [replaceAll] is true,
265+
* it will remove all existing reactions that belongs to the same message(s).
266+
*/
267+
fun addReactions(reactions: Map<MessageId, List<ReactionRecord>>, replaceAll: Boolean, notifyUnread: Boolean)
262268
fun removeReaction(emoji: String, messageTimestamp: Long, threadId: Long, author: String, notifyUnread: Boolean)
263269
fun updateReactionIfNeeded(message: Message, sender: String, openGroupSentTimestamp: Long)
264270
fun deleteReactions(messageId: MessageId)
265271
fun deleteReactions(messageIds: List<Long>, mms: Boolean)
266272
fun setBlocked(recipients: Iterable<Recipient>, isBlocked: Boolean, fromConfigUpdate: Boolean = false)
267-
fun setRecipientHash(recipient: Recipient, recipientHash: String?)
268273
fun blockedContacts(): List<Recipient>
269274
fun getExpirationConfiguration(threadId: Long): ExpirationConfiguration?
270275
fun setExpirationConfiguration(config: ExpirationConfiguration)

app/src/main/java/org/session/libsession/messaging/MessagingModuleConfiguration.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import org.session.libsession.utilities.Device
1212
import org.session.libsession.utilities.TextSecurePreferences
1313
import org.session.libsession.utilities.Toaster
1414
import org.session.libsession.utilities.UsernameUtils
15+
import org.thoughtcrime.securesms.pro.ProStatusManager
1516

1617
class MessagingModuleConfiguration(
1718
val context: Context,
@@ -25,7 +26,8 @@ class MessagingModuleConfiguration(
2526
val clock: SnodeClock,
2627
val preferences: TextSecurePreferences,
2728
val deprecationManager: LegacyGroupDeprecationManager,
28-
val usernameUtils: UsernameUtils
29+
val usernameUtils: UsernameUtils,
30+
val proStatusManager: ProStatusManager
2931
) {
3032

3133
companion object {

app/src/main/java/org/session/libsession/messaging/jobs/BatchMessageReceiveJob.kt

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,38 +6,34 @@ import kotlinx.coroutines.async
66
import kotlinx.coroutines.awaitAll
77
import kotlinx.coroutines.coroutineScope
88
import network.loki.messenger.libsession_util.ConfigBase
9-
import network.loki.messenger.libsession_util.util.BlindKeyAPI
109
import org.session.libsession.messaging.MessagingModuleConfiguration
1110
import org.session.libsession.messaging.messages.Destination
1211
import org.session.libsession.messaging.messages.Message
1312
import org.session.libsession.messaging.messages.Message.Companion.senderOrSync
1413
import org.session.libsession.messaging.messages.control.CallMessage
15-
import org.session.libsession.messaging.messages.control.LegacyGroupControlMessage
16-
import org.session.libsession.messaging.messages.control.ConfigurationMessage
1714
import org.session.libsession.messaging.messages.control.DataExtractionNotification
1815
import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate
1916
import org.session.libsession.messaging.messages.control.MessageRequestResponse
2017
import org.session.libsession.messaging.messages.control.ReadReceipt
21-
import org.session.libsession.messaging.messages.control.SharedConfigurationMessage
2218
import org.session.libsession.messaging.messages.control.TypingIndicator
2319
import org.session.libsession.messaging.messages.control.UnsendRequest
2420
import org.session.libsession.messaging.messages.visible.ParsedMessage
2521
import org.session.libsession.messaging.messages.visible.VisibleMessage
2622
import org.session.libsession.messaging.open_groups.OpenGroupApi
2723
import org.session.libsession.messaging.sending_receiving.MessageReceiver
24+
import org.session.libsession.messaging.sending_receiving.VisibleMessageHandlerContext
25+
import org.session.libsession.messaging.sending_receiving.constructReactionRecords
2826
import org.session.libsession.messaging.sending_receiving.handle
29-
import org.session.libsession.messaging.sending_receiving.handleOpenGroupReactions
3027
import org.session.libsession.messaging.sending_receiving.handleUnsendRequest
3128
import org.session.libsession.messaging.sending_receiving.handleVisibleMessage
3229
import org.session.libsession.messaging.utilities.Data
3330
import org.session.libsession.utilities.SSKEnvironment
3431
import org.session.libsession.utilities.UserConfigType
3532
import org.session.libsignal.protos.UtilProtos
3633
import org.session.libsignal.utilities.AccountId
37-
import org.session.libsignal.utilities.Hex
38-
import org.session.libsignal.utilities.IdPrefix
3934
import org.session.libsignal.utilities.Log
4035
import org.thoughtcrime.securesms.database.model.MessageId
36+
import org.thoughtcrime.securesms.database.model.ReactionRecord
4137
import kotlin.math.max
4238

4339
data class MessageReceiveParameters(
@@ -83,12 +79,9 @@ class BatchMessageReceiveJob(
8379
if (message is VisibleMessage) return true
8480
else { // message is control message otherwise
8581
return when(message) {
86-
is SharedConfigurationMessage -> false
87-
is LegacyGroupControlMessage -> false // message.kind is ClosedGroupControlMessage.Kind.New && !message.isSenderSelf
8882
is DataExtractionNotification -> false
8983
is MessageRequestResponse -> false
9084
is ExpirationTimerUpdate -> false
91-
is ConfigurationMessage -> false
9285
is TypingIndicator -> false
9386
is UnsendRequest -> false
9487
is ReadReceipt -> false
@@ -175,45 +168,51 @@ class BatchMessageReceiveJob(
175168
}
176169

177170
// iterate over threads and persist them (persistence is the longest constant in the batch process operation)
178-
fun processMessages(threadId: Long, messages: List<ParsedMessage>) {
171+
suspend fun processMessages(threadId: Long, messages: List<ParsedMessage>) {
179172
// The LinkedHashMap should preserve insertion order
180173
val messageIds = linkedMapOf<MessageId, Pair<Boolean, Boolean>>()
181174
val myLastSeen = storage.getLastSeen(threadId)
182-
var newLastSeen = myLastSeen.takeUnless { it == -1L } ?: 0
175+
var updatedLastSeen = myLastSeen.takeUnless { it == -1L } ?: 0
176+
val handlerContext = VisibleMessageHandlerContext(
177+
module = MessagingModuleConfiguration.shared,
178+
threadId = threadId,
179+
openGroupID = openGroupID,
180+
)
181+
182+
val communityReactions = mutableMapOf<MessageId, MutableList<ReactionRecord>>()
183+
183184
messages.forEach { (parameters, message, proto) ->
184185
try {
185186
when (message) {
186187
is VisibleMessage -> {
187188
val isUserBlindedSender =
188-
message.sender == serverPublicKey?.let {
189-
BlindKeyAPI.blind15KeyPairOrNull(
190-
ed25519SecretKey = storage.getUserED25519KeyPair()!!
191-
.secretKey.data,
192-
serverPubKey = Hex.fromStringCondensed(it),
193-
)
194-
}?.let {
195-
AccountId(IdPrefix.BLINDED, it.pubKey.data).hexString
196-
}
189+
message.sender == handlerContext.userBlindedKey
190+
197191
if (message.sender == localUserPublicKey || isUserBlindedSender) {
198192
// use sent timestamp here since that is technically the last one we have
199-
newLastSeen = max(newLastSeen, message.sentTimestamp!!)
193+
updatedLastSeen = max(updatedLastSeen, message.sentTimestamp!!)
200194
}
201-
val messageId = MessageReceiver.handleVisibleMessage(message, proto, openGroupID,
202-
threadId,
195+
val messageId = MessageReceiver.handleVisibleMessage(
196+
message = message,
197+
proto = proto,
198+
context = handlerContext,
203199
runThreadUpdate = false,
204-
runProfileUpdate = true)
200+
runProfileUpdate = true
201+
)
205202

206203
if (messageId != null && message.reaction == null) {
207204
messageIds[messageId] = Pair(
208205
(message.sender == localUserPublicKey || isUserBlindedSender),
209206
message.hasMention
210207
)
211208
}
209+
212210
parameters.openGroupMessageServerID?.let {
213-
MessageReceiver.handleOpenGroupReactions(
214-
threadId,
215-
it,
216-
parameters.reactions
211+
constructReactionRecords(
212+
openGroupMessageServerID = it,
213+
context = handlerContext,
214+
reactions = parameters.reactions,
215+
out = communityReactions
217216
)
218217
}
219218
}
@@ -248,13 +247,20 @@ class BatchMessageReceiveJob(
248247
// increment unreads, notify, and update thread
249248
// last seen will be the current last seen if not changed (re-computes the read counts for thread record)
250249
// might have been updated from a different thread at this point
251-
val currentLastSeen = storage.getLastSeen(threadId).let { if (it == -1L) 0 else it }
252-
newLastSeen = max(newLastSeen, currentLastSeen)
253-
if (newLastSeen > 0 || currentLastSeen == 0L) {
254-
storage.markConversationAsRead(threadId, newLastSeen, force = true)
250+
val storedLastSeen = storage.getLastSeen(threadId).let { if (it == -1L) 0 else it }
251+
updatedLastSeen = max(updatedLastSeen, storedLastSeen)
252+
// Only call markConversationAsRead() when lastSeen actually advanced (we sent a message).
253+
// For incoming-only batches (like reactions), skip this to preserve REACTIONS_UNREAD flags
254+
// so the notification system can detect them. Thread updates happen separately below.
255+
if (updatedLastSeen > storedLastSeen) {
256+
storage.markConversationAsRead(threadId, updatedLastSeen, force = true)
255257
}
256258
storage.updateThread(threadId, true)
257259
SSKEnvironment.shared.notificationManager.updateNotification(context, threadId)
260+
261+
if (communityReactions.isNotEmpty()) {
262+
storage.addReactions(communityReactions, replaceAll = true, notifyUnread = false)
263+
}
258264
}
259265

260266
coroutineScope {

app/src/main/java/org/session/libsession/messaging/jobs/GroupLeavingJob.kt

Lines changed: 0 additions & 103 deletions
This file was deleted.

0 commit comments

Comments
 (0)