Legacy expiration type handling tweaks

This commit is contained in:
charles 2022-12-14 18:02:37 +11:00
parent a6f9e17122
commit 23c881f3ce
11 changed files with 29 additions and 23 deletions

View File

@ -107,7 +107,7 @@ class ExpirationSettingsActivity: PassphraseRequiredActionBarActivity() {
lifecycleScope.launchWhenStarted { lifecycleScope.launchWhenStarted {
launch { launch {
viewModel.selectedExpirationType.collect { type -> viewModel.selectedExpirationType.collect { type ->
val position = deleteTypeOptions.indexOfFirst { it.value.toIntOrNull() == type?.number } val position = deleteTypeOptions.indexOfFirst { it.value.toIntOrNull() == type }
deleteTypeOptionAdapter.setSelectedPosition(max(0, position)) deleteTypeOptionAdapter.setSelectedPosition(max(0, position))
} }
} }
@ -208,7 +208,7 @@ class ExpirationSettingsActivity: PassphraseRequiredActionBarActivity() {
setSupportActionBar(binding.toolbar) setSupportActionBar(binding.toolbar)
val actionBar = supportActionBar ?: return val actionBar = supportActionBar ?: return
actionBar.title = getString(R.string.activity_expiration_settings_title) actionBar.title = getString(R.string.activity_expiration_settings_title)
actionBar.subtitle = if (viewModel.selectedExpirationType.value == ExpirationType.DELETE_AFTER_SEND) { actionBar.subtitle = if (viewModel.selectedExpirationType.value == ExpirationType.DELETE_AFTER_SEND.number) {
getString(R.string.activity_expiration_settings_subtitle_sent) getString(R.string.activity_expiration_settings_subtitle_sent)
} else { } else {
getString(R.string.activity_expiration_settings_subtitle) getString(R.string.activity_expiration_settings_subtitle)

View File

@ -34,8 +34,8 @@ class ExpirationSettingsViewModel(
private val _recipient = MutableStateFlow<Recipient?>(null) private val _recipient = MutableStateFlow<Recipient?>(null)
val recipient: StateFlow<Recipient?> = _recipient val recipient: StateFlow<Recipient?> = _recipient
private val _selectedExpirationType = MutableStateFlow<ExpirationType?>(null) private val _selectedExpirationType = MutableStateFlow<Int?>(null)
val selectedExpirationType: StateFlow<ExpirationType?> = _selectedExpirationType val selectedExpirationType: StateFlow<Int?> = _selectedExpirationType
private val _selectedExpirationTimer = MutableStateFlow(afterSendOptions.firstOrNull()) private val _selectedExpirationTimer = MutableStateFlow(afterSendOptions.firstOrNull())
val selectedExpirationTimer: StateFlow<RadioOption?> = _selectedExpirationTimer val selectedExpirationTimer: StateFlow<RadioOption?> = _selectedExpirationTimer
@ -49,10 +49,10 @@ class ExpirationSettingsViewModel(
val recipient = threadDb.getRecipientForThreadId(threadId) val recipient = threadDb.getRecipientForThreadId(threadId)
_recipient.value = recipient _recipient.value = recipient
showExpirationTypeSelector = !ExpirationConfiguration.isNewConfigEnabled || (recipient?.isContactRecipient == true && !recipient.isLocalNumber) showExpirationTypeSelector = !ExpirationConfiguration.isNewConfigEnabled || (recipient?.isContactRecipient == true && !recipient.isLocalNumber)
if (recipient?.isLocalNumber == true || recipient?.isClosedGroupRecipient == true) { if (ExpirationConfiguration.isNewConfigEnabled && (recipient?.isLocalNumber == true || recipient?.isClosedGroupRecipient == true)) {
_selectedExpirationType.value = ExpirationType.DELETE_AFTER_SEND _selectedExpirationType.value = ExpirationType.DELETE_AFTER_SEND.number
} else { } else {
_selectedExpirationType.value = expirationConfig?.expirationType _selectedExpirationType.value = expirationConfig?.expirationTypeValue
} }
_selectedExpirationTimer.value = when(expirationConfig?.expirationType) { _selectedExpirationTimer.value = when(expirationConfig?.expirationType) {
ExpirationType.DELETE_AFTER_SEND -> afterSendOptions.find { it.value.toIntOrNull() == expirationConfig?.durationSeconds } ExpirationType.DELETE_AFTER_SEND -> afterSendOptions.find { it.value.toIntOrNull() == expirationConfig?.durationSeconds }
@ -62,8 +62,8 @@ class ExpirationSettingsViewModel(
} }
selectedExpirationType.mapLatest { selectedExpirationType.mapLatest {
when (it) { when (it) {
ExpirationType.DELETE_AFTER_SEND -> afterSendOptions 0, ExpirationType.DELETE_AFTER_SEND.number -> afterSendOptions
ExpirationType.DELETE_AFTER_READ -> afterReadOptions ExpirationType.DELETE_AFTER_READ.number -> afterReadOptions
else -> emptyList() else -> emptyList()
} }
}.onEach { options -> }.onEach { options ->
@ -76,7 +76,7 @@ class ExpirationSettingsViewModel(
} }
fun onExpirationTypeSelected(option: RadioOption) { fun onExpirationTypeSelected(option: RadioOption) {
_selectedExpirationType.value = option.value.toIntOrNull()?.let { ExpirationType.valueOf(it) } _selectedExpirationType.value = option.value.toIntOrNull()
} }
fun onExpirationTimerSelected(option: RadioOption) { fun onExpirationTimerSelected(option: RadioOption) {

View File

@ -7,7 +7,6 @@ import org.session.libsession.messaging.messages.ExpirationConfiguration
import org.session.libsession.utilities.GroupUtil.CLOSED_GROUP_PREFIX import org.session.libsession.utilities.GroupUtil.CLOSED_GROUP_PREFIX
import org.session.libsession.utilities.GroupUtil.OPEN_GROUP_INBOX_PREFIX import org.session.libsession.utilities.GroupUtil.OPEN_GROUP_INBOX_PREFIX
import org.session.libsession.utilities.GroupUtil.OPEN_GROUP_PREFIX import org.session.libsession.utilities.GroupUtil.OPEN_GROUP_PREFIX
import org.session.libsignal.protos.SignalServiceProtos.Content.ExpirationType
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
class ExpirationConfigurationDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper) { class ExpirationConfigurationDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper) {
@ -51,7 +50,7 @@ class ExpirationConfigurationDatabase(context: Context, helper: SQLCipherOpenHel
return ExpirationConfiguration( return ExpirationConfiguration(
threadId = cursor.getLong(cursor.getColumnIndexOrThrow(THREAD_ID)), threadId = cursor.getLong(cursor.getColumnIndexOrThrow(THREAD_ID)),
durationSeconds = cursor.getInt(cursor.getColumnIndexOrThrow(DURATION_SECONDS)), durationSeconds = cursor.getInt(cursor.getColumnIndexOrThrow(DURATION_SECONDS)),
expirationType = ExpirationType.valueOf(cursor.getInt(cursor.getColumnIndexOrThrow(EXPIRATION_TYPE))), expirationTypeValue = cursor.getInt(cursor.getColumnIndexOrThrow(EXPIRATION_TYPE)),
updatedTimestampMs = cursor.getLong(cursor.getColumnIndexOrThrow(UPDATED_TIMESTAMP_MS)) updatedTimestampMs = cursor.getLong(cursor.getColumnIndexOrThrow(UPDATED_TIMESTAMP_MS))
) )
} }
@ -78,7 +77,7 @@ class ExpirationConfigurationDatabase(context: Context, helper: SQLCipherOpenHel
val values = ContentValues().apply { val values = ContentValues().apply {
put(THREAD_ID, configuration.threadId) put(THREAD_ID, configuration.threadId)
put(DURATION_SECONDS, configuration.durationSeconds) put(DURATION_SECONDS, configuration.durationSeconds)
put(EXPIRATION_TYPE, configuration.expirationType?.number) put(EXPIRATION_TYPE, configuration.expirationTypeValue)
put(UPDATED_TIMESTAMP_MS, configuration.updatedTimestampMs) put(UPDATED_TIMESTAMP_MS, configuration.updatedTimestampMs)
} }

View File

@ -138,6 +138,11 @@ public class RecipientDatabase extends Database {
"OR "+ADDRESS+" IN (SELECT "+GroupDatabase.TABLE_NAME+"."+GroupDatabase.ADMINS+" FROM "+GroupDatabase.TABLE_NAME+")))"; "OR "+ADDRESS+" IN (SELECT "+GroupDatabase.TABLE_NAME+"."+GroupDatabase.ADMINS+" FROM "+GroupDatabase.TABLE_NAME+")))";
} }
public static String getCreateDisappearingStateCommand() {
return "ALTER TABLE "+ TABLE_NAME + " " +
"ADD COLUMN " + DISAPPEARING_STATE + " INTEGER DEFAULT 0;";
}
public static final int NOTIFY_TYPE_ALL = 0; public static final int NOTIFY_TYPE_ALL = 0;
public static final int NOTIFY_TYPE_MENTIONS = 1; public static final int NOTIFY_TYPE_MENTIONS = 1;
public static final int NOTIFY_TYPE_NONE = 2; public static final int NOTIFY_TYPE_NONE = 2;

View File

@ -544,7 +544,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
val recipient = Recipient.from(context, fromSerialized(groupID), false) val recipient = Recipient.from(context, fromSerialized(groupID), false)
val threadId = DatabaseComponent.get(context).threadDatabase().getThreadIdIfExistsFor(recipient) val threadId = DatabaseComponent.get(context).threadDatabase().getThreadIdIfExistsFor(recipient)
DatabaseComponent.get(context).expirationConfigurationDatabase().setExpirationConfiguration( DatabaseComponent.get(context).expirationConfigurationDatabase().setExpirationConfiguration(
ExpirationConfiguration(threadId, duration, ExpirationType.DELETE_AFTER_SEND, System.currentTimeMillis()) ExpirationConfiguration(threadId, duration, ExpirationType.DELETE_AFTER_SEND.number, System.currentTimeMillis())
) )
} }

View File

@ -165,6 +165,7 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
db.execSQL(GroupDatabase.getCreateUpdatedTimestampCommand()); db.execSQL(GroupDatabase.getCreateUpdatedTimestampCommand());
db.execSQL(RecipientDatabase.getCreateApprovedCommand()); db.execSQL(RecipientDatabase.getCreateApprovedCommand());
db.execSQL(RecipientDatabase.getCreateApprovedMeCommand()); db.execSQL(RecipientDatabase.getCreateApprovedMeCommand());
db.execSQL(RecipientDatabase.getCreateDisappearingStateCommand());
db.execSQL(MmsDatabase.CREATE_MESSAGE_REQUEST_RESPONSE_COMMAND); db.execSQL(MmsDatabase.CREATE_MESSAGE_REQUEST_RESPONSE_COMMAND);
db.execSQL(MmsDatabase.CREATE_REACTIONS_UNREAD_COMMAND); db.execSQL(MmsDatabase.CREATE_REACTIONS_UNREAD_COMMAND);
db.execSQL(SmsDatabase.CREATE_REACTIONS_UNREAD_COMMAND); db.execSQL(SmsDatabase.CREATE_REACTIONS_UNREAD_COMMAND);
@ -418,6 +419,7 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
} }
if (oldVersion < lokiV39) { if (oldVersion < lokiV39) {
db.execSQL(RecipientDatabase.getCreateDisappearingStateCommand());
db.execSQL(ExpirationConfigurationDatabase.CREATE_EXPIRATION_CONFIGURATION_TABLE_COMMAND); db.execSQL(ExpirationConfigurationDatabase.CREATE_EXPIRATION_CONFIGURATION_TABLE_COMMAND);
db.execSQL(ExpirationConfigurationDatabase.MIGRATE_GROUP_CONVERSATION_EXPIRY_TYPE_COMMAND); db.execSQL(ExpirationConfigurationDatabase.MIGRATE_GROUP_CONVERSATION_EXPIRY_TYPE_COMMAND);
db.execSQL(ExpirationConfigurationDatabase.MIGRATE_ONE_TO_ONE_CONVERSATION_EXPIRY_TYPE_COMMAND); db.execSQL(ExpirationConfigurationDatabase.MIGRATE_ONE_TO_ONE_CONVERSATION_EXPIRY_TYPE_COMMAND);

View File

@ -14,7 +14,6 @@ import org.session.libsession.utilities.SSKEnvironment;
import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.TextSecurePreferences;
import org.session.libsession.utilities.recipients.Recipient; import org.session.libsession.utilities.recipients.Recipient;
import org.session.libsignal.messages.SignalServiceGroup; import org.session.libsignal.messages.SignalServiceGroup;
import org.session.libsignal.protos.SignalServiceProtos;
import org.session.libsignal.utilities.Log; import org.session.libsignal.utilities.Log;
import org.session.libsignal.utilities.guava.Optional; import org.session.libsignal.utilities.guava.Optional;
import org.thoughtcrime.securesms.database.MmsDatabase; import org.thoughtcrime.securesms.database.MmsDatabase;
@ -69,7 +68,7 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM
} }
@Override @Override
public void setExpirationTimer(@NotNull ExpirationTimerUpdate message, @Nullable SignalServiceProtos.Content.ExpirationType type) { public void setExpirationTimer(@NotNull ExpirationTimerUpdate message, @Nullable Integer expirationType) {
try { try {
long threadId = message.getThreadID(); long threadId = message.getThreadID();
if (message.getGroupPublicKey() != null) { if (message.getGroupPublicKey() != null) {
@ -77,7 +76,7 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM
threadId = DatabaseComponent.get(context).threadDatabase().getOrCreateThreadIdFor(recipient); threadId = DatabaseComponent.get(context).threadDatabase().getOrCreateThreadIdFor(recipient);
} }
DatabaseComponent.get(context).expirationConfigurationDatabase().setExpirationConfiguration( DatabaseComponent.get(context).expirationConfigurationDatabase().setExpirationConfiguration(
new ExpirationConfiguration(threadId, message.getDuration(), type, System.currentTimeMillis()) new ExpirationConfiguration(threadId, message.getDuration(), expirationType, System.currentTimeMillis())
); );
} catch (Exception e) { } catch (Exception e) {
Log.e("Loki", "Failed to update expiration configuration."); Log.e("Loki", "Failed to update expiration configuration.");

View File

@ -873,7 +873,7 @@
<string name="new_conversation_dialog_close_button_content_description">Close Dialog</string> <string name="new_conversation_dialog_close_button_content_description">Close Dialog</string>
<string name="activity_expiration_settings_title">Disappearing Messages</string> <string name="activity_expiration_settings_title">Disappearing Messages</string>
<string name="activity_expiration_settings_subtitle">This setting applies to everyone in this conversation.</string> <string name="activity_expiration_settings_subtitle">This setting applies to everyone in this conversation.</string>
<string name="expiration_type_disappear_legacy_description">Use the original version of disappearing messages.</string> <string name="expiration_type_disappear_legacy_description">Original version of disappearing messages.</string>
<string name="expiration_type_disappear_legacy">Legacy</string> <string name="expiration_type_disappear_legacy">Legacy</string>
<string name="activity_expiration_settings_subtitle_sent">Messages disappear after they have been sent.</string> <string name="activity_expiration_settings_subtitle_sent">Messages disappear after they have been sent.</string>
<string name="expiration_type_disappear_after_read">Disappear After Read</string> <string name="expiration_type_disappear_after_read">Disappear After Read</string>

View File

@ -5,10 +5,12 @@ import org.session.libsignal.protos.SignalServiceProtos.Content.ExpirationType
class ExpirationConfiguration( class ExpirationConfiguration(
val threadId: Long = -1, val threadId: Long = -1,
val durationSeconds: Int = 0, val durationSeconds: Int = 0,
val expirationType: ExpirationType? = null, val expirationTypeValue: Int? = null,
val updatedTimestampMs: Long = 0 val updatedTimestampMs: Long = 0
) { ) {
val isEnabled = durationSeconds > 0 val isEnabled = durationSeconds > 0
val expirationType = expirationTypeValue?.let { ExpirationType.valueOf(it) }
companion object { companion object {
val isNewConfigEnabled = System.currentTimeMillis() > 1_674_000_000_000 // 18/01/2023 val isNewConfigEnabled = System.currentTimeMillis() > 1_674_000_000_000 // 18/01/2023
} }

View File

@ -98,7 +98,7 @@ fun updateExpirationConfigurationIfNeeded(message: Message, proto: SignalService
val remoteConfig = ExpirationConfiguration( val remoteConfig = ExpirationConfiguration(
threadID, threadID,
durationSeconds, durationSeconds,
type, type?.number,
proto.lastDisappearingMessageChangeTimestamp proto.lastDisappearingMessageChangeTimestamp
) )
storage.setExpirationConfiguration(remoteConfig) storage.setExpirationConfiguration(remoteConfig)
@ -164,7 +164,7 @@ private fun MessageReceiver.handleExpirationTimerUpdate(message: ExpirationTimer
recipient.isContactRecipient || recipient.isGroupRecipient -> ExpirationType.DELETE_AFTER_SEND recipient.isContactRecipient || recipient.isGroupRecipient -> ExpirationType.DELETE_AFTER_SEND
else -> null else -> null
} }
SSKEnvironment.shared.messageExpirationManager.setExpirationTimer(message, type) SSKEnvironment.shared.messageExpirationManager.setExpirationTimer(message, type?.number)
} }
private fun MessageReceiver.handleDataExtractionNotification(message: DataExtractionNotification) { private fun MessageReceiver.handleDataExtractionNotification(message: DataExtractionNotification) {

View File

@ -4,7 +4,6 @@ import android.content.Context
import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate
import org.session.libsession.messaging.sending_receiving.notifications.MessageNotifier import org.session.libsession.messaging.sending_receiving.notifications.MessageNotifier
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
import org.session.libsignal.protos.SignalServiceProtos.Content.ExpirationType
class SSKEnvironment( class SSKEnvironment(
val typingIndicators: TypingIndicatorsProtocol, val typingIndicators: TypingIndicatorsProtocol,
@ -37,7 +36,7 @@ class SSKEnvironment(
} }
interface MessageExpirationManagerProtocol { interface MessageExpirationManagerProtocol {
fun setExpirationTimer(message: ExpirationTimerUpdate, type: ExpirationType?) fun setExpirationTimer(message: ExpirationTimerUpdate, expirationType: Int?)
fun startAnyExpiration(timestamp: Long, author: String) fun startAnyExpiration(timestamp: Long, author: String)
} }