mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-31 07:16:13 +00:00
refactor: moving the trusted download dialogs and logic to be auto-download and show visibilities based on download status not trusted status
This commit is contained in:
@@ -15,13 +15,14 @@ import org.session.libsession.messaging.jobs.JobQueue
|
||||
import org.session.libsession.utilities.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog
|
||||
import org.thoughtcrime.securesms.database.SessionContactDatabase
|
||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
|
||||
import javax.inject.Inject
|
||||
|
||||
/** Shown when receiving media from a contact for the first time, to confirm that
|
||||
* they are to be trusted and files sent by them are to be downloaded. */
|
||||
@AndroidEntryPoint
|
||||
class DownloadDialog(private val recipient: Recipient) : BaseDialog() {
|
||||
class DownloadDialog(private val recipient: Recipient,
|
||||
private val
|
||||
) : BaseDialog() {
|
||||
|
||||
@Inject lateinit var contactDB: SessionContactDatabase
|
||||
|
||||
@@ -43,10 +44,6 @@ class DownloadDialog(private val recipient: Recipient) : BaseDialog() {
|
||||
}
|
||||
|
||||
private fun trust() {
|
||||
val sessionID = recipient.address.toString()
|
||||
val contact = contactDB.getContactWithSessionID(sessionID) ?: return
|
||||
val threadID = DatabaseComponent.get(requireContext()).threadDatabase().getThreadIdIfExistsFor(recipient)
|
||||
contactDB.setContactIsTrusted(contact, true, threadID)
|
||||
JobQueue.shared.resumePendingJobs(AttachmentDownloadJob.KEY)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
@@ -6,20 +6,23 @@ import android.widget.LinearLayout
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.core.content.ContextCompat
|
||||
import network.loki.messenger.R
|
||||
import network.loki.messenger.databinding.ViewUntrustedAttachmentBinding
|
||||
import network.loki.messenger.databinding.ViewPendingAttachmentBinding
|
||||
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId
|
||||
import org.session.libsession.utilities.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.conversation.v2.dialogs.DownloadDialog
|
||||
import org.thoughtcrime.securesms.util.ActivityDispatcher
|
||||
import java.util.Locale
|
||||
|
||||
class UntrustedAttachmentView: LinearLayout {
|
||||
private val binding: ViewUntrustedAttachmentBinding by lazy { ViewUntrustedAttachmentBinding.bind(this) }
|
||||
class PendingAttachmentView: LinearLayout {
|
||||
private val binding by lazy { ViewPendingAttachmentBinding.bind(this) }
|
||||
enum class AttachmentType {
|
||||
AUDIO,
|
||||
DOCUMENT,
|
||||
MEDIA
|
||||
}
|
||||
|
||||
private var attachmentId: AttachmentId? = null
|
||||
|
||||
// region Lifecycle
|
||||
constructor(context: Context) : super(context)
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
|
||||
@@ -28,7 +31,7 @@ class UntrustedAttachmentView: LinearLayout {
|
||||
// endregion
|
||||
|
||||
// region Updating
|
||||
fun bind(attachmentType: AttachmentType, @ColorInt textColor: Int) {
|
||||
fun bind(attachmentType: AttachmentType, @ColorInt textColor: Int, attachmentId: AttachmentId) {
|
||||
val (iconRes, stringRes) = when (attachmentType) {
|
||||
AttachmentType.AUDIO -> R.drawable.ic_microphone to R.string.Slide_audio
|
||||
AttachmentType.DOCUMENT -> R.drawable.ic_document_large_light to R.string.document
|
||||
@@ -40,12 +43,15 @@ class UntrustedAttachmentView: LinearLayout {
|
||||
|
||||
binding.untrustedAttachmentIcon.setImageDrawable(iconDrawable)
|
||||
binding.untrustedAttachmentTitle.text = text
|
||||
this.attachmentId = attachmentId
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region Interaction
|
||||
fun showTrustDialog(recipient: Recipient) {
|
||||
ActivityDispatcher.get(context)?.showDialog(DownloadDialog(recipient))
|
||||
fun showDownloadDialog(threadRecipient: Recipient) {
|
||||
attachmentId?.let { attachmentId ->
|
||||
ActivityDispatcher.get(context)?.showDialog(DownloadDialog(threadRecipient, attachmentId))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -40,7 +40,6 @@ import org.thoughtcrime.securesms.conversation.v2.utilities.ModalURLSpan
|
||||
import org.thoughtcrime.securesms.conversation.v2.utilities.TextUtilities.getIntersectedModalSpans
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||
import org.thoughtcrime.securesms.database.model.SmsMessageRecord
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||
import org.thoughtcrime.securesms.util.SearchUtil
|
||||
import org.thoughtcrime.securesms.util.getAccentColor
|
||||
@@ -66,7 +65,7 @@ class VisibleMessageContentView : LinearLayout {
|
||||
|
||||
// region Updating
|
||||
fun bind(message: MessageRecord, isStartOfMessageCluster: Boolean, isEndOfMessageCluster: Boolean,
|
||||
glide: GlideRequests, thread: Recipient, searchQuery: String?, contactIsTrusted: Boolean) {
|
||||
glide: GlideRequests, thread: Recipient, searchQuery: String?, autoDownloadAttachments: Boolean) {
|
||||
// Background
|
||||
val background = getBackground(message.isOutgoing)
|
||||
val color = if (message.isOutgoing) context.getAccentColor()
|
||||
@@ -75,8 +74,8 @@ class VisibleMessageContentView : LinearLayout {
|
||||
background.colorFilter = filter
|
||||
binding.contentParent.background = background
|
||||
|
||||
val onlyBodyMessage = message is SmsMessageRecord
|
||||
val mediaThumbnailMessage = contactIsTrusted && message is MmsMessageRecord && message.slideDeck.thumbnailSlide != null
|
||||
val mediaDownloaded = message is MmsMessageRecord && message.slideDeck.asAttachments().all { it.transferState == AttachmentTransferProgress.TRANSFER_PROGRESS_DONE }
|
||||
val mediaThumbnailMessage = message is MmsMessageRecord && message.slideDeck.thumbnailSlide != null
|
||||
|
||||
// reset visibilities / containers
|
||||
onContentClick.clear()
|
||||
@@ -98,9 +97,9 @@ class VisibleMessageContentView : LinearLayout {
|
||||
|
||||
binding.linkPreviewView.isVisible = message is MmsMessageRecord && message.linkPreviews.isNotEmpty()
|
||||
|
||||
binding.untrustedView.root.isVisible = !contactIsTrusted && message is MmsMessageRecord && message.quote == null && message.linkPreviews.isEmpty()
|
||||
binding.voiceMessageView.root.isVisible = contactIsTrusted && message is MmsMessageRecord && message.slideDeck.audioSlide != null
|
||||
binding.documentView.root.isVisible = contactIsTrusted && message is MmsMessageRecord && message.slideDeck.documentSlide != null
|
||||
binding.pendingAttachmentView.root.isVisible = !mediaDownloaded && message is MmsMessageRecord && message.quote == null && message.linkPreviews.isEmpty()
|
||||
binding.voiceMessageView.root.isVisible = mediaDownloaded && message is MmsMessageRecord && message.slideDeck.audioSlide != null
|
||||
binding.documentView.root.isVisible = mediaDownloaded && message is MmsMessageRecord && message.slideDeck.documentSlide != null
|
||||
binding.albumThumbnailView.isVisible = mediaThumbnailMessage
|
||||
binding.openGroupInvitationView.root.isVisible = message.isOpenGroupInvitation
|
||||
|
||||
@@ -124,7 +123,6 @@ class VisibleMessageContentView : LinearLayout {
|
||||
delegate?.scrollToMessageIfPossible(quote.id)
|
||||
}
|
||||
}
|
||||
val hasMedia = message.slideDeck.asAttachments().isNotEmpty()
|
||||
}
|
||||
|
||||
if (message is MmsMessageRecord) {
|
||||
@@ -156,7 +154,7 @@ class VisibleMessageContentView : LinearLayout {
|
||||
message is MmsMessageRecord && message.slideDeck.audioSlide != null -> {
|
||||
hideBody = true
|
||||
// Audio attachment
|
||||
if (contactIsTrusted || message.isOutgoing) {
|
||||
if (mediaDownloaded || message.isOutgoing) {
|
||||
binding.voiceMessageView.root.indexInAdapter = indexInAdapter
|
||||
binding.voiceMessageView.root.delegate = context as? ConversationActivityV2
|
||||
binding.voiceMessageView.root.bind(message, isStartOfMessageCluster, isEndOfMessageCluster)
|
||||
@@ -165,26 +163,33 @@ class VisibleMessageContentView : LinearLayout {
|
||||
onContentClick.add { binding.voiceMessageView.root.togglePlayback() }
|
||||
onContentDoubleTap = { binding.voiceMessageView.root.handleDoubleTap() }
|
||||
} else {
|
||||
// TODO: move this out to its own area
|
||||
binding.untrustedView.root.bind(UntrustedAttachmentView.AttachmentType.AUDIO, VisibleMessageContentView.getTextColor(context,message))
|
||||
onContentClick.add { binding.untrustedView.root.showTrustDialog(message.individualRecipient) }
|
||||
binding.pendingAttachmentView.root.bind(
|
||||
PendingAttachmentView.AttachmentType.AUDIO,
|
||||
getTextColor(context,message),
|
||||
|
||||
)
|
||||
onContentClick.add { binding.pendingAttachmentView.root.showDownloadDialog(message.recipient) }
|
||||
}
|
||||
}
|
||||
message is MmsMessageRecord && message.slideDeck.documentSlide != null -> {
|
||||
hideBody = true
|
||||
// Document attachment
|
||||
if (contactIsTrusted || message.isOutgoing) {
|
||||
binding.documentView.root.bind(message, VisibleMessageContentView.getTextColor(context, message))
|
||||
if (mediaDownloaded || message.isOutgoing) {
|
||||
binding.documentView.root.bind(message, getTextColor(context, message))
|
||||
} else {
|
||||
binding.untrustedView.root.bind(UntrustedAttachmentView.AttachmentType.DOCUMENT, VisibleMessageContentView.getTextColor(context,message))
|
||||
onContentClick.add { binding.untrustedView.root.showTrustDialog(message.individualRecipient) }
|
||||
binding.pendingAttachmentView.root.bind(
|
||||
PendingAttachmentView.AttachmentType.DOCUMENT,
|
||||
getTextColor(context,message),
|
||||
|
||||
)
|
||||
onContentClick.add { binding.pendingAttachmentView.root.showDownloadDialog(message.recipient) }
|
||||
}
|
||||
}
|
||||
message is MmsMessageRecord && message.slideDeck.asAttachments().isNotEmpty() -> {
|
||||
/*
|
||||
* Images / Video attachment
|
||||
*/
|
||||
if (contactIsTrusted || message.isOutgoing) {
|
||||
if (mediaDownloaded || message.isOutgoing) {
|
||||
// isStart and isEnd of cluster needed for calculating the mask for full bubble image groups
|
||||
// bind after add view because views are inflated and calculated during bind
|
||||
binding.albumThumbnailView.bind(
|
||||
@@ -202,13 +207,17 @@ class VisibleMessageContentView : LinearLayout {
|
||||
} else {
|
||||
hideBody = true
|
||||
binding.albumThumbnailView.clearViews()
|
||||
binding.untrustedView.root.bind(UntrustedAttachmentView.AttachmentType.MEDIA, VisibleMessageContentView.getTextColor(context,message))
|
||||
onContentClick.add { binding.untrustedView.root.showTrustDialog(message.individualRecipient) }
|
||||
binding.pendingAttachmentView.root.bind(
|
||||
PendingAttachmentView.AttachmentType.MEDIA,
|
||||
getTextColor(context,message),
|
||||
|
||||
)
|
||||
onContentClick.add { binding.pendingAttachmentView.root.showDownloadDialog(message.recipient) }
|
||||
}
|
||||
}
|
||||
message.isOpenGroupInvitation -> {
|
||||
hideBody = true
|
||||
binding.openGroupInvitationView.root.bind(message, VisibleMessageContentView.getTextColor(context, message))
|
||||
binding.openGroupInvitationView.root.bind(message, getTextColor(context, message))
|
||||
onContentClick.add { binding.openGroupInvitationView.root.joinOpenGroup() }
|
||||
}
|
||||
}
|
||||
@@ -243,7 +252,7 @@ class VisibleMessageContentView : LinearLayout {
|
||||
fun recycle() {
|
||||
arrayOf(
|
||||
binding.deletedMessageView.root,
|
||||
binding.untrustedView.root,
|
||||
binding.pendingAttachmentView.root,
|
||||
binding.voiceMessageView.root,
|
||||
binding.openGroupInvitationView.root,
|
||||
binding.documentView.root,
|
||||
|
||||
@@ -685,9 +685,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
||||
}
|
||||
}
|
||||
|
||||
override fun shouldAutoDownloadAttachments(recipient: Recipient): Boolean {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
override fun shouldAutoDownloadAttachments(recipient: Recipient): Boolean = true
|
||||
|
||||
override fun setAutoDownloadAttachments(
|
||||
recipient: Recipient,
|
||||
|
||||
@@ -191,6 +191,9 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
||||
executeStatements(db, GroupReceiptDatabase.CREATE_INDEXES);
|
||||
|
||||
executeStatements(db, ReactionDatabase.CREATE_REACTION_TRIGGERS);
|
||||
|
||||
db.execSQL(RecipientDatabase.getCreateAutoDownloadCommand());
|
||||
db.execSQL(RecipientDatabase.getUpdateAutoDownloadValuesCommand());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.thoughtcrime.securesms.conversation.v2.messages.UntrustedAttachmentView
|
||||
<org.thoughtcrime.securesms.conversation.v2.messages.PendingAttachmentView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
@@ -27,4 +27,4 @@
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end" />
|
||||
|
||||
</org.thoughtcrime.securesms.conversation.v2.messages.UntrustedAttachmentView>
|
||||
</org.thoughtcrime.securesms.conversation.v2.messages.PendingAttachmentView>
|
||||
@@ -26,13 +26,13 @@
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
|
||||
<include layout="@layout/view_untrusted_attachment"
|
||||
<include layout="@layout/view_pending_attachment"
|
||||
tools:visibility="gone"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/untrustedView"
|
||||
android:id="@+id/pending_attachment_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
|
||||
@@ -119,6 +119,13 @@ message DataMessage {
|
||||
required string name = 3;
|
||||
}
|
||||
|
||||
message GroupMessage {
|
||||
optional GroupDeleteMessage deleteMessage = 31;
|
||||
optional GroupMemberLeftMessage memberLeftMessage = 32;
|
||||
optional GroupInviteMessage inviteMessage = 33;
|
||||
optional GroupPromoteMessage promoteMessage = 34;
|
||||
}
|
||||
|
||||
message ClosedGroupControlMessage {
|
||||
|
||||
enum Type {
|
||||
@@ -182,6 +189,34 @@ message DataMessage {
|
||||
optional OpenGroupInvitation openGroupInvitation = 102;
|
||||
optional ClosedGroupControlMessage closedGroupControlMessage = 104;
|
||||
optional string syncTarget = 105;
|
||||
optional GroupMessage groupMessage = 120;
|
||||
}
|
||||
|
||||
message GroupDeleteMessage {
|
||||
// @required
|
||||
required bytes publicKey = 1; // the identity public key of the group to be deleted
|
||||
// @required
|
||||
required bytes lastEncryptionKey = 2; // used by members to make sure incoming admin action can be trusted
|
||||
}
|
||||
|
||||
message GroupMemberLeftMessage {
|
||||
// the pubkey of the member left is included as part of the closed group encryption logic (senderIdentity on desktop)
|
||||
}
|
||||
|
||||
message GroupInviteMessage {
|
||||
// @required
|
||||
required bytes publicKey = 1; // this is the group public key
|
||||
// @required
|
||||
required string name = 2;
|
||||
// @required
|
||||
required bytes memberPrivateKey = 3;
|
||||
}
|
||||
|
||||
message GroupPromoteMessage {
|
||||
// @required
|
||||
required bytes publicKey = 1; // this is the session id for the user that should be promoted
|
||||
// @required
|
||||
required bytes encryptedPrivateKey = 2; // this is the group admins key
|
||||
}
|
||||
|
||||
message CallMessage {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user