mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-19 19:28:26 +00:00
messages: completed missing parts related to database calls
This commit is contained in:
parent
9afb32d3a2
commit
f642e76ca4
@ -12,6 +12,7 @@ public class DatabaseAttachment extends Attachment {
|
||||
private final long mmsId;
|
||||
private final boolean hasData;
|
||||
private final boolean hasThumbnail;
|
||||
private boolean isUploaded = false;
|
||||
|
||||
public DatabaseAttachment(AttachmentId attachmentId, long mmsId,
|
||||
boolean hasData, boolean hasThumbnail,
|
||||
@ -75,4 +76,12 @@ public class DatabaseAttachment extends Attachment {
|
||||
public boolean hasThumbnail() {
|
||||
return hasThumbnail;
|
||||
}
|
||||
|
||||
public boolean isUploaded() {
|
||||
return isUploaded;
|
||||
}
|
||||
|
||||
public void setUploaded(boolean uploaded) {
|
||||
isUploaded = uploaded;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,52 @@
|
||||
package org.thoughtcrime.securesms.attachments
|
||||
|
||||
import android.content.Context
|
||||
import com.google.protobuf.ByteString
|
||||
import org.session.libsession.database.dto.DatabaseAttachmentDTO
|
||||
import org.session.libsession.database.MessageDataProvider
|
||||
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
||||
import org.thoughtcrime.securesms.database.Database
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
|
||||
import org.thoughtcrime.securesms.util.MediaUtil
|
||||
|
||||
class DatabaseAttachmentProvider(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper), MessageDataProvider {
|
||||
override fun getAttachment(uniqueID: String): DatabaseAttachmentDTO? {
|
||||
|
||||
val attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context)
|
||||
val uniqueID = uniqueID.toLongOrNull() ?: return null
|
||||
val attachmentID = AttachmentId(0, uniqueID)
|
||||
val databaseAttachment = attachmentDatabase.getAttachment(attachmentID) ?: return null
|
||||
|
||||
return databaseAttachment.toDTO()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Extension to DatabaseAttachment class
|
||||
|
||||
fun DatabaseAttachment.toDTO(): DatabaseAttachmentDTO {
|
||||
var databaseAttachmentDTO = DatabaseAttachmentDTO()
|
||||
databaseAttachmentDTO.contentType = this.contentType
|
||||
databaseAttachmentDTO.fileName = this.fileName
|
||||
databaseAttachmentDTO.caption = this.caption
|
||||
|
||||
databaseAttachmentDTO.size = this.size.toInt()
|
||||
databaseAttachmentDTO.key = ByteString.copyFrom(this.key?.toByteArray())
|
||||
databaseAttachmentDTO.digest = ByteString.copyFrom(this.digest)
|
||||
databaseAttachmentDTO.flags = if (this.isVoiceNote) SignalServiceProtos.AttachmentPointer.Flags.VOICE_MESSAGE.number else 0
|
||||
|
||||
databaseAttachmentDTO.url = this.url
|
||||
|
||||
if (this.shouldHaveImageSize()) {
|
||||
databaseAttachmentDTO.shouldHaveImageSize = true
|
||||
databaseAttachmentDTO.width = this.width
|
||||
databaseAttachmentDTO.height = this.height
|
||||
}
|
||||
|
||||
return databaseAttachmentDTO
|
||||
}
|
||||
|
||||
fun DatabaseAttachment.shouldHaveImageSize(): Boolean {
|
||||
return (MediaUtil.isVideo(this) || MediaUtil.isImage(this) || MediaUtil.isGif(this));
|
||||
}
|
@ -497,6 +497,7 @@ public class AttachmentDatabase extends Database {
|
||||
database.update(TABLE_NAME, values, PART_ID_WHERE, ((DatabaseAttachment)attachment).getAttachmentId().toStrings());
|
||||
|
||||
notifyConversationListeners(DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(messageId));
|
||||
((DatabaseAttachment) attachment).setUploaded(true);
|
||||
}
|
||||
|
||||
public void setTransferState(long messageId, @NonNull Attachment attachment, int transferState) {
|
||||
|
@ -0,0 +1,9 @@
|
||||
package org.session.libsession.database
|
||||
|
||||
import org.session.libsession.database.dto.DatabaseAttachmentDTO
|
||||
|
||||
interface MessageDataProvider {
|
||||
|
||||
fun getAttachment(uniqueID: String): DatabaseAttachmentDTO?
|
||||
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
package org.session.libsession.database.dto
|
||||
|
||||
import android.util.Size
|
||||
import com.google.protobuf.ByteString
|
||||
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
||||
import kotlin.math.round
|
||||
|
||||
class DatabaseAttachmentDTO {
|
||||
var contentType: String? = null
|
||||
|
||||
var fileName: String? = null
|
||||
|
||||
var url: String? = null
|
||||
|
||||
var caption: String? = null
|
||||
|
||||
var size: Int = 0
|
||||
|
||||
var key: ByteString? = null
|
||||
|
||||
var digest: ByteString? = null
|
||||
|
||||
var flags: Int = 0
|
||||
|
||||
var width: Int = 0
|
||||
|
||||
var height: Int = 0
|
||||
|
||||
val isVoiceNote: Boolean = false
|
||||
|
||||
var shouldHaveImageSize: Boolean = false
|
||||
|
||||
val isUploaded: Boolean = false
|
||||
|
||||
fun toProto(): SignalServiceProtos.AttachmentPointer? {
|
||||
val builder = org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer.newBuilder()
|
||||
builder.contentType = this.contentType
|
||||
|
||||
if (!this.fileName.isNullOrEmpty()) {
|
||||
builder.fileName = this.fileName
|
||||
}
|
||||
if (!this.caption.isNullOrEmpty()) {
|
||||
builder.caption = this.caption
|
||||
}
|
||||
|
||||
builder.size = this.size
|
||||
builder.key = this.key
|
||||
builder.digest = this.digest
|
||||
builder.flags = if (this.isVoiceNote) org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer.Flags.VOICE_MESSAGE.number else 0
|
||||
|
||||
//TODO I did copy the behavior of iOS below, not sure if that's relevant here...
|
||||
if (this.shouldHaveImageSize) {
|
||||
if (this.width < kotlin.Int.MAX_VALUE && this.height < kotlin.Int.MAX_VALUE) {
|
||||
val imageSize: Size = Size(this.width, this.height)
|
||||
val imageWidth = round(imageSize.width.toDouble())
|
||||
val imageHeight = round(imageSize.height.toDouble())
|
||||
if (imageWidth > 0 && imageHeight > 0) {
|
||||
builder.width = imageWidth.toInt()
|
||||
builder.height = imageHeight.toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
builder.url = this.url
|
||||
|
||||
try {
|
||||
return builder.build()
|
||||
} catch (e: Exception) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -12,7 +12,7 @@ abstract class Message<T: com.google.protobuf.MessageOrBuilder?> {
|
||||
var sender: String? = null
|
||||
var groupPublicKey: String? = null
|
||||
var openGroupServerMessageID: Long? = null
|
||||
val ttl: Long = 2 * 24 * 60 * 60 * 1000
|
||||
open val ttl: Long = 2 * 24 * 60 * 60 * 1000
|
||||
|
||||
// validation
|
||||
open fun isValid(): Boolean {
|
||||
|
@ -5,11 +5,11 @@ import org.session.libsignal.service.internal.push.SignalServiceProtos
|
||||
|
||||
class TypingIndicator() : ControlMessage() {
|
||||
|
||||
override val ttl: Long = 30 * 1000
|
||||
|
||||
companion object {
|
||||
const val TAG = "TypingIndicator"
|
||||
|
||||
//val ttl: 30 * 1000 //TODO
|
||||
|
||||
fun fromProto(proto: SignalServiceProtos.Content): TypingIndicator? {
|
||||
val typingIndicatorProto = proto.typingMessage ?: return null
|
||||
val kind = Kind.fromProto(typingIndicatorProto.action)
|
||||
|
@ -2,6 +2,7 @@ package org.session.libsession.messaging.messages.visible
|
||||
|
||||
import android.util.Size
|
||||
import android.webkit.MimeTypeMap
|
||||
import org.session.libsession.database.MessageDataProvider
|
||||
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
||||
import java.io.File
|
||||
|
||||
@ -66,4 +67,8 @@ class Attachment : VisibleMessageProto<SignalServiceProtos.AttachmentPointer?>()
|
||||
override fun toProto(): SignalServiceProtos.AttachmentPointer? {
|
||||
TODO("Not implemented")
|
||||
}
|
||||
|
||||
override fun toProto(messageDataProvider: MessageDataProvider): SignalServiceProtos.AttachmentPointer? {
|
||||
TODO("Not implemented")
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package org.session.libsession.messaging.messages.visible
|
||||
|
||||
import org.session.libsession.database.MessageDataProvider
|
||||
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
||||
|
||||
class Contact : VisibleMessageProto<SignalServiceProtos.DataMessage.Contact?>() {
|
||||
@ -13,4 +14,8 @@ class Contact : VisibleMessageProto<SignalServiceProtos.DataMessage.Contact?>()
|
||||
override fun toProto(): SignalServiceProtos.DataMessage.Contact? {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun toProto(messageDataProvider: MessageDataProvider): SignalServiceProtos.DataMessage.Contact? {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package org.session.libsession.messaging.messages.visible
|
||||
|
||||
import android.content.Context
|
||||
import org.session.libsession.database.MessageDataProvider
|
||||
import org.session.libsignal.libsignal.logging.Log
|
||||
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
||||
|
||||
@ -33,7 +35,7 @@ class LinkPreview() : VisibleMessageProto<SignalServiceProtos.DataMessage.Previe
|
||||
return (title != null && url != null && attachmentID != null)
|
||||
}
|
||||
|
||||
override fun toProto(): SignalServiceProtos.DataMessage.Preview? {
|
||||
override fun toProto(messageDataProvider: MessageDataProvider): SignalServiceProtos.DataMessage.Preview? {
|
||||
val url = url
|
||||
if (url == null) {
|
||||
Log.w(TAG, "Couldn't construct link preview proto from: $this")
|
||||
@ -44,7 +46,8 @@ class LinkPreview() : VisibleMessageProto<SignalServiceProtos.DataMessage.Previe
|
||||
title?.let { linkPreviewProto.title = title }
|
||||
val attachmentID = attachmentID
|
||||
attachmentID?.let {
|
||||
//TODO database stuff
|
||||
val attachmentProto = messageDataProvider.getAttachment(attachmentID)
|
||||
attachmentProto?.let { linkPreviewProto.image = attachmentProto.toProto() }
|
||||
}
|
||||
// Build
|
||||
try {
|
||||
@ -54,4 +57,8 @@ class LinkPreview() : VisibleMessageProto<SignalServiceProtos.DataMessage.Previe
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
override fun toProto(): SignalServiceProtos.DataMessage.Preview? {
|
||||
TODO("Not implemented")
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package org.session.libsession.messaging.messages.visible
|
||||
|
||||
import com.google.protobuf.ByteString
|
||||
import org.session.libsession.database.MessageDataProvider
|
||||
import org.session.libsignal.libsignal.logging.Log
|
||||
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
||||
|
||||
@ -57,4 +58,8 @@ class Profile() : VisibleMessageProto<SignalServiceProtos.DataMessage?>() {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
override fun toProto(messageDataProvider: MessageDataProvider): SignalServiceProtos.DataMessage? {
|
||||
return toProto()
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package org.session.libsession.messaging.messages.visible
|
||||
|
||||
import com.goterl.lazycode.lazysodium.BuildConfig
|
||||
import org.session.libsession.database.MessageDataProvider
|
||||
import org.session.libsignal.libsignal.logging.Log
|
||||
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
||||
|
||||
@ -29,14 +31,13 @@ class Quote() : VisibleMessageProto<SignalServiceProtos.DataMessage.Quote?>() {
|
||||
this.attachmentID = attachmentID
|
||||
}
|
||||
|
||||
|
||||
// validation
|
||||
override fun isValid(): Boolean {
|
||||
if (!super.isValid()) return false
|
||||
return (timestamp != null && publicKey != null)
|
||||
}
|
||||
|
||||
override fun toProto(): SignalServiceProtos.DataMessage.Quote? {
|
||||
override fun toProto(messageDataProvider: MessageDataProvider): SignalServiceProtos.DataMessage.Quote? {
|
||||
val timestamp = timestamp
|
||||
val publicKey = publicKey
|
||||
if (timestamp == null || publicKey == null) {
|
||||
@ -47,7 +48,7 @@ class Quote() : VisibleMessageProto<SignalServiceProtos.DataMessage.Quote?>() {
|
||||
quoteProto.id = timestamp
|
||||
quoteProto.author = publicKey
|
||||
text?.let { quoteProto.text = text }
|
||||
addAttachmentsIfNeeded(quoteProto)
|
||||
addAttachmentsIfNeeded(quoteProto, messageDataProvider)
|
||||
// Build
|
||||
try {
|
||||
return quoteProto.build()
|
||||
@ -57,16 +58,33 @@ class Quote() : VisibleMessageProto<SignalServiceProtos.DataMessage.Quote?>() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun addAttachmentsIfNeeded(quoteProto: SignalServiceProtos.DataMessage.Quote.Builder) {
|
||||
private fun addAttachmentsIfNeeded(quoteProto: SignalServiceProtos.DataMessage.Quote.Builder, messageDataProvider: MessageDataProvider) {
|
||||
val attachmentID = attachmentID ?: return
|
||||
//TODO databas stuff
|
||||
val attachmentProto = messageDataProvider.getAttachment(attachmentID)
|
||||
if (attachmentProto == null) {
|
||||
Log.w(TAG, "Ignoring invalid attachment for quoted message.")
|
||||
return
|
||||
}
|
||||
if (!attachmentProto.isUploaded) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
//TODO equivalent to iOS's preconditionFailure
|
||||
Log.d(TAG,"Sending a message before all associated attachments have been uploaded.")
|
||||
return
|
||||
}
|
||||
}
|
||||
val quotedAttachmentProto = SignalServiceProtos.DataMessage.Quote.QuotedAttachment.newBuilder()
|
||||
//TODO more database related stuff
|
||||
//quotedAttachmentProto.contentType =
|
||||
quotedAttachmentProto.contentType = attachmentProto.contentType
|
||||
val fileName = attachmentProto.fileName
|
||||
fileName?.let { quotedAttachmentProto.fileName = fileName }
|
||||
quotedAttachmentProto.thumbnail = attachmentProto.toProto()
|
||||
try {
|
||||
quoteProto.addAttachments(quotedAttachmentProto.build())
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "Couldn't construct quoted attachment proto from: $this")
|
||||
}
|
||||
}
|
||||
|
||||
override fun toProto(): SignalServiceProtos.DataMessage.Quote? {
|
||||
TODO("Not implemented")
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package org.session.libsession.messaging.messages.visible
|
||||
|
||||
import com.goterl.lazycode.lazysodium.BuildConfig
|
||||
import org.session.libsession.database.MessageDataProvider
|
||||
import org.session.libsignal.libsignal.logging.Log
|
||||
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
||||
|
||||
@ -46,7 +48,7 @@ class VisibleMessage() : VisibleMessageProto<SignalServiceProtos.Content?>() {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun toProto(): SignalServiceProtos.Content? {
|
||||
override fun toProto(messageDataProvider: MessageDataProvider): SignalServiceProtos.Content? {
|
||||
val proto = SignalServiceProtos.Content.newBuilder()
|
||||
var attachmentIDs = this.attachmentIDs
|
||||
val dataMessage: SignalServiceProtos.DataMessage.Builder
|
||||
@ -85,9 +87,15 @@ class VisibleMessage() : VisibleMessageProto<SignalServiceProtos.Content?>() {
|
||||
}
|
||||
}
|
||||
//Attachments
|
||||
// TODO I'm blocking on that one...
|
||||
//swift: let attachments = attachmentIDs.compactMap { TSAttachmentStream.fetch(uniqueId: $0, transaction: transaction) }
|
||||
|
||||
val attachments = attachmentIDs.mapNotNull { messageDataProvider.getAttachment(it) }
|
||||
if (!attachments.all { it.isUploaded }) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
//TODO equivalent to iOS's preconditionFailure
|
||||
Log.d(TAG,"Sending a message before all associated attachments have been uploaded.")
|
||||
}
|
||||
}
|
||||
val attachmentProtos = attachments.mapNotNull { it.toProto() }
|
||||
dataMessage.addAllAttachments(attachmentProtos)
|
||||
// TODO Contact
|
||||
// Build
|
||||
try {
|
||||
@ -99,4 +107,8 @@ class VisibleMessage() : VisibleMessageProto<SignalServiceProtos.Content?>() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun toProto(): SignalServiceProtos.Content? {
|
||||
TODO("Not implemented")
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
package org.session.libsession.messaging.messages.visible
|
||||
|
||||
import org.session.libsession.database.MessageDataProvider
|
||||
import org.session.libsession.messaging.messages.Message
|
||||
|
||||
abstract class VisibleMessageProto<T: com.google.protobuf.MessageOrBuilder?> : Message<T>() {
|
||||
|
||||
abstract fun toProto(messageDataProvider: MessageDataProvider): T
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user