From f5a583e7c86869da97212113b46f1d36108d2298 Mon Sep 17 00:00:00 2001 From: Brice Date: Tue, 1 Dec 2020 16:24:50 +1100 Subject: [PATCH] classes structure redesign + LinkPreview & BaseVisibleMessage implementations --- .../messages/visible/BaseVisibleMessage.kt | 98 +++++++++++++++++++ .../messaging/messages/visible/Contact.kt | 5 +- .../messaging/messages/visible/LinkPreview.kt | 53 ++++++++-- .../messaging/messages/visible/Profile.kt | 9 +- .../messaging/messages/visible/Quote.kt | 14 ++- .../messages/visible/VisibleMessage.kt | 11 ++- .../visible/attachments/Attachment.kt | 5 +- 7 files changed, 172 insertions(+), 23 deletions(-) create mode 100644 libsession/src/main/java/org/session/libsession/messaging/messages/visible/BaseVisibleMessage.kt diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/BaseVisibleMessage.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/BaseVisibleMessage.kt new file mode 100644 index 0000000000..1ea7768381 --- /dev/null +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/BaseVisibleMessage.kt @@ -0,0 +1,98 @@ +package org.session.libsession.messaging.messages.visible + +import org.session.libsignal.libsignal.logging.Log +import org.session.libsignal.service.internal.push.SignalServiceProtos + +class BaseVisibleMessage() : VisibleMessage() { + + var text: String? = null + var attachmentIDs = ArrayList() + var quote: Quote? = null + var linkPreview: LinkPreview? = null + var contact: Contact? = null + var profile: Profile? = null + + companion object { + const val TAG = "BaseVisibleMessage" + + fun fromProto(proto: SignalServiceProtos.Content): BaseVisibleMessage? { + val dataMessage = proto.dataMessage ?: return null + val result = BaseVisibleMessage() + result.text = dataMessage.body + // Attachments are handled in MessageReceiver + val quoteProto = dataMessage.quote + val quote = Quote.fromProto(quoteProto) + quote?.let { result.quote = quote } + val linkPreviewProto = dataMessage.previewList.first() + val linkPreview = LinkPreview.fromProto(linkPreviewProto) + linkPreview?.let { result.linkPreview = linkPreview } + // TODO Contact + val profile = Profile.fromProto(dataMessage) + if (profile != null) { result.profile = profile } + return result + } + } + + // validation + override fun isValid(): Boolean { + if (!super.isValid()) return false + if (attachmentIDs.isNotEmpty()) return true + val text = text?.trim() ?: return false + if (text.isEmpty()) return true + return false + } + + override fun toProto(transaction: String): SignalServiceProtos.Content? { + val proto = SignalServiceProtos.Content.newBuilder() + var attachmentIDs = this.attachmentIDs + val dataMessage: SignalServiceProtos.DataMessage.Builder + // Profile + val profile = profile + val profileProto = profile?.toProto("") //TODO + if (profileProto != null) { + dataMessage = profileProto.toBuilder() + } else { + dataMessage = SignalServiceProtos.DataMessage.newBuilder() + } + // Text + text?.let { dataMessage.body = text } + // Quote + val quotedAttachmentID = quote?.attachmentID + quotedAttachmentID?.let { + val index = attachmentIDs.indexOf(quotedAttachmentID) + if (index >= 0) { attachmentIDs.removeAt(index) } + } + val quote = quote + quote?.let { + val quoteProto = quote.toProto(transaction) + if (quoteProto != null) dataMessage.quote = quoteProto + } + //Link preview + val linkPreviewAttachmentID = linkPreview?.attachmentID + linkPreviewAttachmentID?.let { + val index = attachmentIDs.indexOf(quotedAttachmentID) + if (index >= 0) { attachmentIDs.removeAt(index) } + } + val linkPreview = linkPreview + linkPreview?.let { + val linkPreviewProto = linkPreview.toProto(transaction) + linkPreviewProto?.let { + dataMessage.addAllPreview(listOf(linkPreviewProto)) + } + } + //Attachments + // TODO I'm blocking on that one... + //swift: let attachments = attachmentIDs.compactMap { TSAttachmentStream.fetch(uniqueId: $0, transaction: transaction) } + + + // Build + try { + proto.dataMessage = dataMessage.build() + return proto.build() + } catch (e: Exception) { + Log.w(TAG, "Couldn't construct visible message proto from: $this") + return null + } + } + +} \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Contact.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Contact.kt index e0c9d2ab34..cbca11cd2d 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Contact.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Contact.kt @@ -1,9 +1,8 @@ package org.session.libsession.messaging.messages.visible -import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate import org.session.libsignal.service.internal.push.SignalServiceProtos -internal class Contact : VisibleMessage() { +class Contact : VisibleMessage() { companion object { fun fromProto(proto: SignalServiceProtos.Content): Contact? { @@ -11,7 +10,7 @@ internal class Contact : VisibleMessage() { } } - override fun toProto(): SignalServiceProtos.Content? { + override fun toProto(transaction: String): SignalServiceProtos.DataMessage.Contact? { TODO("Not yet implemented") } } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/LinkPreview.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/LinkPreview.kt index 3bcafd71a7..90521b6e30 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/LinkPreview.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/LinkPreview.kt @@ -1,17 +1,58 @@ package org.session.libsession.messaging.messages.visible -import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate +import org.session.libsession.messaging.messages.control.TypingIndicator +import org.session.libsignal.libsignal.logging.Log import org.session.libsignal.service.internal.push.SignalServiceProtos -internal class LinkPreview : VisibleMessage(){ +class LinkPreview() : VisibleMessage(){ + + var title: String? = null + var url: String? = null + var attachmentID: String? = null companion object { - fun fromProto(proto: SignalServiceProtos.Content): LinkPreview? { - TODO("Not yet implemented") + const val TAG = "LinkPreview" + + fun fromProto(proto: SignalServiceProtos.DataMessage.Preview): LinkPreview? { + val title = proto.title + val url = proto.url + return LinkPreview(title, url, null) } } - override fun toProto(): SignalServiceProtos.Content? { - TODO("Not yet implemented") + //constructor + internal constructor(title: String?, url: String, attachmentID: String?) : this() { + this.title = title + this.url = url + this.attachmentID = attachmentID + } + + + // validation + override fun isValid(): Boolean { + if (!super.isValid()) return false + return (title != null && url != null && attachmentID != null) + } + + override fun toProto(transaction: String): SignalServiceProtos.DataMessage.Preview? { + val url = url + if (url == null) { + Log.w(TAG, "Couldn't construct link preview proto from: $this") + return null + } + val linkPreviewProto = SignalServiceProtos.DataMessage.Preview.newBuilder() + linkPreviewProto.url = url + title?. let { linkPreviewProto.title = title } + val attachmentID = attachmentID + attachmentID?.let { + //TODO database stuff + } + // Build + try { + return linkPreviewProto.build() + } catch (e: Exception) { + Log.w(TAG, "Couldn't construct link preview proto from: $this") + return null + } } } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Profile.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Profile.kt index a5b09b4f79..193966e003 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Profile.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Profile.kt @@ -1,17 +1,16 @@ package org.session.libsession.messaging.messages.visible -import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate import org.session.libsignal.service.internal.push.SignalServiceProtos -internal class Profile : VisibleMessage() { +class Profile() : VisibleMessage() { companion object { - fun fromProto(proto: SignalServiceProtos.Content): Profile? { + fun fromProto(proto: SignalServiceProtos.DataMessage): Profile? { TODO("Not yet implemented") } } - override fun toProto(): SignalServiceProtos.Content? { - TODO("Not yet implemented") + override fun toProto(transaction: String): SignalServiceProtos.DataMessage? { + return null } } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Quote.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Quote.kt index 55b6481c94..0f60db1865 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Quote.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Quote.kt @@ -1,17 +1,21 @@ package org.session.libsession.messaging.messages.visible -import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate import org.session.libsignal.service.internal.push.SignalServiceProtos -internal class Quote : VisibleMessage() { +class Quote() : VisibleMessage() { + + var timestamp: Long? = 0 + var publicKey: String? = null + var text: String? = null + var attachmentID: String? = null companion object { - fun fromProto(proto: SignalServiceProtos.Content): Quote? { + fun fromProto(proto: SignalServiceProtos.DataMessage.Quote): Quote? { TODO("Not yet implemented") } } - override fun toProto(): SignalServiceProtos.Content? { - TODO("Not yet implemented") + override fun toProto(transaction: String): SignalServiceProtos.DataMessage.Quote? { + return null } } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/VisibleMessage.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/VisibleMessage.kt index 5ea2cea79e..bb60a51817 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/VisibleMessage.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/VisibleMessage.kt @@ -1,6 +1,15 @@ package org.session.libsession.messaging.messages.visible import org.session.libsession.messaging.messages.Message +import org.session.libsignal.service.internal.push.SignalServiceProtos -abstract class VisibleMessage : Message() { +abstract class VisibleMessage : Message() { + + abstract fun toProto(transaction: String): T + + final override fun toProto(): SignalServiceProtos.Content? { + //we don't need to implement this method in subclasses + //TODO it just needs an equivalent to swift: preconditionFailure("Use toProto(using:) instead.") + TODO("Not yet implemented") + } } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/attachments/Attachment.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/attachments/Attachment.kt index b7ab2ec8e2..f50ffb6baa 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/attachments/Attachment.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/attachments/Attachment.kt @@ -1,10 +1,9 @@ package org.session.libsession.messaging.messages.visible.attachments -import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate -import org.session.libsession.messaging.messages.visible.VisibleMessage +import org.session.libsession.messaging.messages.visible.BaseVisibleMessage import org.session.libsignal.service.internal.push.SignalServiceProtos -internal class Attachment : VisibleMessage() { +internal class Attachment : BaseVisibleMessage() { companion object { fun fromProto(proto: SignalServiceProtos.Content): Attachment? {