Fix expiry timer update handling

This commit is contained in:
charles 2022-12-19 19:37:22 +11:00
parent 644484b650
commit 487f99ab93
7 changed files with 42 additions and 24 deletions

View File

@ -20,6 +20,7 @@ import org.session.libsession.messaging.messages.ExpirationConfiguration
import org.session.libsession.messaging.open_groups.OpenGroup
import org.session.libsession.utilities.ExpirationUtil
import org.session.libsession.utilities.recipients.Recipient
import org.session.libsignal.protos.SignalServiceProtos
import org.thoughtcrime.securesms.conversation.v2.utilities.MentionManagerUtilities
import org.thoughtcrime.securesms.database.GroupDatabase
import org.thoughtcrime.securesms.database.LokiAPIDatabase
@ -104,9 +105,14 @@ class ConversationActionBarView : LinearLayout {
fun updateSubtitle(recipient: Recipient, openGroup: OpenGroup? = null, config: ExpirationConfiguration? = null) {
val settings = mutableListOf<ConversationSetting>()
if (config?.isEnabled == true) {
val prefix = if (config.expirationType == SignalServiceProtos.Content.ExpirationType.DELETE_AFTER_READ) {
context.getString(R.string.expiration_type_disappear_after_read)
} else {
context.getString(R.string.expiration_type_disappear_after_send)
}
settings.add(
ConversationSetting(
"${context.getString(R.string.expiration_type_disappear_after_read)} - ${ExpirationUtil.getExpirationAbbreviatedDisplayValue(context, config?.durationSeconds ?: 0)}" ,
"$prefix - ${ExpirationUtil.getExpirationAbbreviatedDisplayValue(context, config.durationSeconds)}" ,
ConversationSettingType.EXPIRATION,
R.drawable.ic_timer
)

View File

@ -15,6 +15,7 @@ import kotlinx.coroutines.launch
import org.session.libsession.messaging.messages.ExpirationConfiguration
import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate
import org.session.libsession.messaging.sending_receiving.MessageSender
import org.session.libsession.utilities.SSKEnvironment.MessageExpirationManagerProtocol
import org.session.libsession.utilities.recipients.Recipient
import org.session.libsignal.protos.SignalServiceProtos.Content.ExpirationType
import org.thoughtcrime.securesms.database.Storage
@ -25,6 +26,7 @@ class ExpirationSettingsViewModel(
private val threadId: Long,
private val afterReadOptions: List<RadioOption>,
private val afterSendOptions: List<RadioOption>,
private val messageExpirationManager: MessageExpirationManagerProtocol,
private val threadDb: ThreadDatabase,
private val storage: Storage
) : ViewModel() {
@ -54,11 +56,6 @@ class ExpirationSettingsViewModel(
_uiState.update {
it.copy(showExpirationTypeSelector = !ExpirationConfiguration.isNewConfigEnabled || (recipient?.isContactRecipient == true && !recipient.isLocalNumber))
}
if (ExpirationConfiguration.isNewConfigEnabled && (recipient?.isLocalNumber == true || recipient?.isClosedGroupRecipient == true)) {
_selectedExpirationType.value = ExpirationType.DELETE_AFTER_SEND.number
} else {
_selectedExpirationType.value = expirationConfig?.expirationTypeValue ?: -1
}
_selectedExpirationType.value = if (ExpirationConfiguration.isNewConfigEnabled) {
if (recipient?.isLocalNumber == true || recipient?.isClosedGroupRecipient == true) {
ExpirationType.DELETE_AFTER_SEND.number
@ -108,6 +105,8 @@ class ExpirationSettingsViewModel(
val address = recipient.value?.address ?: return@launch
message.recipient = address.serialize()
message.sentTimestamp = System.currentTimeMillis()
messageExpirationManager.setExpirationTimer(message)
MessageSender.send(message, address)
_uiState.update {
it.copy(settingsSaved = true)
@ -128,6 +127,7 @@ class ExpirationSettingsViewModel(
@Assisted private val threadId: Long,
@Assisted("afterRead") private val afterReadOptions: List<RadioOption>,
@Assisted("afterSend") private val afterSendOptions: List<RadioOption>,
private val messageExpirationManager: MessageExpirationManagerProtocol,
private val threadDb: ThreadDatabase,
private val storage: Storage
) : ViewModelProvider.Factory {
@ -137,6 +137,7 @@ class ExpirationSettingsViewModel(
threadId,
afterReadOptions,
afterSendOptions,
messageExpirationManager,
threadDb,
storage
) as T

View File

@ -83,6 +83,7 @@ class ExpirationConfigurationDatabase(context: Context, helper: SQLCipherOpenHel
writableDatabase.insert(TABLE_NAME, null, values)
writableDatabase.setTransactionSuccessful()
notifyConversationListeners(configuration.threadId)
} finally {
writableDatabase.endTransaction()
}

View File

@ -8,12 +8,14 @@ import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import net.sqlcipher.database.SQLiteDatabase
import org.session.libsession.database.MessageDataProvider
import org.session.libsession.utilities.SSKEnvironment
import org.thoughtcrime.securesms.attachments.DatabaseAttachmentProvider
import org.thoughtcrime.securesms.crypto.AttachmentSecret
import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider
import org.thoughtcrime.securesms.crypto.DatabaseSecretProvider
import org.thoughtcrime.securesms.database.*
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
import org.thoughtcrime.securesms.service.ExpiringMessageManager
import javax.inject.Singleton
@Module
@ -25,6 +27,10 @@ object DatabaseModule {
SQLiteDatabase.loadLibs(context)
}
@Provides
@Singleton
fun provideMessageExpirationManagerProtocol(@ApplicationContext context: Context): SSKEnvironment.MessageExpirationManagerProtocol = ExpiringMessageManager(context)
@Provides
@Singleton
fun provideAttachmentSecret(@ApplicationContext context: Context) = AttachmentSecretProvider.getInstance(context).orCreateAttachmentSecret

View File

@ -69,20 +69,7 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM
}
@Override
public void setExpirationTimer(@NotNull ExpirationTimerUpdate message, @Nullable Integer expirationType) {
try {
ThreadDatabase threadDb = DatabaseComponent.get(context).threadDatabase();
long threadId = threadDb.getOrCreateThreadIdFor(Recipient.from(context, Address.fromSerialized(message.getSender()), false));
if (message.getGroupPublicKey() != null) {
Recipient recipient = Recipient.from(context, Address.fromSerialized(GroupUtil.doubleEncodeGroupID(message.getGroupPublicKey())), false);
threadId = threadDb.getOrCreateThreadIdFor(recipient);
}
DatabaseComponent.get(context).expirationConfigurationDatabase().setExpirationConfiguration(
new ExpirationConfiguration(threadId, message.getDuration(), expirationType, System.currentTimeMillis())
);
} catch (Exception e) {
Log.e("Loki", "Failed to update expiration configuration.");
}
public void setExpirationTimer(@NotNull ExpirationTimerUpdate message) {
String userPublicKey = TextSecurePreferences.getLocalNumber(context);
String senderPublicKey = message.getSender();

View File

@ -33,8 +33,10 @@ import org.session.libsession.messaging.utilities.SodiumUtilities
import org.session.libsession.messaging.utilities.WebRtcUtils
import org.session.libsession.snode.SnodeAPI
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.Address.Companion.fromSerialized
import org.session.libsession.utilities.GroupRecord
import org.session.libsession.utilities.GroupUtil
import org.session.libsession.utilities.GroupUtil.doubleEncodeGroupID
import org.session.libsession.utilities.ProfileKeyUtil
import org.session.libsession.utilities.SSKEnvironment
import org.session.libsession.utilities.TextSecurePreferences
@ -92,7 +94,7 @@ fun updateExpirationConfigurationIfNeeded(message: Message, proto: SignalService
val threadID = storage.getOrCreateThreadIdFor(message.sender!!, message.groupPublicKey, openGroupID)
if (threadID <= 0) return
val localConfig = storage.getExpirationConfiguration(threadID)
if (localConfig == null || localConfig.updatedTimestampMs > proto.lastDisappearingMessageChangeTimestamp) return
if (localConfig != null && localConfig.updatedTimestampMs > proto.lastDisappearingMessageChangeTimestamp) return
val durationSeconds = if (proto.hasExpirationTimer()) proto.expirationTimer else 0
val type = if (proto.hasExpirationType()) proto.expirationType else null
val remoteConfig = ExpirationConfiguration(
@ -102,6 +104,9 @@ fun updateExpirationConfigurationIfNeeded(message: Message, proto: SignalService
proto.lastDisappearingMessageChangeTimestamp
)
storage.setExpirationConfiguration(remoteConfig)
if (message is ExpirationTimerUpdate) {
SSKEnvironment.shared.messageExpirationManager.setExpirationTimer(message)
}
}
// region Control Messages
@ -158,13 +163,25 @@ fun MessageReceiver.cancelTypingIndicatorsIfNeeded(senderPublicKey: String) {
private fun MessageReceiver.handleExpirationTimerUpdate(message: ExpirationTimerUpdate) {
if (ExpirationConfiguration.isNewConfigEnabled) return
val recipient = Recipient.from(MessagingModuleConfiguration.shared.context, Address.fromSerialized(message.sender!!), false)
val module = MessagingModuleConfiguration.shared
val recipient = Recipient.from(module.context, Address.fromSerialized(message.sender!!), false)
val type = when {
recipient.isContactRecipient -> ExpirationType.DELETE_AFTER_READ
recipient.isGroupRecipient -> ExpirationType.DELETE_AFTER_SEND
else -> null
}
SSKEnvironment.shared.messageExpirationManager.setExpirationTimer(message, type?.number)
try {
var threadId: Long = module.storage.getOrCreateThreadIdFor(fromSerialized(message.sender!!))
if (message.groupPublicKey != null) {
threadId = module.storage.getOrCreateThreadIdFor(fromSerialized(doubleEncodeGroupID(message.groupPublicKey!!)))
}
module.storage.setExpirationConfiguration(
ExpirationConfiguration(threadId, message.duration!!, type?.number ?: -1, System.currentTimeMillis())
)
} catch (e: Exception) {
Log.e("Loki", "Failed to update expiration configuration.")
}
SSKEnvironment.shared.messageExpirationManager.setExpirationTimer(message)
}
private fun MessageReceiver.handleDataExtractionNotification(message: DataExtractionNotification) {

View File

@ -36,7 +36,7 @@ class SSKEnvironment(
}
interface MessageExpirationManagerProtocol {
fun setExpirationTimer(message: ExpirationTimerUpdate, expirationType: Int?)
fun setExpirationTimer(message: ExpirationTimerUpdate)
fun startAnyExpiration(timestamp: Long, author: String)
}