Skip to content

Commit

Permalink
Merge pull request #589 from xmtp/cv/01-16-consent_filtering_by_array
Browse files Browse the repository at this point in the history
Consent filtering by array
  • Loading branch information
cameronvoell authored Jan 17, 2025
2 parents e6d23df + 8c15ef6 commit 809de5e
Show file tree
Hide file tree
Showing 14 changed files with 562 additions and 112 deletions.
8 changes: 8 additions & 0 deletions .changeset/sweet-toes-join.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@xmtp/react-native-sdk": patch
---

- Add ability to filter and sync by multiple consents
- And new inboxId methods for performance
- Conversation list sort by last "readable" msg
- Default msg history off
18 changes: 9 additions & 9 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,19 @@ repositories {
dependencies {
implementation project(':expo-modules-core')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
implementation "org.xmtp:android:3.0.21"
implementation "org.xmtp:android:3.0.22"
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"
// xmtp-android local testing setup below (comment org.xmtp:android above)
// implementation files('<PATH_TO_LIBRARY>/xmtp-android/library/build/outputs/aar/library-debug.aar')
// implementation 'com.google.crypto.tink:tink-android:1.8.0'
// implementation 'io.grpc:grpc-kotlin-stub:1.4.1'
// implementation 'io.grpc:grpc-okhttp:1.62.2'
// implementation 'io.grpc:grpc-protobuf-lite:1.62.2'
// implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0'
// implementation 'org.web3j:crypto:4.9.4'
// implementation "net.java.dev.jna:jna:5.14.0@aar"
// api 'com.google.protobuf:protobuf-kotlin-lite:3.22.3'
// api 'org.xmtp:proto-kotlin:3.71.0'
// implementation 'io.grpc:grpc-kotlin-stub:1.4.1'
// implementation 'io.grpc:grpc-okhttp:1.62.2'
// implementation 'io.grpc:grpc-protobuf-lite:1.62.2'
// implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0'
// implementation 'org.web3j:crypto:4.9.4'
// implementation "net.java.dev.jna:jna:5.14.0@aar"
// api 'com.google.protobuf:protobuf-kotlin-lite:3.22.3'
// api 'org.xmtp:proto-kotlin:3.72.4'
}
87 changes: 70 additions & 17 deletions android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,6 @@ class XMTPModule : Module() {
a.apply { set(i, v.toByte()) }
}
val historySyncUrl = authOptions.historySyncUrl
?: when (authOptions.environment) {
"production" -> "https://message-history.production.ephemera.network/"
"local" -> "http://10.0.2.2:5558"
else -> "https://message-history.dev.ephemera.network/"
}
return ClientOptions(
api = apiEnvironments(authOptions.environment, authOptions.appVersion),
preAuthenticateToInboxCallback = preAuthenticateToInboxCallback,
Expand Down Expand Up @@ -552,47 +547,47 @@ class XMTPModule : Module() {
).toJson()
}

AsyncFunction("listGroups") Coroutine { installationId: String, groupParams: String?, limit: Int?, consentState: String? ->
AsyncFunction("listGroups") Coroutine { installationId: String, groupParams: String?, limit: Int?, consentStringStates: List<String>? ->
withContext(Dispatchers.IO) {
logV("listGroups")
val client = clients[installationId] ?: throw XMTPException("No client")
val params = ConversationParamsWrapper.conversationParamsFromJson(groupParams ?: "")
val consent = consentState?.let { getConsentState(it) }
val consentStates = consentStringStates?.let { getConsentStates(it) }
val groups = client.conversations.listGroups(
limit = limit,
consentState = consent
consentStates = consentStates
)
groups.map { group ->
GroupWrapper.encode(client, group, params)
}
}
}

AsyncFunction("listDms") Coroutine { installationId: String, groupParams: String?, limit: Int?, consentState: String? ->
AsyncFunction("listDms") Coroutine { installationId: String, groupParams: String?, limit: Int?, consentStringStates: List<String>? ->
withContext(Dispatchers.IO) {
logV("listDms")
val client = clients[installationId] ?: throw XMTPException("No client")
val params = ConversationParamsWrapper.conversationParamsFromJson(groupParams ?: "")
val consent = consentState?.let { getConsentState(it) }
val consentStates = consentStringStates?.let { getConsentStates(it) }
val dms = client.conversations.listDms(
limit = limit,
consentState = consent
consentStates = consentStates
)
dms.map { dm ->
DmWrapper.encode(client, dm, params)
}
}
}

AsyncFunction("listConversations") Coroutine { installationId: String, conversationParams: String?, limit: Int?, consentState: String? ->
AsyncFunction("listConversations") Coroutine { installationId: String, conversationParams: String?, limit: Int?, consentStringStates: List<String>? ->
withContext(Dispatchers.IO) {
logV("listConversations")
val client = clients[installationId] ?: throw XMTPException("No client")
val params =
ConversationParamsWrapper.conversationParamsFromJson(conversationParams ?: "")
val consent = consentState?.let { getConsentState(it) }
val consentStates = consentStringStates?.let { getConsentStates(it) }
val conversations =
client.conversations.list(limit = limit, consentState = consent)
client.conversations.list(limit = limit, consentStates = consentStates)
conversations.map { conversation ->
ConversationWrapper.encode(client, conversation, params)
}
Expand Down Expand Up @@ -776,6 +771,15 @@ class XMTPModule : Module() {
}
}

AsyncFunction("findOrCreateDmWithInboxId") Coroutine { installationId: String, peerInboxId: String ->
withContext(Dispatchers.IO) {
logV("findOrCreateDmWithInboxId")
val client = clients[installationId] ?: throw XMTPException("No client")
val dm = client.conversations.findOrCreateDmWithInboxId(peerInboxId)
DmWrapper.encode(client, dm)
}
}

AsyncFunction("createGroup") Coroutine { installationId: String, peerAddresses: List<String>, permission: String, groupOptionsJson: String ->
withContext(Dispatchers.IO) {
logV("createGroup")
Expand Down Expand Up @@ -820,6 +824,49 @@ class XMTPModule : Module() {
}
}

AsyncFunction("createGroupWithInboxIds") Coroutine { installationId: String, inboxIds: List<String>, permission: String, groupOptionsJson: String ->
withContext(Dispatchers.IO) {
logV("createGroupWithInboxIds")
val client = clients[installationId] ?: throw XMTPException("No client")
val permissionLevel = when (permission) {
"admin_only" -> GroupPermissionPreconfiguration.ADMIN_ONLY
else -> GroupPermissionPreconfiguration.ALL_MEMBERS
}
val createGroupParams =
CreateGroupParamsWrapper.createGroupParamsFromJson(groupOptionsJson)
val group = client.conversations.newGroupWithInboxIds(
inboxIds,
permissionLevel,
createGroupParams.groupName,
createGroupParams.groupImageUrlSquare,
createGroupParams.groupDescription,
createGroupParams.groupPinnedFrameUrl
)
GroupWrapper.encode(client, group)
}
}

AsyncFunction("createGroupCustomPermissionsWithInboxIds") Coroutine { installationId: String, inboxIds: List<String>, permissionPolicySetJson: String, groupOptionsJson: String ->
withContext(Dispatchers.IO) {
logV("createGroupCustomPermissionsWithInboxIds")
val client = clients[installationId] ?: throw XMTPException("No client")
val createGroupParams =
CreateGroupParamsWrapper.createGroupParamsFromJson(groupOptionsJson)
val permissionPolicySet =
PermissionPolicySetWrapper.createPermissionPolicySetFromJson(
permissionPolicySetJson
)
val group = client.conversations.newGroupCustomPermissionsWithInboxIds(
inboxIds,
permissionPolicySet,
createGroupParams.groupName,
createGroupParams.groupImageUrlSquare,
createGroupParams.groupDescription,
createGroupParams.groupPinnedFrameUrl
)
GroupWrapper.encode(client, group)
}
}

AsyncFunction("listMemberInboxIds") Coroutine { installationId: String, id: String ->
withContext(Dispatchers.IO) {
Expand Down Expand Up @@ -860,13 +907,13 @@ class XMTPModule : Module() {
}
}

AsyncFunction("syncAllConversations") Coroutine { installationId: String, consentState: String? ->
AsyncFunction("syncAllConversations") Coroutine { installationId: String, consentStringStates: List<String>? ->
withContext(Dispatchers.IO) {
logV("syncAllConversations")
val client = clients[installationId] ?: throw XMTPException("No client")
val consent = consentState?.let { getConsentState(it) }
val consentStates = consentStringStates?.let { getConsentStates(it) }
val numGroupsSyncedInt: Int =
client.conversations.syncAllConversations(consent).toInt()
client.conversations.syncAllConversations(consentStates).toInt()
numGroupsSyncedInt
}
}
Expand Down Expand Up @@ -1443,6 +1490,12 @@ class XMTPModule : Module() {
}
}

private fun getConsentStates(stateStrings: List<String>): List<ConsentState> {
return stateStrings.map { stateString ->
getConsentState(stateString)
}
}

private fun getEntryType(entryString: String): EntryType {
return when (entryString) {
"address" -> EntryType.ADDRESS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class PermissionPolicySetWrapper {
"updateGroupDescriptionPolicy" to fromPermissionOption(policySet.updateGroupDescriptionPolicy),
"updateGroupImagePolicy" to fromPermissionOption(policySet.updateGroupImagePolicy),
"updateGroupPinnedFrameUrlPolicy" to fromPermissionOption(policySet.updateGroupPinnedFrameUrlPolicy),
"updateMessageExpirationPolicy" to fromPermissionOption(policySet.updateMessageExpirationPolicy),
)
}

Expand All @@ -50,7 +51,8 @@ class PermissionPolicySetWrapper {
updateGroupNamePolicy = createPermissionOptionFromString(jsonObj.get("updateGroupNamePolicy").asString),
updateGroupDescriptionPolicy = createPermissionOptionFromString(jsonObj.get("updateGroupDescriptionPolicy").asString),
updateGroupImagePolicy = createPermissionOptionFromString(jsonObj.get("updateGroupImagePolicy").asString),
updateGroupPinnedFrameUrlPolicy = createPermissionOptionFromString(jsonObj.get("updateGroupPinnedFrameUrlPolicy").asString)
updateGroupPinnedFrameUrlPolicy = createPermissionOptionFromString(jsonObj.get("updateGroupPinnedFrameUrlPolicy").asString),
updateMessageExpirationPolicy = createPermissionOptionFromString(jsonObj.get("updateMessageExpirationPolicy").asString),
)
}

Expand Down
16 changes: 8 additions & 8 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ PODS:
- hermes-engine/Pre-built (= 0.71.14)
- hermes-engine/Pre-built (0.71.14)
- libevent (2.1.12)
- LibXMTP (3.0.18)
- LibXMTP (3.0.20)
- MessagePacker (0.4.7)
- MMKV (2.0.2):
- MMKVCore (~> 2.0.2)
Expand Down Expand Up @@ -448,18 +448,18 @@ PODS:
- SQLCipher/standard (4.5.7):
- SQLCipher/common
- SwiftProtobuf (1.28.2)
- XMTP (3.0.23):
- XMTP (3.0.24):
- Connect-Swift (= 1.0.0)
- CryptoSwift (= 1.8.3)
- CSecp256k1 (~> 0.2)
- LibXMTP (= 3.0.18)
- LibXMTP (= 3.0.20)
- SQLCipher (= 4.5.7)
- XMTPReactNative (3.1.6):
- XMTPReactNative (3.1.7):
- CSecp256k1 (~> 0.2)
- ExpoModulesCore
- MessagePacker
- SQLCipher (= 4.5.7)
- XMTP (= 3.0.23)
- XMTP (= 3.0.24)
- Yoga (1.14.0)

DEPENDENCIES:
Expand Down Expand Up @@ -711,7 +711,7 @@ SPEC CHECKSUMS:
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
hermes-engine: d7cc127932c89c53374452d6f93473f1970d8e88
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
LibXMTP: 09d80c1ef92a6fd195a13b2e0911259bf87005e3
LibXMTP: 5c8a858675af142e4a5336e27bb2d6fa6d633b18
MessagePacker: ab2fe250e86ea7aedd1a9ee47a37083edd41fd02
MMKV: 3eacda84cd1c4fc95cf848d3ecb69d85ed56006c
MMKVCore: 508b4d3a8ce031f1b5c8bd235f0517fb3f4c73a9
Expand Down Expand Up @@ -762,8 +762,8 @@ SPEC CHECKSUMS:
RNSVG: d00c8f91c3cbf6d476451313a18f04d220d4f396
SQLCipher: 5e6bfb47323635c8b657b1b27d25c5f1baf63bf5
SwiftProtobuf: 4dbaffec76a39a8dc5da23b40af1a5dc01a4c02d
XMTP: 645cb707d5d779b896d00b5f547227325a7379a7
XMTPReactNative: 9b25afc1fb008aa92d83d957263e8a14507efefc
XMTP: 3d82fe8598fe043a67ad93276084ab46a30a1fa3
XMTPReactNative: cd9144370b01abf420c74dd773a82ca0c1a8633b
Yoga: e71803b4c1fff832ccf9b92541e00f9b873119b9

PODFILE CHECKSUM: 0e6fe50018f34e575d38dc6a1fdf1f99c9596cdd
Expand Down
Loading

0 comments on commit 809de5e

Please sign in to comment.