Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -142,14 +142,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 @@ -176,7 +174,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 @@ -186,13 +186,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)
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 @@ -102,19 +102,14 @@ 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)
threadDatabase.notifyThreadUpdated(threadId)
}

// Handle pending community reactions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import android.provider.Settings
import androidx.annotation.ArrayRes
import androidx.annotation.StyleRes
import androidx.camera.core.CameraSelector
import androidx.core.app.NotificationCompat
import androidx.core.content.edit
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import dagger.hilt.android.qualifiers.ApplicationContext
Expand Down Expand Up @@ -263,8 +262,6 @@ interface TextSecurePreferences {
var migratedToDisablingKDF: Boolean
var migratedToMultiPartConfig: Boolean

var migratedDisappearingMessagesToMessageContent: Boolean

var selectedActivityAliasName: String?

var inAppReviewState: String?
Expand Down Expand Up @@ -1037,10 +1034,6 @@ class AppTextSecurePreferences @Inject constructor(
get() = getBooleanPreference(TextSecurePreferences.MIGRATED_TO_MULTIPART_CONFIG, false)
set(value) = setBooleanPreference(TextSecurePreferences.MIGRATED_TO_MULTIPART_CONFIG, 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
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 kicked: Boolean get() = groupInfo.kicked
val destroyed: Boolean get() = groupInfo.destroyed
val shouldPoll: Boolean get() = groupInfo.shouldPoll
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 @@ -41,6 +42,7 @@ class AuthAwareComponents(
proStatusManager: Lazy<ProStatusManager>,
pollerManager: Lazy<PollerManager>,
backgroundPollManager: Lazy<BackgroundPollManager>,
markReadProcessor: Lazy<MarkReadProcessor>,
): this(
components = listOf<Lazy<out AuthAwareComponent>>(
expiringMessageManager,
Expand All @@ -56,6 +58,7 @@ class AuthAwareComponents(
proStatusManager,
pollerManager,
backgroundPollManager,
markReadProcessor,
)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,9 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
import network.loki.messenger.R
import network.loki.messenger.libsession_util.ReadableGroupInfoConfig
import network.loki.messenger.libsession_util.util.Conversation
import network.loki.messenger.libsession_util.util.UserPic
import org.session.libsession.avatars.AvatarCacheCleaner
import org.session.libsession.database.StorageProtocol
Expand Down Expand Up @@ -56,8 +51,6 @@ import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.dependencies.ManagerScope
import org.thoughtcrime.securesms.repository.ConversationRepository
import org.thoughtcrime.securesms.util.SessionMetaProtocol
import org.thoughtcrime.securesms.util.castAwayType
import java.util.EnumSet
import java.util.concurrent.TimeUnit
import javax.inject.Inject

Expand Down Expand Up @@ -92,18 +85,10 @@ class ConfigToDatabaseSync @Inject constructor(
@param:ManagerScope private val scope: CoroutineScope,
) : AuthAwareComponent {
override suspend fun doWhileLoggedIn(loggedInState: LoggedInState) {
combine(
conversationRepository.conversationListAddressesFlow,
configFactory.userConfigsChanged(EnumSet.of(UserConfigType.CONVO_INFO_VOLATILE))
.castAwayType()
.onStart { emit(Unit) }
.map { _ -> configFactory.withUserConfigs { it.convoInfoVolatile.all() } },
::Pair
).distinctUntilChanged()
.collectLatest { (conversations, convoInfo) ->
conversationRepository.conversationListAddressesFlow
.collectLatest { conversations ->
try {
ensureConversations(conversations, loggedInState.accountId)
updateConvoVolatile(convoInfo)
} catch (e: Exception) {
Log.e(TAG, "Error updating conversations from config", e)
}
Expand Down Expand Up @@ -337,32 +322,4 @@ class ConfigToDatabaseSync @Inject constructor(
private val MmsMessageRecord.containsAttachment: Boolean
get() = this.slideDeck.slides.isNotEmpty() && !this.slideDeck.isVoiceNote


private fun updateConvoVolatile(convos: List<Conversation?>) {
for (conversation in convos.asSequence().filterNotNull()) {
val address: Address.Conversable = when (conversation) {
is Conversation.OneToOne -> Address.Standard(AccountId(conversation.accountId))
is Conversation.LegacyGroup -> Address.LegacyGroup(conversation.groupId)
is Conversation.Community -> Address.Community(serverUrl = conversation.baseCommunityInfo.baseUrl, room = conversation.baseCommunityInfo.room)
is Conversation.ClosedGroup -> Address.Group(AccountId(conversation.accountId)) // New groups will be managed bia libsession
is Conversation.BlindedOneToOne -> {
// Not supported yet
continue
}
}

val threadId = threadDatabase.getThreadIdIfExistsFor(address)

if (threadId != -1L) {
if (conversation.lastRead > storage.getLastSeen(threadId)) {
storage.markConversationAsRead(
threadId,
conversation.lastRead,
force = true
)
storage.updateThread(threadId, false)
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import org.thoughtcrime.securesms.ui.UINavigator
@HiltViewModel(assistedFactory = DisappearingMessagesViewModel.Factory::class)
class DisappearingMessagesViewModel @AssistedInject constructor(
@Assisted private val address: Address,
@Assisted("isNewConfigEnabled") private val isNewConfigEnabled: Boolean,
@Assisted("showDebugOptions") private val showDebugOptions: Boolean,
@Assisted private val navigator: UINavigator<ConversationSettingsDestination>,
@param:ApplicationContext private val context: Context,
Expand All @@ -39,7 +38,7 @@ class DisappearingMessagesViewModel @AssistedInject constructor(

private val _state = MutableStateFlow(
State(
isNewConfigEnabled = isNewConfigEnabled,
isNewConfigEnabled = true,
showDebugOptions = showDebugOptions
)
)
Expand Down Expand Up @@ -95,7 +94,6 @@ class DisappearingMessagesViewModel @AssistedInject constructor(
interface Factory {
fun create(
address: Address,
@Assisted("isNewConfigEnabled") isNewConfigEnabled: Boolean,
@Assisted("showDebugOptions") showDebugOptions: Boolean,
navigator: UINavigator<ConversationSettingsDestination>
): DisappearingMessagesViewModel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ import network.loki.messenger.databinding.ActivityConversationV2Binding
import network.loki.messenger.libsession_util.util.ExpiryMode
import org.session.libsession.database.StorageProtocol
import org.session.libsession.messaging.groups.GroupManagerV2
import org.session.libsession.messaging.messages.ExpirationConfiguration
import org.session.libsession.messaging.messages.applyExpiryMode
import org.session.libsession.messaging.messages.control.DataExtractionNotification
import org.session.libsession.messaging.messages.signal.OutgoingMediaMessage
Expand Down Expand Up @@ -210,7 +209,6 @@ import org.thoughtcrime.securesms.util.adapter.runWhenLaidOut
import org.thoughtcrime.securesms.util.drawToBitmap
import org.thoughtcrime.securesms.util.fadeIn
import org.thoughtcrime.securesms.util.fadeOut
import org.thoughtcrime.securesms.util.getConversationUnread
import org.thoughtcrime.securesms.util.isFullyScrolled
import org.thoughtcrime.securesms.util.isNearBottom
import org.thoughtcrime.securesms.util.push
Expand Down Expand Up @@ -376,7 +374,7 @@ class ConversationActivityV2 : ScreenLockActionBarActivity(), InputBarDelegate,
private val adapter by lazy {
val adapter = ConversationAdapter(
this,
storage.getLastSeen(viewModel.threadId),
storage.getLastSeen(viewModel.address),
false,
onItemPress = { message, position, view, event ->
handlePress(message, position, view, event)
Expand Down Expand Up @@ -634,9 +632,10 @@ class ConversationActivityV2 : ScreenLockActionBarActivity(), InputBarDelegate,
try {
when (it) {
is Long -> {
if (storage.getLastSeen(viewModel.threadId) < it) {
storage.markConversationAsRead(viewModel.threadId, it)
}
storage.updateConversationLastSeenIfNeeded(
viewModel.address,
it
)
}

is MessageId -> {
Expand Down Expand Up @@ -827,24 +826,6 @@ class ConversationActivityV2 : ScreenLockActionBarActivity(), InputBarDelegate,
} else {
if (firstLoad.getAndSet(false)) {
scrollToFirstUnreadMessageOrBottom()

// On the first load, check if there unread messages
if (unreadCount == 0 && adapter.itemCount > 0) {
lifecycleScope.launch(Dispatchers.Default) {
val isUnread = configFactory.withUserConfigs {
it.convoInfoVolatile.getConversationUnread(
viewModel.address,
)
}

if (isUnread) {
storage.markConversationAsRead(
viewModel.threadId,
clock.currentTimeMills()
)
}
}
}
} else {
// If there are new data updated, we'll try to stay scrolled at the bottom (if we were at the bottom).
// scrolled to bottom has a leniency of 50dp, so if we are within the 50dp but not fully at the bottom, scroll down
Expand Down Expand Up @@ -1050,8 +1031,7 @@ class ConversationActivityV2 : ScreenLockActionBarActivity(), InputBarDelegate,
private fun setUpOutdatedClientBanner() {
val legacyRecipient = viewModel.legacyBannerRecipient(this)

val shouldShowLegacy = ExpirationConfiguration.isNewConfigEnabled &&
legacyRecipient != null
val shouldShowLegacy = legacyRecipient != null

binding.conversationHeader.outdatedDisappearingBanner.isVisible = shouldShowLegacy
if (shouldShowLegacy) {
Expand Down Expand Up @@ -1245,7 +1225,7 @@ class ConversationActivityV2 : ScreenLockActionBarActivity(), InputBarDelegate,
return
}

val lastSeenTimestamp = threadDb.getLastSeenAndHasSent(viewModel.threadId).first()
val lastSeenTimestamp = storage.getLastSeen(viewModel.address)
val lastSeenItemPosition = adapter.findLastSeenItemPosition(lastSeenTimestamp) ?: return

binding.conversationRecyclerView.runWhenLaidOut {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,7 @@ class ControlMessageView : LinearLayout {
expirationTimerView.setExpirationTime(message.expireStarted, message.expiresIn)
}

followSetting.isVisible = ExpirationConfiguration.isNewConfigEnabled
&& !message.isOutgoing
followSetting.isVisible = !message.isOutgoing
&& messageContent.expiryMode != (message.individualRecipient?.expiryMode ?: ExpiryMode.NONE)
&& !threadRecipient.isGroupOrCommunityRecipient

Expand Down
Loading