Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
983cfdd
Remove unused code
SessionHero01 Dec 11, 2025
3c38859
Merge remote-tracking branch 'origin/dev' into tidy-up-threads
SessionHero01 Dec 11, 2025
116aa5e
WIP
SessionHero01 Dec 12, 2025
532ac54
Handling mark read automatically
SessionHero01 Dec 15, 2025
cbe2cb2
Optimize
SessionHero01 Dec 15, 2025
f96e604
Merge branch 'dev' into tidy-up-threads
SessionHero01 Dec 15, 2025
764deff
Remove debug code
SessionHero01 Dec 15, 2025
d4ab425
Merge remote-tracking branch 'origin/tidy-up-threads' into tidy-up-th…
SessionHero01 Dec 15, 2025
0d19fce
Fixed test issues
SessionHero01 Dec 15, 2025
e4de84d
Merge remote-tracking branch 'origin/dev' into tidy-up-threads
simophin Dec 16, 2025
d98e29d
Merge remote-tracking branch 'origin/dev' into tidy-up-threads
simophin Dec 16, 2025
82ad649
Merge issues
simophin Dec 16, 2025
ebce4f0
Merge remote-tracking branch 'origin/dev' into tidy-up-threads
SessionHero01 Dec 16, 2025
49588fa
Fixed tests and added comments
SessionHero01 Dec 16, 2025
3ae46eb
Merge remote-tracking branch 'origin/dev' into tidy-up-threads
SessionHero01 Dec 17, 2025
0bf3a06
Add missing place to notify thread updated
SessionHero01 Dec 17, 2025
f07c53b
Tidy up
SessionHero01 Dec 17, 2025
50d4bd0
Fixed missing thread notification
SessionHero01 Dec 17, 2025
f1122d0
Optimise thread query
SessionHero01 Jan 4, 2026
bfc05fb
Merge remote-tracking branch 'origin/dev' into tidy-up-threads
SessionHero01 Jan 6, 2026
bcc68ee
Merge remote-tracking branch 'origin/dev' into tidy-up-threads
SessionHero01 Jan 7, 2026
baf4062
Merge remote-tracking branch 'origin/dev' into tidy-up-threads
SessionHero01 Jan 8, 2026
96e6906
New implementation of getUnreadCount based on last read
SessionHero01 Jan 8, 2026
3d2ee30
Fixes deadlock
SessionHero01 Jan 8, 2026
e854ac9
Merge remote-tracking branch 'origin/dev' into tidy-up-threads
SessionHero01 Feb 18, 2026
2a01c5b
Fix compile errors after merge
SessionHero01 Feb 18, 2026
aec374c
PR feedback
SessionHero01 Feb 18, 2026
7eca292
Merge branch 'dev' into tidy-up-threads
SessionHero01 Feb 19, 2026
7ba59d8
Config sync
SessionHero01 Feb 19, 2026
449c6c8
Merge remote-tracking branch 'origin/dev' into tidy-up-threads
SessionHero01 Feb 19, 2026
3cb0123
Db based last seen
SessionHero01 Feb 20, 2026
ea87cf9
Merge remote-tracking branch 'origin/dev' into tidy-up-threads
SessionHero01 Feb 23, 2026
1e82daa
Mark read WIP
SessionHero01 Feb 24, 2026
b82075a
Merge remote-tracking branch 'origin/dev' into tidy-up-threads
SessionHero01 Feb 24, 2026
abfd495
Merge remote-tracking branch 'origin/dev' into tidy-up-threads
SessionHero01 Feb 24, 2026
ed3a0a3
Thread mark read WIP
SessionHero01 Feb 24, 2026
a73bf8e
Merge remote-tracking branch 'origin/dev' into tidy-up-threads
SessionHero01 Feb 25, 2026
0194039
Message notification optimization
SessionHero01 Feb 26, 2026
41cea90
Mark read processor
SessionHero01 Feb 27, 2026
ab2b4b2
Tidy up
SessionHero01 Feb 27, 2026
c46ec41
Tidy up
SessionHero01 Feb 27, 2026
29ca0a9
Tidy up
SessionHero01 Feb 27, 2026
6a35aa4
Shorten TTL
SessionHero01 Feb 28, 2026
4a4d5fd
Merge remote-tracking branch 'origin/dev' into tidy-up-threads
SessionHero01 Mar 1, 2026
4cd341a
Renamed
SessionHero01 Mar 1, 2026
931d861
Import
SessionHero01 Mar 1, 2026
736f773
Fixed tests
SessionHero01 Mar 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -141,14 +141,12 @@ interface StorageProtocol {
fun getOrCreateThreadIdFor(address: Address): Long
fun getThreadId(address: Address): Long?
fun getThreadIdForMms(mmsId: Long): Long
fun getLastUpdated(threadID: Long): Long
fun trimThreadBefore(threadID: Long, timestamp: Long)
fun getMessageCount(threadID: Long): Long
fun getTotalPinned(): Int
suspend fun getTotalSentProBadges(): Int
suspend fun getTotalSentLongMessages(): Int
fun setPinned(address: Address, isPinned: Boolean)
fun isRead(threadId: Long) : Boolean
fun setThreadCreationDate(threadId: Long, newDate: Long)
fun getLastLegacyRecipient(threadRecipient: String): String?
fun setLastLegacyRecipient(threadRecipient: String, senderRecipient: String?)
Expand All @@ -175,7 +173,9 @@ interface StorageProtocol {
attachments: List<Attachment>,
runThreadUpdate: Boolean
): MessageId?
fun markConversationAsRead(threadId: Long, lastSeenTime: Long, force: Boolean = false, updateNotification: Boolean = true)

fun updateConversationLastSeenIfNeeded(threadAddress: Address.Conversable, lastSeenTime: Long)
fun updateConversationLastSeenIfNeeded(threadId: Long, lastSeenTime: Long)

/**
* Marks the conversation as read up to and including the message with [messageId]. It will
Expand All @@ -185,13 +185,11 @@ interface StorageProtocol {
*/
fun markConversationAsReadUpToMessage(messageId: MessageId)
fun markConversationAsUnread(threadId: Long)
fun getLastSeen(threadId: Long): Long
fun getLastSeen(threadAddress: Address.Conversable): Long?
fun ensureMessageHashesAreSender(hashes: Set<String>, sender: String, closedGroupId: String): Boolean
fun updateThread(threadId: Long, unarchive: Boolean)
fun insertDataExtractionNotificationMessage(senderPublicKey: String, message: DataExtractionNotificationInfoMessage, sentTimestamp: Long)
fun insertMessageRequestResponseFromYou(threadId: Long)
fun insertCallMessage(senderPublicKey: String, callMessageType: CallMessageType, sentTimestamp: Long, expiryMode: ExpiryMode)
fun conversationHasOutgoing(userPublicKey: String): Boolean
fun deleteMessagesByHash(threadId: Long, hashes: List<String>)
fun deleteMessagesByUser(threadId: Long, userSessionId: String)
fun clearAllMessages(threadId: Long): List<String?>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@ data class ExpirationConfiguration(
val expiryMode: ExpiryMode = ExpiryMode.NONE,
val updatedTimestampMs: Long = 0
) {
val isEnabled = expiryMode.expirySeconds > 0

companion object {
val isNewConfigEnabled = true
}
val isEnabled get() = expiryMode.expirySeconds > 0
}

data class ExpirationDatabaseMetadata(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@ package org.session.libsession.messaging.open_groups
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import network.loki.messenger.libsession_util.util.BaseCommunityInfo
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import org.session.libsession.messaging.open_groups.OpenGroup.Companion.toAddress
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.GroupUtil

@Deprecated("This class is no longer used except in migration. Use RoomInfo instead")
@Serializable
Expand All @@ -27,20 +23,15 @@ data class OpenGroup(
val id: String get() = groupId

companion object {

/**
* Returns the group ID for this community info. The group ID is the session android unique
* way of identifying a community. It itself isn't super useful but it's used to construct
* the [Address] for communities.
*
* See [toAddress]
*/
val BaseCommunityInfo.groupId: String
get() = "${baseUrl}.${room}"

fun BaseCommunityInfo.toAddress(): Address {
return Address.fromSerialized(GroupUtil.getEncodedOpenGroupID(groupId.toByteArray()))
}
}

val groupId: String get() = "$server.$room"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,6 @@ class MessageRequestResponseHandler @Inject constructor(
dataExtractionNotification = null
),
threadId,
runThreadUpdate = true,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,18 +107,12 @@ class ReceivedMessageProcessor @Inject constructor(
try {
return block(context)
} finally {
for (threadId in context.threadIDs.values) {
if (context.maxOutgoingMessageTimestamp > 0L &&
context.maxOutgoingMessageTimestamp > storage.getLastSeen(threadId)
) {
storage.markConversationAsRead(
threadId,
context.maxOutgoingMessageTimestamp,
force = true
)
}
for ((threadAddress, threadId) in context.threadIDs) {
storage.updateConversationLastSeenIfNeeded(
threadAddress = threadAddress,
context.maxOutgoingMessageTimestamp,
)

storage.updateThread(threadId, true)
notificationManager.updateNotification(this.context, threadId)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import network.loki.messenger.libsession_util.protocol.ProFeature
import network.loki.messenger.libsession_util.protocol.ProMessageFeature
import network.loki.messenger.libsession_util.protocol.ProProfileFeature
import network.loki.messenger.libsession_util.util.toBitSet
import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.file_server.FileServer
import org.session.libsession.utilities.TextSecurePreferences.Companion.AUTOPLAY_AUDIO_MESSAGES
import org.session.libsession.utilities.TextSecurePreferences.Companion.CALL_NOTIFICATIONS_ENABLED
Expand Down Expand Up @@ -102,8 +101,6 @@ interface TextSecurePreferences {
fun getNeedsSqlCipherMigration(): Boolean
fun isIncognitoKeyboardEnabled(): Boolean
fun setIncognitoKeyboardEnabled(enabled : Boolean)
fun isReadReceiptsEnabled(): Boolean
fun setReadReceiptsEnabled(enabled: Boolean)
fun isTypingIndicatorsEnabled(): Boolean
fun setTypingIndicatorsEnabled(enabled: Boolean)
fun isLinkPreviewsEnabled(): Boolean
Expand Down Expand Up @@ -265,8 +262,6 @@ interface TextSecurePreferences {
var migratedToGroupV2Config: Boolean
var migratedToDisablingKDF: Boolean

var migratedDisappearingMessagesToMessageContent: Boolean

var selectedActivityAliasName: String?

var inAppReviewState: String?
Expand Down Expand Up @@ -305,7 +300,6 @@ interface TextSecurePreferences {
const val REPEAT_ALERTS_PREF = "pref_repeat_alerts"
const val NOTIFICATION_PRIVACY_PREF = "pref_notification_privacy"
const val DIRECT_CAPTURE_CAMERA_ID = "pref_direct_capture_camera_id"
const val READ_RECEIPTS_PREF = "pref_read_receipts"
const val INCOGNITO_KEYBOARD_PREF = "pref_incognito_keyboard"
const val NEEDS_SQLCIPHER_MIGRATION = "pref_needs_sql_cipher_migration"
const val BACKUP_ENABLED = "pref_backup_enabled_v3"
Expand Down Expand Up @@ -451,11 +445,6 @@ interface TextSecurePreferences {
return getBooleanPreference(context, INCOGNITO_KEYBOARD_PREF, true)
}

@JvmStatic
fun isReadReceiptsEnabled(context: Context): Boolean {
return getBooleanPreference(context, READ_RECEIPTS_PREF, false)
}

@JvmStatic
fun isGifSearchInGridLayout(context: Context): Boolean {
return getBooleanPreference(context, GIF_GRID_LAYOUT, false)
Expand Down Expand Up @@ -673,10 +662,6 @@ class AppTextSecurePreferences @Inject constructor(
putBoolean(TextSecurePreferences.MIGRATED_TO_DISABLING_KDF, value)
}

override var migratedDisappearingMessagesToMessageContent: Boolean
get() = getBooleanPreference("migrated_disappearing_messages_to_message_content", false)
set(value) = setBooleanPreference("migrated_disappearing_messages_to_message_content", value)

override fun getConfigurationMessageSynced(): Boolean {
return getBooleanPreference(TextSecurePreferences.CONFIGURATION_SYNCED, false)
}
Expand Down Expand Up @@ -771,15 +756,6 @@ class AppTextSecurePreferences @Inject constructor(
_events.tryEmit(TextSecurePreferences.INCOGNITO_KEYBOARD_PREF)
}

override fun isReadReceiptsEnabled(): Boolean {
return getBooleanPreference(TextSecurePreferences.READ_RECEIPTS_PREF, false)
}

override fun setReadReceiptsEnabled(enabled: Boolean) {
setBooleanPreference(TextSecurePreferences.READ_RECEIPTS_PREF, enabled)
_events.tryEmit(TextSecurePreferences.READ_RECEIPTS_PREF)
}

override fun isTypingIndicatorsEnabled(): Boolean {
return getBooleanPreference(TextSecurePreferences.TYPING_INDICATORS, false)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import okhttp3.HttpUrl.Companion.toHttpUrl
import org.session.libsession.messaging.open_groups.GroupMemberRole
import org.session.libsession.messaging.open_groups.OpenGroupApi
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.recipients.RemoteFile.Companion.toRemoteFile
import org.session.libsignal.utilities.AccountId
import org.thoughtcrime.securesms.util.DateUtils.Companion.secondsToInstant
import java.time.Instant

/**
Expand Down Expand Up @@ -134,17 +136,24 @@ sealed interface RecipientData {
* A recipient that was saved in your contact config.
*/
data class Contact(
val name: String,
val nickname: String?,
override val avatar: RemoteFile.Encrypted?,
val approved: Boolean,
val approvedMe: Boolean,
val blocked: Boolean,
val expiryMode: ExpiryMode,
override val priority: Long,
private val configData: network.loki.messenger.libsession_util.util.Contact,
override val proData: ProData?,
override val profileUpdatedAt: Instant?,
) : RecipientData {
val name: String get() = configData.name
val nickname: String? get() = configData.nickname.takeIf { it.isNotBlank() }
val approved: Boolean get() = configData.approved
val approvedMe: Boolean get() = configData.approvedMe
val blocked: Boolean get() = configData.blocked
val createdAt: Instant get() = Instant.ofEpochSecond(configData.createdEpochSeconds)
override val priority: Long get() = configData.priority
override val profileUpdatedAt: Instant? get() = configData.profileUpdatedEpochSeconds
.secondsToInstant()

val expiryMode: ExpiryMode get() = configData.expiryMode

override val avatar: RemoteFile?
get() = configData.profilePicture.toRemoteFile()

val displayName: String
get() = nickname?.takeIf { it.isNotBlank() } ?: name

Expand Down Expand Up @@ -186,6 +195,7 @@ sealed interface RecipientData {
val destroyed: Boolean get() = groupInfo.destroyed
val shouldPoll: Boolean get() = groupInfo.shouldPoll
override val proData: ProData? get() = null //todo LARGE GROUP hiding group pro status until we enable large groups
val joinedAt: Instant get() = Instant.ofEpochSecond(groupInfo.joinedAtSecs)

override val profileUpdatedAt: Instant?
get() = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import org.thoughtcrime.securesms.groups.handler.CleanupInvitationHandler
import org.thoughtcrime.securesms.groups.handler.DestroyedGroupSync
import org.thoughtcrime.securesms.groups.handler.RemoveGroupMemberHandler
import org.thoughtcrime.securesms.notifications.BackgroundPollManager
import org.thoughtcrime.securesms.notifications.MarkReadProcessor
import org.thoughtcrime.securesms.notifications.PushRegistrationHandler
import org.thoughtcrime.securesms.pro.ProStatusManager
import org.thoughtcrime.securesms.service.ExpiringMessageManager
Expand Down Expand Up @@ -42,6 +43,7 @@ class AuthAwareComponents(
proStatusManager: Lazy<ProStatusManager>,
pollerManager: Lazy<PollerManager>,
backgroundPollManager: Lazy<BackgroundPollManager>,
markReadProcessor: Lazy<MarkReadProcessor>,
versionDataFetcher: Lazy<VersionDataFetcher>,
): this(
components = listOf<Lazy<out AuthAwareComponent>>(
Expand All @@ -59,6 +61,7 @@ class AuthAwareComponents(
pollerManager,
backgroundPollManager,
versionDataFetcher,
markReadProcessor,
)
)
}
Loading