Skip to content

Commit

Permalink
Merge pull request #156 from xmtp/np/custom-content-types-android
Browse files Browse the repository at this point in the history
Android side of custom content types
  • Loading branch information
nplasterer authored Nov 30, 2023
2 parents 0576065 + fd1c631 commit caee68c
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 20 deletions.
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ repositories {
dependencies {
implementation project(':expo-modules-core')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
implementation "org.xmtp:android:0.6.12"
implementation "org.xmtp:android:0.6.14"
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'com.facebook.react:react-native:0.71.3'
implementation "com.daveanthonythomas.moshipack:moshipack:1.0.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,27 @@ class XMTPModule : Module() {
).toJson()
}

AsyncFunction("sendEncodedContent") { clientAddress: String, topic: String, encodedContentData: List<Int> ->
val conversation =
findConversation(
clientAddress = clientAddress,
topic = topic
) ?: throw XMTPException("no conversation found for $topic")

val encodedContentDataBytes =
encodedContentData.foldIndexed(ByteArray(encodedContentData.size)) { i, a, v ->
a.apply {
set(
i,
v.toByte()
)
}
}
val encodedContent = EncodedContent.parseFrom(encodedContentDataBytes)

conversation.send(encodedContent = encodedContent)
}

AsyncFunction("listConversations") { clientAddress: String ->
logV("listConversations")
val client = clients[clientAddress] ?: throw XMTPException("No client")
Expand All @@ -288,7 +309,7 @@ class XMTPModule : Module() {
val beforeDate = if (before != null) Date(before) else null
val afterDate = if (after != null) Date(after) else null

conversation.messages(
conversation.decryptedMessages(
limit = limit,
before = beforeDate,
after = afterDate,
Expand Down Expand Up @@ -340,7 +361,7 @@ class XMTPModule : Module() {
topicsList.add(Pair(topic, page))
}

client.conversations.listBatchMessages(topicsList)
client.conversations.listBatchDecryptedMessages(topicsList)
.map { DecodedMessageWrapper.encode(it) }
}

Expand Down Expand Up @@ -486,7 +507,7 @@ class XMTPModule : Module() {
topic = topic
)
?: throw XMTPException("no conversation found for $topic")
val decodedMessage = conversation.decode(envelope)
val decodedMessage = conversation.decrypt(envelope)
DecodedMessageWrapper.encode(decodedMessage)
}

Expand Down Expand Up @@ -581,7 +602,7 @@ class XMTPModule : Module() {
subscriptions[getMessagesKey(clientAddress)]?.cancel()
subscriptions[getMessagesKey(clientAddress)] = CoroutineScope(Dispatchers.IO).launch {
try {
client.conversations.streamAllMessages().collect { message ->
client.conversations.streamAllDecryptedMessages().collect { message ->
sendEvent(
"message",
mapOf(
Expand All @@ -607,7 +628,7 @@ class XMTPModule : Module() {
subscriptions[conversation.cacheKey(clientAddress)] =
CoroutineScope(Dispatchers.IO).launch {
try {
conversation.streamMessages().collect { message ->
conversation.streamDecryptedMessages().collect { message ->
sendEvent(
"message",
mapOf(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package expo.modules.xmtpreactnativesdk.wrappers

import android.util.Base64
import com.google.gson.GsonBuilder
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import com.google.protobuf.ByteString
Expand All @@ -14,6 +15,7 @@ import org.xmtp.android.library.codecs.ContentTypeReadReceipt
import org.xmtp.android.library.codecs.ContentTypeRemoteAttachment
import org.xmtp.android.library.codecs.ContentTypeReply
import org.xmtp.android.library.codecs.ContentTypeText
import org.xmtp.android.library.codecs.EncodedContent
import org.xmtp.android.library.codecs.Reaction
import org.xmtp.android.library.codecs.ReactionCodec
import org.xmtp.android.library.codecs.ReadReceipt
Expand All @@ -28,16 +30,17 @@ import org.xmtp.android.library.codecs.description
import org.xmtp.android.library.codecs.getReactionAction
import org.xmtp.android.library.codecs.getReactionSchema
import org.xmtp.android.library.codecs.id
import org.xmtp.proto.message.contents.Content.EncodedContent
import java.net.URL

class ContentJson(
val type: ContentTypeId,
val content: Any?,
private val encodedContent: EncodedContent? = null,
) {
constructor(encoded: EncodedContent) : this(
type = encoded.type,
content = encoded.decoded(),
encodedContent = encoded
);

companion object {
Expand Down Expand Up @@ -157,19 +160,43 @@ class ContentJson(
ContentTypeReply.id -> mapOf(
"reply" to mapOf(
"reference" to (content as Reply).reference,
"content" to ContentJson(content.contentType, content.content).toJsonMap(),
"content" to ContentJson(
content.contentType,
content.content,
encodedContent
).toJsonMap(),
)
)

ContentTypeReadReceipt.id -> mapOf(
"readReceipt" to ""
)

else -> mapOf(
"unknown" to mapOf(
"contentTypeId" to type.description
)
)
else -> {
val json = JsonObject()
encodedContent?.let {
val typeJson = JsonObject()
typeJson.addProperty("authorityId", encodedContent.type.authorityId)
typeJson.addProperty("typeId", encodedContent.type.typeId)
typeJson.addProperty("versionMajor", encodedContent.type.versionMajor)
typeJson.addProperty("versionMinor", encodedContent.type.versionMinor)
val parameters = GsonBuilder().create().toJson(encodedContent.parametersMap)

json.addProperty("fallback", encodedContent.fallback)
json.add("parameters", JsonParser.parseString(parameters))
json.add("type", typeJson)
}
val encodedContentJSON = json.toString()
if (encodedContentJSON.isNotBlank()) {
mapOf("encoded" to encodedContentJSON)
} else {
mapOf(
"unknown" to mapOf(
"contentTypeId" to type.description
)
)
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
package expo.modules.xmtpreactnativesdk.wrappers

import com.google.gson.GsonBuilder
import org.xmtp.android.library.DecodedMessage
import org.xmtp.android.library.codecs.description
import org.xmtp.android.library.codecs.id
import org.xmtp.android.library.messages.DecryptedMessage

class DecodedMessageWrapper {

companion object {
fun encode(model: DecodedMessage): String {
fun encode(model: DecryptedMessage): String {
val gson = GsonBuilder().create()
val message = encodeMap(model)
return gson.toJson(message)
}

fun encodeMap(model: DecodedMessage): Map<String, Any> = mapOf(
fun encodeMap(model: DecryptedMessage): Map<String, Any> = mapOf(
"id" to model.id,
"topic" to model.topic,
"contentTypeId" to model.encodedContent.type.description,
"content" to ContentJson(model.encodedContent).toJsonMap(),
"senderAddress" to model.senderAddress,
"sent" to model.sent.time,
"fallback" to model.fallbackContent
"sent" to model.sentAt.time,
"fallback" to model.encodedContent.fallback
)
}
}

0 comments on commit caee68c

Please sign in to comment.