mirror of
https://github.com/oxen-io/session-android.git
synced 2025-04-04 17:05:38 +00:00
feat: add user config integrated into config sync
This commit is contained in:
parent
06c0ab3080
commit
8db92cc55c
@ -95,7 +95,7 @@ class LibSessionTests {
|
|||||||
fakePollNewConfig(contacts, newContactMerge)
|
fakePollNewConfig(contacts, newContactMerge)
|
||||||
verify(storageSpy).addLibSessionContacts(argThat {
|
verify(storageSpy).addLibSessionContacts(argThat {
|
||||||
first().let { it.id == newContactId && it.approved } && size == 1
|
first().let { it.id == newContactId && it.approved } && size == 1
|
||||||
})
|
}, 0)
|
||||||
verify(storageSpy).setRecipientApproved(argThat { address.serialize() == newContactId }, eq(true))
|
verify(storageSpy).setRecipientApproved(argThat { address.serialize() == newContactId }, eq(true))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,12 +194,12 @@ public class ApplicationContext extends Application implements DefaultLifecycleO
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void notifyUpdates(@NonNull ConfigBase forConfigObject) {
|
public void notifyUpdates(@NonNull ConfigBase forConfigObject, long messageTimestamp) {
|
||||||
// forward to the config factory / storage ig
|
// forward to the config factory / storage ig
|
||||||
if (forConfigObject instanceof UserProfile && !textSecurePreferences.getConfigurationMessageSynced()) {
|
if (forConfigObject instanceof UserProfile && !textSecurePreferences.getConfigurationMessageSynced()) {
|
||||||
textSecurePreferences.setConfigurationMessageSynced(true);
|
textSecurePreferences.setConfigurationMessageSynced(true);
|
||||||
}
|
}
|
||||||
storage.notifyConfigUpdates(forConfigObject);
|
storage.notifyConfigUpdates(forConfigObject, messageTimestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -27,7 +27,7 @@ class ExpirationConfigurationDatabase(context: Context, helper: SQLCipherOpenHel
|
|||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val MIGRATE_GROUP_CONVERSATION_EXPIRY_TYPE_COMMAND = """
|
val MIGRATE_GROUP_CONVERSATION_EXPIRY_TYPE_COMMAND = """
|
||||||
INSERT INTO $TABLE_NAME ($THREAD_ID) SELECT ${ThreadDatabase.TABLE_NAME}.${ThreadDatabase.ID}, ${RecipientDatabase.EXPIRE_MESSAGES}, 1
|
INSERT INTO $TABLE_NAME ($THREAD_ID) SELECT ${ThreadDatabase.TABLE_NAME}.${ThreadDatabase.ID}
|
||||||
FROM ${ThreadDatabase.TABLE_NAME}, ${RecipientDatabase.TABLE_NAME}
|
FROM ${ThreadDatabase.TABLE_NAME}, ${RecipientDatabase.TABLE_NAME}
|
||||||
WHERE ${ThreadDatabase.TABLE_NAME}.${ThreadDatabase.ADDRESS} LIKE '$CLOSED_GROUP_PREFIX%'
|
WHERE ${ThreadDatabase.TABLE_NAME}.${ThreadDatabase.ADDRESS} LIKE '$CLOSED_GROUP_PREFIX%'
|
||||||
AND EXISTS (SELECT ${RecipientDatabase.EXPIRE_MESSAGES} FROM ${RecipientDatabase.TABLE_NAME} WHERE ${ThreadDatabase.TABLE_NAME}.${ThreadDatabase.ADDRESS} = ${RecipientDatabase.TABLE_NAME}.${RecipientDatabase.ADDRESS} AND ${RecipientDatabase.EXPIRE_MESSAGES} > 0)
|
AND EXISTS (SELECT ${RecipientDatabase.EXPIRE_MESSAGES} FROM ${RecipientDatabase.TABLE_NAME} WHERE ${ThreadDatabase.TABLE_NAME}.${ThreadDatabase.ADDRESS} = ${RecipientDatabase.TABLE_NAME}.${RecipientDatabase.ADDRESS} AND ${RecipientDatabase.EXPIRE_MESSAGES} > 0)
|
||||||
@ -35,7 +35,7 @@ class ExpirationConfigurationDatabase(context: Context, helper: SQLCipherOpenHel
|
|||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val MIGRATE_ONE_TO_ONE_CONVERSATION_EXPIRY_TYPE_COMMAND = """
|
val MIGRATE_ONE_TO_ONE_CONVERSATION_EXPIRY_TYPE_COMMAND = """
|
||||||
INSERT INTO $TABLE_NAME ($THREAD_ID) SELECT ${ThreadDatabase.TABLE_NAME}.${ThreadDatabase.ID}, ${RecipientDatabase.EXPIRE_MESSAGES}, 2
|
INSERT INTO $TABLE_NAME ($THREAD_ID) SELECT ${ThreadDatabase.TABLE_NAME}.${ThreadDatabase.ID}
|
||||||
FROM ${ThreadDatabase.TABLE_NAME}, ${RecipientDatabase.TABLE_NAME}
|
FROM ${ThreadDatabase.TABLE_NAME}, ${RecipientDatabase.TABLE_NAME}
|
||||||
WHERE ${ThreadDatabase.TABLE_NAME}.${ThreadDatabase.ADDRESS} NOT LIKE '$CLOSED_GROUP_PREFIX%'
|
WHERE ${ThreadDatabase.TABLE_NAME}.${ThreadDatabase.ADDRESS} NOT LIKE '$CLOSED_GROUP_PREFIX%'
|
||||||
AND ${ThreadDatabase.TABLE_NAME}.${ThreadDatabase.ADDRESS} NOT LIKE '$OPEN_GROUP_PREFIX%'
|
AND ${ThreadDatabase.TABLE_NAME}.${ThreadDatabase.ADDRESS} NOT LIKE '$OPEN_GROUP_PREFIX%'
|
||||||
|
@ -434,8 +434,8 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co
|
|||||||
return DatabaseComponent.get(context).lokiAPIDatabase().getAuthToken(id)
|
return DatabaseComponent.get(context).lokiAPIDatabase().getAuthToken(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun notifyConfigUpdates(forConfigObject: ConfigBase) {
|
override fun notifyConfigUpdates(forConfigObject: ConfigBase, messageTimestamp: Long) {
|
||||||
notifyUpdates(forConfigObject)
|
notifyUpdates(forConfigObject, messageTimestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun conversationInConfig(publicKey: String?, groupPublicKey: String?, openGroupId: String?, visibleOnly: Boolean): Boolean {
|
override fun conversationInConfig(publicKey: String?, groupPublicKey: String?, openGroupId: String?, visibleOnly: Boolean): Boolean {
|
||||||
@ -446,16 +446,16 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co
|
|||||||
return configFactory.canPerformChange(variant, publicKey, changeTimestampMs)
|
return configFactory.canPerformChange(variant, publicKey, changeTimestampMs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun notifyUpdates(forConfigObject: ConfigBase) {
|
private fun notifyUpdates(forConfigObject: ConfigBase, messageTimestamp: Long) {
|
||||||
when (forConfigObject) {
|
when (forConfigObject) {
|
||||||
is UserProfile -> updateUser(forConfigObject)
|
is UserProfile -> updateUser(forConfigObject, messageTimestamp)
|
||||||
is Contacts -> updateContacts(forConfigObject)
|
is Contacts -> updateContacts(forConfigObject, messageTimestamp)
|
||||||
is ConversationVolatileConfig -> updateConvoVolatile(forConfigObject)
|
is ConversationVolatileConfig -> updateConvoVolatile(forConfigObject, messageTimestamp)
|
||||||
is UserGroupsConfig -> updateUserGroups(forConfigObject)
|
is UserGroupsConfig -> updateUserGroups(forConfigObject, messageTimestamp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateUser(userProfile: UserProfile) {
|
private fun updateUser(userProfile: UserProfile, messageTimestamp: Long) {
|
||||||
val userPublicKey = getUserPublicKey() ?: return
|
val userPublicKey = getUserPublicKey() ?: return
|
||||||
// would love to get rid of recipient and context from this
|
// would love to get rid of recipient and context from this
|
||||||
val recipient = Recipient.from(context, fromSerialized(userPublicKey), false)
|
val recipient = Recipient.from(context, fromSerialized(userPublicKey), false)
|
||||||
@ -486,11 +486,16 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co
|
|||||||
setPinned(ourThread, userProfile.getNtsPriority() > 0)
|
setPinned(ourThread, userProfile.getNtsPriority() > 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getThreadId(recipient)?.let { ourThread ->
|
||||||
|
val expiration = ExpirationConfiguration(ourThread, userProfile.getNtsExpiry(), messageTimestamp)
|
||||||
|
DatabaseComponent.get(context).expirationConfigurationDatabase().setExpirationConfiguration(expiration)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateContacts(contacts: Contacts) {
|
private fun updateContacts(contacts: Contacts, messageTimestamp: Long) {
|
||||||
val extracted = contacts.all().toList()
|
val extracted = contacts.all().toList()
|
||||||
addLibSessionContacts(extracted)
|
addLibSessionContacts(extracted, messageTimestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun clearUserPic() {
|
override fun clearUserPic() {
|
||||||
@ -510,7 +515,7 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co
|
|||||||
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(context)
|
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateConvoVolatile(convos: ConversationVolatileConfig) {
|
private fun updateConvoVolatile(convos: ConversationVolatileConfig, messageTimestamp: Long) {
|
||||||
val extracted = convos.all()
|
val extracted = convos.all()
|
||||||
for (conversation in extracted) {
|
for (conversation in extracted) {
|
||||||
val threadId = when (conversation) {
|
val threadId = when (conversation) {
|
||||||
@ -527,7 +532,7 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateUserGroups(userGroups: UserGroupsConfig) {
|
private fun updateUserGroups(userGroups: UserGroupsConfig, messageTimestamp: Long) {
|
||||||
val threadDb = DatabaseComponent.get(context).threadDatabase()
|
val threadDb = DatabaseComponent.get(context).threadDatabase()
|
||||||
val localUserPublicKey = getUserPublicKey() ?: return Log.w(
|
val localUserPublicKey = getUserPublicKey() ?: return Log.w(
|
||||||
"Loki",
|
"Loki",
|
||||||
@ -579,6 +584,7 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (group in lgc) {
|
for (group in lgc) {
|
||||||
|
val groupId = GroupUtil.doubleEncodeGroupID(group.sessionId)
|
||||||
val existingGroup = existingClosedGroups.firstOrNull { GroupUtil.doubleDecodeGroupId(it.encodedId) == group.sessionId }
|
val existingGroup = existingClosedGroups.firstOrNull { GroupUtil.doubleDecodeGroupId(it.encodedId) == group.sessionId }
|
||||||
val existingThread = existingGroup?.let { getThreadId(existingGroup.encodedId) }
|
val existingThread = existingGroup?.let { getThreadId(existingGroup.encodedId) }
|
||||||
if (existingGroup != null) {
|
if (existingGroup != null) {
|
||||||
@ -593,7 +599,6 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co
|
|||||||
} else {
|
} else {
|
||||||
val members = group.members.keys.map { Address.fromSerialized(it) }
|
val members = group.members.keys.map { Address.fromSerialized(it) }
|
||||||
val admins = group.members.filter { it.value /*admin = true*/ }.keys.map { Address.fromSerialized(it) }
|
val admins = group.members.filter { it.value /*admin = true*/ }.keys.map { Address.fromSerialized(it) }
|
||||||
val groupId = GroupUtil.doubleEncodeGroupID(group.sessionId)
|
|
||||||
val title = group.name
|
val title = group.name
|
||||||
val formationTimestamp = (group.joinedAt * 1000L)
|
val formationTimestamp = (group.joinedAt * 1000L)
|
||||||
createGroup(groupId, title, admins + members, null, null, admins, formationTimestamp)
|
createGroup(groupId, title, admins + members, null, null, admins, formationTimestamp)
|
||||||
@ -616,6 +621,17 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co
|
|||||||
// Start polling
|
// Start polling
|
||||||
ClosedGroupPollerV2.shared.startPolling(group.sessionId)
|
ClosedGroupPollerV2.shared.startPolling(group.sessionId)
|
||||||
}
|
}
|
||||||
|
getThreadId(Address.fromSerialized(groupId))?.let { conversationThreadId ->
|
||||||
|
val mode =
|
||||||
|
if (group.disappearingTimer == 0L) ExpiryMode.NONE
|
||||||
|
else ExpiryMode.AfterRead(group.disappearingTimer)
|
||||||
|
val newConfig = ExpirationConfiguration(
|
||||||
|
conversationThreadId, mode, messageTimestamp
|
||||||
|
)
|
||||||
|
DatabaseComponent.get(context)
|
||||||
|
.expirationConfigurationDatabase()
|
||||||
|
.setExpirationConfiguration(newConfig)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1163,7 +1179,7 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co
|
|||||||
return if (recipientSettings.isPresent) { recipientSettings.get() } else null
|
return if (recipientSettings.isPresent) { recipientSettings.get() } else null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addLibSessionContacts(contacts: List<LibSessionContact>) {
|
override fun addLibSessionContacts(contacts: List<LibSessionContact>, timestamp: Long) {
|
||||||
val mappingDb = DatabaseComponent.get(context).blindedIdMappingDatabase()
|
val mappingDb = DatabaseComponent.get(context).blindedIdMappingDatabase()
|
||||||
val moreContacts = contacts.filter { contact ->
|
val moreContacts = contacts.filter { contact ->
|
||||||
val id = SessionId(contact.id)
|
val id = SessionId(contact.id)
|
||||||
@ -1204,6 +1220,15 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co
|
|||||||
setPinned(conversationThreadId, contact.priority == PRIORITY_PINNED)
|
setPinned(conversationThreadId, contact.priority == PRIORITY_PINNED)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
getThreadId(recipient)?.let { conversationThreadId ->
|
||||||
|
val expiration = ExpirationConfiguration(
|
||||||
|
conversationThreadId,
|
||||||
|
contact.expiryMode,
|
||||||
|
timestamp
|
||||||
|
)
|
||||||
|
DatabaseComponent.get(context).expirationConfigurationDatabase()
|
||||||
|
.setExpirationConfiguration(expiration)
|
||||||
|
}
|
||||||
setRecipientHash(recipient, contact.hashCode().toString())
|
setRecipientHash(recipient, contact.hashCode().toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1676,7 +1701,15 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co
|
|||||||
override fun getExpirationConfiguration(threadId: Long): ExpirationConfiguration? {
|
override fun getExpirationConfiguration(threadId: Long): ExpirationConfiguration? {
|
||||||
val recipient = getRecipientForThread(threadId) ?: return null
|
val recipient = getRecipientForThread(threadId) ?: return null
|
||||||
val dbExpirationMetadata = DatabaseComponent.get(context).expirationConfigurationDatabase().getExpirationConfiguration(threadId) ?: return null
|
val dbExpirationMetadata = DatabaseComponent.get(context).expirationConfigurationDatabase().getExpirationConfiguration(threadId) ?: return null
|
||||||
return if (recipient.isContactRecipient && recipient.address.serialize().startsWith(IdPrefix.STANDARD.value)) {
|
return if (recipient.isLocalNumber) {
|
||||||
|
configFactory.user?.getNtsExpiry()?.let { mode ->
|
||||||
|
ExpirationConfiguration(
|
||||||
|
threadId,
|
||||||
|
mode,
|
||||||
|
dbExpirationMetadata.updatedTimestampMs
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else if (recipient.isContactRecipient && recipient.address.serialize().startsWith(IdPrefix.STANDARD.value)) {
|
||||||
// read it from contacts config if exists
|
// read it from contacts config if exists
|
||||||
configFactory.contacts?.get(recipient.address.serialize())?.let { contact ->
|
configFactory.contacts?.get(recipient.address.serialize())?.let { contact ->
|
||||||
val mode = contact.expiryMode
|
val mode = contact.expiryMode
|
||||||
@ -1703,11 +1736,26 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co
|
|||||||
override fun setExpirationConfiguration(config: ExpirationConfiguration) {
|
override fun setExpirationConfiguration(config: ExpirationConfiguration) {
|
||||||
val recipient = getRecipientForThread(config.threadId) ?: return
|
val recipient = getRecipientForThread(config.threadId) ?: return
|
||||||
if (recipient.isClosedGroupRecipient) {
|
if (recipient.isClosedGroupRecipient) {
|
||||||
configFactory.userGroups?.getLegacyGroupInfo()
|
val userGroups = configFactory.userGroups ?: return
|
||||||
|
val groupPublicKey = GroupUtil.addressToGroupSessionId(recipient.address)
|
||||||
|
val expiryMode = config.expiryMode
|
||||||
|
val groupInfo = userGroups.getLegacyGroupInfo(groupPublicKey)?.let { info ->
|
||||||
|
info.copy(disappearingTimer = when (expiryMode) {
|
||||||
|
null, ExpiryMode.NONE -> 0
|
||||||
|
else -> expiryMode.expirySeconds
|
||||||
|
})
|
||||||
|
} ?: return
|
||||||
|
userGroups.set(groupInfo)
|
||||||
} else if (recipient.isLocalNumber) {
|
} else if (recipient.isLocalNumber) {
|
||||||
|
val user = configFactory.user ?: return
|
||||||
|
user.setNtsExpiry(config.expiryMode ?: ExpiryMode.NONE)
|
||||||
} else if (recipient.isContactRecipient) {
|
} else if (recipient.isContactRecipient) {
|
||||||
|
val contacts = configFactory.contacts ?: return
|
||||||
|
val expiry = config.expiryMode
|
||||||
|
val contact = contacts.get(recipient.address.serialize())?.copy(
|
||||||
|
expiryMode = expiry ?: ExpiryMode.NONE
|
||||||
|
) ?: return
|
||||||
|
contacts.set(contact)
|
||||||
}
|
}
|
||||||
DatabaseComponent.get(context).expirationConfigurationDatabase().setExpirationConfiguration(config)
|
DatabaseComponent.get(context).expirationConfigurationDatabase().setExpirationConfiguration(config)
|
||||||
}
|
}
|
||||||
|
@ -187,7 +187,7 @@ class ConfigFactory(
|
|||||||
override fun persist(forConfigObject: ConfigBase, timestamp: Long) {
|
override fun persist(forConfigObject: ConfigBase, timestamp: Long) {
|
||||||
try {
|
try {
|
||||||
listeners.forEach { listener ->
|
listeners.forEach { listener ->
|
||||||
listener.notifyUpdates(forConfigObject)
|
listener.notifyUpdates(forConfigObject, timestamp)
|
||||||
}
|
}
|
||||||
when (forConfigObject) {
|
when (forConfigObject) {
|
||||||
is UserProfile -> persistUserConfigDump(timestamp)
|
is UserProfile -> persistUserConfigDump(timestamp)
|
||||||
|
@ -96,3 +96,27 @@ Java_network_loki_messenger_libsession_1util_UserProfile_getNtsPriority(JNIEnv *
|
|||||||
auto profile = ptrToProfile(env, thiz);
|
auto profile = ptrToProfile(env, thiz);
|
||||||
return profile->get_nts_priority();
|
return profile->get_nts_priority();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT void JNICALL
|
||||||
|
Java_network_loki_messenger_libsession_1util_UserProfile_setNtsExpiry(JNIEnv *env, jobject thiz,
|
||||||
|
jobject expiry_mode) {
|
||||||
|
std::lock_guard lock{util::util_mutex_};
|
||||||
|
auto profile = ptrToProfile(env, thiz);
|
||||||
|
auto expiry = util::deserialize_expiry(env, expiry_mode);
|
||||||
|
profile->set_nts_expiry(std::chrono::seconds (expiry.second));
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jobject JNICALL
|
||||||
|
Java_network_loki_messenger_libsession_1util_UserProfile_getNtsExpiry(JNIEnv *env, jobject thiz) {
|
||||||
|
std::lock_guard lock{util::util_mutex_};
|
||||||
|
auto profile = ptrToProfile(env, thiz);
|
||||||
|
auto nts_expiry = profile->get_nts_expiry();
|
||||||
|
if (nts_expiry == std::nullopt) {
|
||||||
|
auto expiry = util::serialize_expiry(env, session::config::expiration_mode::none, std::chrono::seconds(0));
|
||||||
|
return expiry;
|
||||||
|
}
|
||||||
|
auto expiry = util::serialize_expiry(env, session::config::expiration_mode::after_send, std::chrono::seconds(*nts_expiry));
|
||||||
|
return expiry;
|
||||||
|
}
|
||||||
|
@ -4,6 +4,7 @@ import network.loki.messenger.libsession_util.util.BaseCommunityInfo
|
|||||||
import network.loki.messenger.libsession_util.util.ConfigPush
|
import network.loki.messenger.libsession_util.util.ConfigPush
|
||||||
import network.loki.messenger.libsession_util.util.Contact
|
import network.loki.messenger.libsession_util.util.Contact
|
||||||
import network.loki.messenger.libsession_util.util.Conversation
|
import network.loki.messenger.libsession_util.util.Conversation
|
||||||
|
import network.loki.messenger.libsession_util.util.ExpiryMode
|
||||||
import network.loki.messenger.libsession_util.util.GroupInfo
|
import network.loki.messenger.libsession_util.util.GroupInfo
|
||||||
import network.loki.messenger.libsession_util.util.UserPic
|
import network.loki.messenger.libsession_util.util.UserPic
|
||||||
import org.session.libsignal.protos.SignalServiceProtos.SharedConfigMessage.Kind
|
import org.session.libsignal.protos.SignalServiceProtos.SharedConfigMessage.Kind
|
||||||
@ -126,6 +127,8 @@ class UserProfile(pointer: Long) : ConfigBase(pointer) {
|
|||||||
external fun setPic(userPic: UserPic)
|
external fun setPic(userPic: UserPic)
|
||||||
external fun setNtsPriority(priority: Int)
|
external fun setNtsPriority(priority: Int)
|
||||||
external fun getNtsPriority(): Int
|
external fun getNtsPriority(): Int
|
||||||
|
external fun setNtsExpiry(expiryMode: ExpiryMode)
|
||||||
|
external fun getNtsExpiry(): ExpiryMode
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConversationVolatileConfig(pointer: Long): ConfigBase(pointer) {
|
class ConversationVolatileConfig(pointer: Long): ConfigBase(pointer) {
|
||||||
|
@ -182,7 +182,7 @@ interface StorageProtocol {
|
|||||||
fun setContact(contact: Contact)
|
fun setContact(contact: Contact)
|
||||||
fun getRecipientForThread(threadId: Long): Recipient?
|
fun getRecipientForThread(threadId: Long): Recipient?
|
||||||
fun getRecipientSettings(address: Address): RecipientSettings?
|
fun getRecipientSettings(address: Address): RecipientSettings?
|
||||||
fun addLibSessionContacts(contacts: List<LibSessionContact>)
|
fun addLibSessionContacts(contacts: List<LibSessionContact>, timestamp: Long)
|
||||||
fun addContacts(contacts: List<ConfigurationMessage.Contact>)
|
fun addContacts(contacts: List<ConfigurationMessage.Contact>)
|
||||||
|
|
||||||
// Attachments
|
// Attachments
|
||||||
@ -229,7 +229,7 @@ interface StorageProtocol {
|
|||||||
fun updateDisappearingState(threadID: Long, disappearingState: Recipient.DisappearingState)
|
fun updateDisappearingState(threadID: Long, disappearingState: Recipient.DisappearingState)
|
||||||
|
|
||||||
// Shared configs
|
// Shared configs
|
||||||
fun notifyConfigUpdates(forConfigObject: ConfigBase)
|
fun notifyConfigUpdates(forConfigObject: ConfigBase, messageTimestamp: Long)
|
||||||
fun conversationInConfig(publicKey: String?, groupPublicKey: String?, openGroupId: String?, visibleOnly: Boolean): Boolean
|
fun conversationInConfig(publicKey: String?, groupPublicKey: String?, openGroupId: String?, visibleOnly: Boolean): Boolean
|
||||||
fun canPerformConfigChange(variant: String, publicKey: String, changeTimestampMs: Long): Boolean
|
fun canPerformConfigChange(variant: String, publicKey: String, changeTimestampMs: Long): Boolean
|
||||||
}
|
}
|
||||||
|
@ -65,11 +65,13 @@ abstract class Message {
|
|||||||
if (config.isEnabled && config.expiryMode != null) {
|
if (config.isEnabled && config.expiryMode != null) {
|
||||||
expirationTimer = config.expiryMode.expirySeconds.toInt()
|
expirationTimer = config.expiryMode.expirySeconds.toInt()
|
||||||
lastDisappearingMessageChangeTimestamp = config.updatedTimestampMs
|
lastDisappearingMessageChangeTimestamp = config.updatedTimestampMs
|
||||||
config.expiryMode.let { expiryMode ->
|
if (ExpirationConfiguration.isNewConfigEnabled) {
|
||||||
when (expiryMode) {
|
config.expiryMode.let { expiryMode ->
|
||||||
is ExpiryMode.AfterSend -> expirationType = ExpirationType.DELETE_AFTER_SEND
|
when (expiryMode) {
|
||||||
is ExpiryMode.AfterRead -> expirationType = ExpirationType.DELETE_AFTER_READ
|
is ExpiryMode.AfterSend -> expirationType = ExpirationType.DELETE_AFTER_SEND
|
||||||
ExpiryMode.NONE -> { /* do nothing */ }
|
is ExpiryMode.AfterRead -> expirationType = ExpirationType.DELETE_AFTER_READ
|
||||||
|
ExpiryMode.NONE -> { /* do nothing */ }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@ package org.session.libsession.messaging.messages.control
|
|||||||
import org.session.libsession.messaging.MessagingModuleConfiguration
|
import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||||
import org.session.libsession.messaging.messages.ExpirationConfiguration
|
import org.session.libsession.messaging.messages.ExpirationConfiguration
|
||||||
import org.session.libsession.messaging.messages.visible.VisibleMessage
|
import org.session.libsession.messaging.messages.visible.VisibleMessage
|
||||||
import org.session.libsignal.utilities.Log
|
|
||||||
import org.session.libsignal.protos.SignalServiceProtos
|
import org.session.libsignal.protos.SignalServiceProtos
|
||||||
|
import org.session.libsignal.utilities.Log
|
||||||
|
|
||||||
class ExpirationTimerUpdate() : ControlMessage() {
|
class ExpirationTimerUpdate() : ControlMessage() {
|
||||||
/** In the case of a sync message, the public key of the person the message was targeted at.
|
/** In the case of a sync message, the public key of the person the message was targeted at.
|
||||||
@ -26,7 +26,9 @@ class ExpirationTimerUpdate() : ControlMessage() {
|
|||||||
|
|
||||||
fun fromProto(proto: SignalServiceProtos.Content): ExpirationTimerUpdate? {
|
fun fromProto(proto: SignalServiceProtos.Content): ExpirationTimerUpdate? {
|
||||||
val dataMessageProto = if (proto.hasDataMessage()) proto.dataMessage else return null
|
val dataMessageProto = if (proto.hasDataMessage()) proto.dataMessage else return null
|
||||||
val isExpirationTimerUpdate = dataMessageProto.flags.and(SignalServiceProtos.DataMessage.Flags.EXPIRATION_TIMER_UPDATE_VALUE) != 0
|
val isExpirationTimerUpdate = dataMessageProto.flags.and(
|
||||||
|
SignalServiceProtos.DataMessage.Flags.EXPIRATION_TIMER_UPDATE_VALUE
|
||||||
|
) != 0
|
||||||
if (!isExpirationTimerUpdate) return null
|
if (!isExpirationTimerUpdate) return null
|
||||||
val syncTarget = dataMessageProto.syncTarget
|
val syncTarget = dataMessageProto.syncTarget
|
||||||
val duration = if (proto.hasExpirationTimer()) proto.expirationTimer else dataMessageProto.expireTimer
|
val duration = if (proto.hasExpirationTimer()) proto.expirationTimer else dataMessageProto.expireTimer
|
||||||
|
@ -69,7 +69,7 @@ fun MessageReceiver.handle(message: Message, proto: SignalServiceProtos.Content,
|
|||||||
// Do nothing if the message was outdated
|
// Do nothing if the message was outdated
|
||||||
if (MessageReceiver.messageIsOutdated(message, threadId, openGroupID)) { return }
|
if (MessageReceiver.messageIsOutdated(message, threadId, openGroupID)) { return }
|
||||||
|
|
||||||
MessageReceiver.updateExpiryIfNeeded(message, proto, openGroupID, )
|
MessageReceiver.updateExpiryIfNeeded(message, proto, openGroupID)
|
||||||
when (message) {
|
when (message) {
|
||||||
is ReadReceipt -> handleReadReceipt(message)
|
is ReadReceipt -> handleReadReceipt(message)
|
||||||
is TypingIndicator -> handleTypingIndicator(message)
|
is TypingIndicator -> handleTypingIndicator(message)
|
||||||
|
@ -19,5 +19,5 @@ interface ConfigFactoryProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface ConfigFactoryUpdateListener {
|
interface ConfigFactoryUpdateListener {
|
||||||
fun notifyUpdates(forConfigObject: ConfigBase)
|
fun notifyUpdates(forConfigObject: ConfigBase, messageTimestamp: Long)
|
||||||
}
|
}
|
@ -1,6 +1,5 @@
|
|||||||
package org.session.libsession.utilities
|
package org.session.libsession.utilities
|
||||||
|
|
||||||
import network.loki.messenger.libsession_util.util.GroupInfo
|
|
||||||
import org.session.libsignal.messages.SignalServiceGroup
|
import org.session.libsignal.messages.SignalServiceGroup
|
||||||
import org.session.libsignal.utilities.Hex
|
import org.session.libsignal.utilities.Hex
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
@ -104,6 +103,11 @@ object GroupUtil {
|
|||||||
return Hex.toStringCondensed(getDecodedGroupIDAsData(getDecodedGroupID(groupID)))
|
return Hex.toStringCondensed(getDecodedGroupIDAsData(getDecodedGroupID(groupID)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun addressToGroupSessionId(address: Address): String {
|
||||||
|
return doubleDecodeGroupId(address.toGroupString())
|
||||||
|
}
|
||||||
|
|
||||||
fun createConfigMemberMap(
|
fun createConfigMemberMap(
|
||||||
members: Collection<String>,
|
members: Collection<String>,
|
||||||
admins: Collection<String>
|
admins: Collection<String>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user