mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-27 12:05:22 +00:00
Hide follow settings button when not applicable
This commit is contained in:
parent
cf0dbffafd
commit
988040b577
@ -0,0 +1,38 @@
|
|||||||
|
package org.thoughtcrime.securesms.conversation.disappearingmessages
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import network.loki.messenger.libsession_util.util.ExpiryMode
|
||||||
|
import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||||
|
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.snode.SnodeAPI
|
||||||
|
import org.session.libsession.utilities.Address
|
||||||
|
import org.session.libsession.utilities.SSKEnvironment
|
||||||
|
import org.session.libsession.utilities.SSKEnvironment.MessageExpirationManagerProtocol
|
||||||
|
import org.session.libsession.utilities.TextSecurePreferences
|
||||||
|
import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class DisappearingMessages @Inject constructor(
|
||||||
|
@ApplicationContext private val context: Context,
|
||||||
|
private val textSecurePreferences: TextSecurePreferences,
|
||||||
|
private val messageExpirationManager: MessageExpirationManagerProtocol,
|
||||||
|
) {
|
||||||
|
fun set(threadId: Long, address: Address, mode: ExpiryMode) {
|
||||||
|
val expiryChangeTimestampMs = SnodeAPI.nowWithOffset
|
||||||
|
MessagingModuleConfiguration.shared.storage.setExpirationConfiguration(ExpirationConfiguration(threadId, mode, expiryChangeTimestampMs))
|
||||||
|
|
||||||
|
val message = ExpirationTimerUpdate(mode).apply {
|
||||||
|
sender = textSecurePreferences.getLocalNumber()
|
||||||
|
isSenderSelf = true
|
||||||
|
recipient = address.serialize()
|
||||||
|
sentTimestamp = expiryChangeTimestampMs
|
||||||
|
}
|
||||||
|
|
||||||
|
messageExpirationManager.setExpirationTimer(message)
|
||||||
|
MessageSender.send(message, address)
|
||||||
|
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(context)
|
||||||
|
}
|
||||||
|
}
|
@ -99,7 +99,7 @@ class DisappearingMessagesViewModel(
|
|||||||
recipient = address.serialize()
|
recipient = address.serialize()
|
||||||
sentTimestamp = expiryChangeTimestampMs
|
sentTimestamp = expiryChangeTimestampMs
|
||||||
}
|
}
|
||||||
messageExpirationManager.setExpirationTimer(message, mode)
|
messageExpirationManager.setExpirationTimer(message)
|
||||||
MessageSender.send(message, address)
|
MessageSender.send(message, address)
|
||||||
|
|
||||||
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(application)
|
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(application)
|
||||||
|
@ -8,16 +8,26 @@ import androidx.core.content.res.ResourcesCompat
|
|||||||
import androidx.core.view.isGone
|
import androidx.core.view.isGone
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
import network.loki.messenger.databinding.ViewControlMessageBinding
|
import network.loki.messenger.databinding.ViewControlMessageBinding
|
||||||
|
import network.loki.messenger.libsession_util.util.ExpiryMode
|
||||||
|
import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||||
import org.session.libsession.messaging.messages.ExpirationConfiguration
|
import org.session.libsession.messaging.messages.ExpirationConfiguration
|
||||||
import org.session.libsession.utilities.ExpirationUtil.getExpirationDisplayValue
|
import org.session.libsession.utilities.ExpirationUtil.getExpirationDisplayValue
|
||||||
import org.session.libsession.utilities.getExpirationTypeDisplayValue
|
import org.session.libsession.utilities.getExpirationTypeDisplayValue
|
||||||
|
import org.thoughtcrime.securesms.conversation.disappearingmessages.DisappearingMessages
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||||
import org.thoughtcrime.securesms.showSessionDialog
|
import org.thoughtcrime.securesms.showSessionDialog
|
||||||
|
import javax.inject.Inject
|
||||||
import kotlin.time.Duration.Companion.milliseconds
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
|
private val MessageRecord.expiryMode get() = if (expiresIn <= 0) ExpiryMode.NONE
|
||||||
|
else if (expireStarted == timestamp) ExpiryMode.AfterSend(expiresIn / 1000)
|
||||||
|
else ExpiryMode.AfterRead(expiresIn / 1000)
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
class ControlMessageView : LinearLayout {
|
class ControlMessageView : LinearLayout {
|
||||||
|
|
||||||
private lateinit var binding: ViewControlMessageBinding
|
private lateinit var binding: ViewControlMessageBinding
|
||||||
@ -26,6 +36,8 @@ class ControlMessageView : LinearLayout {
|
|||||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { initialize() }
|
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { initialize() }
|
||||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { initialize() }
|
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { initialize() }
|
||||||
|
|
||||||
|
@Inject lateinit var disappearingMessages: DisappearingMessages
|
||||||
|
|
||||||
private fun initialize() {
|
private fun initialize() {
|
||||||
binding = ViewControlMessageBinding.inflate(LayoutInflater.from(context), this, true)
|
binding = ViewControlMessageBinding.inflate(LayoutInflater.from(context), this, true)
|
||||||
layoutParams = RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT)
|
layoutParams = RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT)
|
||||||
@ -42,24 +54,31 @@ class ControlMessageView : LinearLayout {
|
|||||||
message.isExpirationTimerUpdate -> {
|
message.isExpirationTimerUpdate -> {
|
||||||
binding.apply {
|
binding.apply {
|
||||||
expirationTimerView.isVisible = true
|
expirationTimerView.isVisible = true
|
||||||
|
|
||||||
|
|
||||||
expirationTimerView.setExpirationTime(message.expireStarted, message.expiresIn)
|
expirationTimerView.setExpirationTime(message.expireStarted, message.expiresIn)
|
||||||
followSetting.isVisible = ExpirationConfiguration.isNewConfigEnabled && !message.isOutgoing
|
|
||||||
|
followSetting.isVisible = ExpirationConfiguration.isNewConfigEnabled
|
||||||
|
&& !message.isOutgoing
|
||||||
|
&& message.expiryMode != (MessagingModuleConfiguration.shared.storage.getExpirationConfiguration(message.threadId)?.expiryMode ?: ExpiryMode.NONE)
|
||||||
|
|
||||||
followSetting.setOnClickListener {
|
followSetting.setOnClickListener {
|
||||||
context.showSessionDialog {
|
context.showSessionDialog {
|
||||||
val isOff = message.expiresIn == 0L
|
|
||||||
title(R.string.dialog_disappearing_messages_follow_setting_title)
|
title(R.string.dialog_disappearing_messages_follow_setting_title)
|
||||||
if (isOff) {
|
if (message.expiresIn == 0L) {
|
||||||
text(R.string.dialog_disappearing_messages_follow_setting_off_body)
|
text(R.string.dialog_disappearing_messages_follow_setting_off_body)
|
||||||
} else {
|
} else {
|
||||||
text(
|
text(
|
||||||
context.getString(
|
context.getString(
|
||||||
R.string.dialog_disappearing_messages_follow_setting_on_body,
|
R.string.dialog_disappearing_messages_follow_setting_on_body,
|
||||||
getExpirationDisplayValue(context, message.expiresIn.milliseconds),
|
getExpirationDisplayValue(context, message.expiresIn.milliseconds),
|
||||||
context.getExpirationTypeDisplayValue(message.expireStarted == message.timestamp)
|
context.getExpirationTypeDisplayValue(message.isNotDisappearAfterRead)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
destructiveButton(if (isOff) R.string.dialog_disappearing_messages_follow_setting_confirm else R.string.dialog_disappearing_messages_follow_setting_set) { }
|
destructiveButton(if (message.expiresIn == 0L) R.string.dialog_disappearing_messages_follow_setting_confirm else R.string.dialog_disappearing_messages_follow_setting_set) {
|
||||||
|
disappearingMessages.set(message.threadId, message.recipient.address, message.expiryMode)
|
||||||
|
}
|
||||||
cancelButton()
|
cancelButton()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import android.graphics.drawable.ColorDrawable
|
|||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
|
import android.util.Log
|
||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
import android.view.HapticFeedbackConstants
|
import android.view.HapticFeedbackConstants
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
@ -61,6 +62,8 @@ import kotlin.math.min
|
|||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
|
private const val TAG = "VisibleMessageView"
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class VisibleMessageView : LinearLayout {
|
class VisibleMessageView : LinearLayout {
|
||||||
|
|
||||||
@ -349,6 +352,8 @@ class VisibleMessageView : LinearLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun updateExpirationTimer(message: MessageRecord) {
|
private fun updateExpirationTimer(message: MessageRecord) {
|
||||||
|
Log.d(TAG, "updateExpirationTimer() called with: message = $message")
|
||||||
|
|
||||||
if (!message.isOutgoing) binding.messageStatusTextView.bringToFront()
|
if (!message.isOutgoing) binding.messageStatusTextView.bringToFront()
|
||||||
|
|
||||||
val expireStarted = message.expireStarted.takeIf { it > 0 } ?: SnodeAPI.nowWithOffset
|
val expireStarted = message.expireStarted.takeIf { it > 0 } ?: SnodeAPI.nowWithOffset
|
||||||
|
@ -54,6 +54,10 @@ public abstract class MessageRecord extends DisplayRecord {
|
|||||||
private final List<ReactionRecord> reactions;
|
private final List<ReactionRecord> reactions;
|
||||||
private final boolean hasMention;
|
private final boolean hasMention;
|
||||||
|
|
||||||
|
public final boolean isNotDisappearAfterRead() {
|
||||||
|
return expireStarted == getTimestamp();
|
||||||
|
}
|
||||||
|
|
||||||
public abstract boolean isMms();
|
public abstract boolean isMms();
|
||||||
public abstract boolean isMmsNotification();
|
public abstract boolean isMmsNotification();
|
||||||
|
|
||||||
|
@ -58,6 +58,8 @@ class MarkReadReceiver : BroadcastReceiver() {
|
|||||||
) {
|
) {
|
||||||
if (markedReadMessages.isEmpty()) return
|
if (markedReadMessages.isEmpty()) return
|
||||||
|
|
||||||
|
Log.d(TAG, "process() called with: context = $context, markedReadMessages = $markedReadMessages")
|
||||||
|
|
||||||
sendReadReceipts(context, markedReadMessages)
|
sendReadReceipts(context, markedReadMessages)
|
||||||
|
|
||||||
markedReadMessages.forEach { scheduleDeletion(context, it.expirationInfo) }
|
markedReadMessages.forEach { scheduleDeletion(context, it.expirationInfo) }
|
||||||
@ -119,6 +121,8 @@ class MarkReadReceiver : BroadcastReceiver() {
|
|||||||
context: Context,
|
context: Context,
|
||||||
hashToMessage: Map<String, MarkedMessageInfo>
|
hashToMessage: Map<String, MarkedMessageInfo>
|
||||||
) {
|
) {
|
||||||
|
Log.d(TAG, "fetchUpdatedExpiriesAndScheduleDeletion() called with: context = $context, hashToMessage = $hashToMessage")
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
val expiries = SnodeAPI.getExpiries(hashToMessage.keys.toList(), TextSecurePreferences.getLocalNumber(context)!!).get()["expiries"] as Map<String, Long>
|
val expiries = SnodeAPI.getExpiries(hashToMessage.keys.toList(), TextSecurePreferences.getLocalNumber(context)!!).get()["expiries"] as Map<String, Long>
|
||||||
hashToMessage.forEach { (hash, info) -> expiries[hash]?.let { scheduleDeletion(context, info.expirationInfo, it - info.expirationInfo.expireStarted) } }
|
hashToMessage.forEach { (hash, info) -> expiries[hash]?.let { scheduleDeletion(context, info.expirationInfo, it - info.expirationInfo.expireStarted) } }
|
||||||
@ -129,6 +133,8 @@ class MarkReadReceiver : BroadcastReceiver() {
|
|||||||
expirationInfo: ExpirationInfo,
|
expirationInfo: ExpirationInfo,
|
||||||
expiresIn: Long = expirationInfo.expiresIn
|
expiresIn: Long = expirationInfo.expiresIn
|
||||||
) {
|
) {
|
||||||
|
Log.d(TAG, "scheduleDeletion() called with: context = $context, expirationInfo = $expirationInfo, expiresIn = $expiresIn")
|
||||||
|
|
||||||
if (expiresIn <= 0 || expirationInfo.expireStarted > 0) return
|
if (expiresIn <= 0 || expirationInfo.expireStarted > 0) return
|
||||||
|
|
||||||
val now = SnodeAPI.nowWithOffset
|
val now = SnodeAPI.nowWithOffset
|
||||||
|
@ -62,7 +62,8 @@ class ExpiringMessageManager(context: Context) : MessageExpirationManagerProtoco
|
|||||||
synchronized(expiringMessageReferences) { (expiringMessageReferences as Object).notifyAll() }
|
synchronized(expiringMessageReferences) { (expiringMessageReferences as Object).notifyAll() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setExpirationTimer(message: ExpirationTimerUpdate, expiryMode: ExpiryMode?) {
|
override fun setExpirationTimer(message: ExpirationTimerUpdate) {
|
||||||
|
val expiryMode: ExpiryMode = message.expiryMode
|
||||||
Log.d(TAG, "setExpirationTimer() called with: message = $message, expiryMode = $expiryMode")
|
Log.d(TAG, "setExpirationTimer() called with: message = $message, expiryMode = $expiryMode")
|
||||||
|
|
||||||
val userPublicKey = getLocalNumber(context)
|
val userPublicKey = getLocalNumber(context)
|
||||||
|
@ -155,6 +155,7 @@ fun MessageReceiver.cancelTypingIndicatorsIfNeeded(senderPublicKey: String) {
|
|||||||
|
|
||||||
private fun MessageReceiver.handleExpirationTimerUpdate(message: ExpirationTimerUpdate) {
|
private fun MessageReceiver.handleExpirationTimerUpdate(message: ExpirationTimerUpdate) {
|
||||||
if (ExpirationConfiguration.isNewConfigEnabled) return
|
if (ExpirationConfiguration.isNewConfigEnabled) return
|
||||||
|
|
||||||
val module = MessagingModuleConfiguration.shared
|
val module = MessagingModuleConfiguration.shared
|
||||||
try {
|
try {
|
||||||
val threadId = fromSerialized(message.groupPublicKey?.let(::doubleEncodeGroupID) ?: message.sender!!)
|
val threadId = fromSerialized(message.groupPublicKey?.let(::doubleEncodeGroupID) ?: message.sender!!)
|
||||||
@ -170,7 +171,7 @@ private fun MessageReceiver.handleExpirationTimerUpdate(message: ExpirationTimer
|
|||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e("Loki", "Failed to update expiration configuration.")
|
Log.e("Loki", "Failed to update expiration configuration.")
|
||||||
}
|
}
|
||||||
SSKEnvironment.shared.messageExpirationManager.setExpirationTimer(message, message.expiryMode)
|
SSKEnvironment.shared.messageExpirationManager.setExpirationTimer(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MessageReceiver.handleDataExtractionNotification(message: DataExtractionNotification) {
|
private fun MessageReceiver.handleDataExtractionNotification(message: DataExtractionNotification) {
|
||||||
@ -298,24 +299,25 @@ fun MessageReceiver.updateExpiryIfNeeded(
|
|||||||
|
|
||||||
val lastDisappearingMessageChangeTimestamp = proto.lastDisappearingMessageChangeTimestamp
|
val lastDisappearingMessageChangeTimestamp = proto.lastDisappearingMessageChangeTimestamp
|
||||||
|
|
||||||
|
// don't update any values for open groups
|
||||||
|
if (recipient.isOpenGroupRecipient && type != null) throw MessageReceiver.Error.InvalidMessage
|
||||||
|
|
||||||
|
val incoming1on1 = recipient.isContactRecipient && !message.isSenderSelf
|
||||||
|
|
||||||
val remoteConfig = ExpirationConfiguration(
|
val remoteConfig = ExpirationConfiguration(
|
||||||
threadID,
|
threadID,
|
||||||
expiryMode,
|
expiryMode,
|
||||||
lastDisappearingMessageChangeTimestamp
|
lastDisappearingMessageChangeTimestamp
|
||||||
)
|
)
|
||||||
|
|
||||||
// don't update any values for open groups
|
remoteConfig.takeUnless { incoming1on1 }?.takeIf {
|
||||||
if (recipient.isOpenGroupRecipient && type != null) throw MessageReceiver.Error.InvalidMessage
|
|
||||||
|
|
||||||
remoteConfig.takeIf {
|
|
||||||
localConfig == null
|
localConfig == null
|
||||||
|| it.updatedTimestampMs > localConfig.updatedTimestampMs
|
|| it.updatedTimestampMs > localConfig.updatedTimestampMs
|
||||||
|| !isNewConfigEnabled && !proto.hasLastDisappearingMessageChangeTimestamp() }
|
|| !isNewConfigEnabled && !proto.hasLastDisappearingMessageChangeTimestamp()
|
||||||
?.let(storage::setExpirationConfiguration)
|
}?.let(storage::setExpirationConfiguration)
|
||||||
|
|
||||||
|
|
||||||
if (message is ExpirationTimerUpdate) {
|
if (message is ExpirationTimerUpdate) {
|
||||||
SSKEnvironment.shared.messageExpirationManager.setExpirationTimer(message, expiryMode)
|
SSKEnvironment.shared.messageExpirationManager.setExpirationTimer(message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ class SSKEnvironment(
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface MessageExpirationManagerProtocol {
|
interface MessageExpirationManagerProtocol {
|
||||||
fun setExpirationTimer(message: ExpirationTimerUpdate, expiryType: ExpiryMode?)
|
fun setExpirationTimer(message: ExpirationTimerUpdate)
|
||||||
fun startAnyExpiration(timestamp: Long, author: String, expireStartedAt: Long)
|
fun startAnyExpiration(timestamp: Long, author: String, expireStartedAt: Long)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user