From 85f24a4bcc9a1a1170f5382280d66a1be3e7b7b0 Mon Sep 17 00:00:00 2001 From: cameronvoell Date: Tue, 2 Jul 2024 18:35:06 -0700 Subject: [PATCH 1/3] added pinned frame url --- .../modules/xmtpreactnativesdk/XMTPModule.kt | 42 ++++++++++++++-- .../wrappers/CreateGroupParamsWrapper.kt | 22 ++++++++ .../wrappers/GroupWrapper.kt | 4 -- .../wrappers/PermissionPolicySetWrapper.kt | 1 + example/src/tests/groupPermissionsTests.ts | 50 +++++++++++++++++++ src/index.ts | 47 +++++++++++++++-- src/lib/Conversations.ts | 3 +- src/lib/Group.ts | 40 +++++++++++++++ src/lib/types/CreateGroupOptions.ts | 1 + src/lib/types/PermissionPolicySet.ts | 1 + 10 files changed, 198 insertions(+), 13 deletions(-) create mode 100644 android/src/main/java/expo/modules/xmtpreactnativesdk/wrappers/CreateGroupParamsWrapper.kt diff --git a/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt b/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt index 3055e5af9..e68fba3d7 100644 --- a/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt +++ b/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt @@ -20,6 +20,7 @@ import expo.modules.xmtpreactnativesdk.wrappers.ConsentWrapper.Companion.consent import expo.modules.xmtpreactnativesdk.wrappers.ContentJson import expo.modules.xmtpreactnativesdk.wrappers.ConversationContainerWrapper import expo.modules.xmtpreactnativesdk.wrappers.ConversationWrapper +import expo.modules.xmtpreactnativesdk.wrappers.CreateGroupParamsWrapper import expo.modules.xmtpreactnativesdk.wrappers.DecodedMessageWrapper import expo.modules.xmtpreactnativesdk.wrappers.DecryptedLocalAttachment import expo.modules.xmtpreactnativesdk.wrappers.EncryptedLocalAttachment @@ -834,7 +835,7 @@ class XMTPModule : Module() { ConversationWrapper.encode(client, conversation) } } - AsyncFunction("createGroup") Coroutine { inboxId: String, peerAddresses: List, permission: String, groupName: String, groupImageUrlSquare: String, groupDescription: String -> + AsyncFunction("createGroup") Coroutine { inboxId: String, peerAddresses: List, permission: String, groupOptionsJson: String -> withContext(Dispatchers.IO) { logV("createGroup") val client = clients[inboxId] ?: throw XMTPException("No client") @@ -842,17 +843,20 @@ class XMTPModule : Module() { "admin_only" -> GroupPermissionPreconfiguration.ADMIN_ONLY else -> GroupPermissionPreconfiguration.ALL_MEMBERS } + val createGroupParams = CreateGroupParamsWrapper.createGroupParamsFromJson(groupOptionsJson) val group = client.conversations.newGroup( peerAddresses, permissionLevel, - groupName, - groupImageUrlSquare, - groupDescription + createGroupParams.groupName, + createGroupParams.groupImageUrlSquare, + createGroupParams.groupDescription, + createGroupParams.groupPinnedFrameUrl ) GroupWrapper.encode(client, group) } } + AsyncFunction("listMemberInboxIds") Coroutine { inboxId: String, groupId: String -> withContext(Dispatchers.IO) { logV("listMembers") @@ -988,6 +992,26 @@ class XMTPModule : Module() { } } + AsyncFunction("groupPinnedFrameUrl") Coroutine { inboxId: String, id: String -> + withContext(Dispatchers.IO) { + logV("groupPinnedFrameUrl") + val client = clients[inboxId] ?: throw XMTPException("No client") + val group = findGroup(inboxId, id) + + group?.pinnedFrameUrl + } + } + + AsyncFunction("updateGroupPinnedFrameUrl") Coroutine { inboxId: String, id: String, pinnedFrameUrl: String -> + withContext(Dispatchers.IO) { + logV("updateGroupPinnedFrameUrl") + val client = clients[inboxId] ?: throw XMTPException("No client") + val group = findGroup(inboxId, id) + + group?.updateGroupPinnedFrameUrl(pinnedFrameUrl) + } + } + AsyncFunction("isGroupActive") Coroutine { inboxId: String, id: String -> withContext(Dispatchers.IO) { logV("isGroupActive") @@ -1166,6 +1190,16 @@ class XMTPModule : Module() { } } + AsyncFunction("updateGroupPinnedFrameUrlPermission") Coroutine { clientInboxId: String, id: String, newPermission: String -> + withContext(Dispatchers.IO) { + logV("updateGroupPinnedFrameUrlPermission") + val client = clients[clientInboxId] ?: throw XMTPException("No client") + val group = findGroup(clientInboxId, id) + + group?.updateGroupPinnedFrameUrlPermission(getPermissionOption(newPermission)) + } + } + AsyncFunction("permissionPolicySet") Coroutine { inboxId: String, id: String -> withContext(Dispatchers.IO) { logV("groupImageUrlSquare") diff --git a/android/src/main/java/expo/modules/xmtpreactnativesdk/wrappers/CreateGroupParamsWrapper.kt b/android/src/main/java/expo/modules/xmtpreactnativesdk/wrappers/CreateGroupParamsWrapper.kt new file mode 100644 index 000000000..d857ffb49 --- /dev/null +++ b/android/src/main/java/expo/modules/xmtpreactnativesdk/wrappers/CreateGroupParamsWrapper.kt @@ -0,0 +1,22 @@ +package expo.modules.xmtpreactnativesdk.wrappers + +import com.google.gson.JsonParser + +class CreateGroupParamsWrapper( + val groupName: String, + val groupImageUrlSquare: String, + val groupDescription: String, + val groupPinnedFrameUrl: String, +) { + companion object { + fun createGroupParamsFromJson(authParams: String): CreateGroupParamsWrapper { + val jsonOptions = JsonParser.parseString(authParams).asJsonObject + return CreateGroupParamsWrapper( + if (jsonOptions.has("name")) jsonOptions.get("name").asString else "", + if (jsonOptions.has("imageUrlSquare")) jsonOptions.get("imageUrlSquare").asString else "", + if (jsonOptions.has("description")) jsonOptions.get("description").asString else "", + if (jsonOptions.has("pinnedFrameUrl")) jsonOptions.get("pinnedFrameUrl").asString else "", + ) + } + } +} diff --git a/android/src/main/java/expo/modules/xmtpreactnativesdk/wrappers/GroupWrapper.kt b/android/src/main/java/expo/modules/xmtpreactnativesdk/wrappers/GroupWrapper.kt index 738a66109..5edd8914c 100644 --- a/android/src/main/java/expo/modules/xmtpreactnativesdk/wrappers/GroupWrapper.kt +++ b/android/src/main/java/expo/modules/xmtpreactnativesdk/wrappers/GroupWrapper.kt @@ -9,7 +9,6 @@ class GroupWrapper { companion object { fun encodeToObj(client: Client, group: Group): Map { - val permissionPolicySet = PermissionPolicySetWrapper.encodeToJsonString(group.permissionPolicySet()) return mapOf( "clientAddress" to client.address, "id" to group.id.toHex(), @@ -18,10 +17,7 @@ class GroupWrapper { "version" to "GROUP", "topic" to group.topic, "creatorInboxId" to group.creatorInboxId(), - "name" to group.name, "isActive" to group.isActive(), - "imageUrlSquare" to group.imageUrlSquare, - "description" to group.description ) } diff --git a/android/src/main/java/expo/modules/xmtpreactnativesdk/wrappers/PermissionPolicySetWrapper.kt b/android/src/main/java/expo/modules/xmtpreactnativesdk/wrappers/PermissionPolicySetWrapper.kt index 3a25699e3..0922d33a9 100644 --- a/android/src/main/java/expo/modules/xmtpreactnativesdk/wrappers/PermissionPolicySetWrapper.kt +++ b/android/src/main/java/expo/modules/xmtpreactnativesdk/wrappers/PermissionPolicySetWrapper.kt @@ -25,6 +25,7 @@ class PermissionPolicySetWrapper { "updateGroupNamePolicy" to fromPermissionOption(policySet.updateGroupNamePolicy), "updateGroupDescriptionPolicy" to fromPermissionOption(policySet.updateGroupDescriptionPolicy), "updateGroupImagePolicy" to fromPermissionOption(policySet.updateGroupImagePolicy), + "updateGroupPinnedFrameUrlPolicy" to fromPermissionOption(policySet.updateGroupPinnedFrameUrlPolicy), ) } diff --git a/example/src/tests/groupPermissionsTests.ts b/example/src/tests/groupPermissionsTests.ts index bd6ff470b..bdc0960e3 100644 --- a/example/src/tests/groupPermissionsTests.ts +++ b/example/src/tests/groupPermissionsTests.ts @@ -463,3 +463,53 @@ test('can update group permissions', async () => { return true }) + +test('can update group pinned frame', async () => { + // Create clients + const [alix, bo, caro] = await createClients(3) + + // Bo creates a group with Alix and Caro + const boGroup = await bo.conversations.newGroup( + [alix.address, caro.address], + { permissionLevel: 'admin_only' } + ) + + // Verify that alix can not update the group pinned frame + await alix.conversations.syncGroups() + const alixGroup = (await alix.conversations.listGroups())[0] + try { + await alixGroup.updateGroupPinnedFrameUrl('new pinned frame') + assert(false, 'Alix should not be able to update the group pinned frame') + // eslint-disable-next-line @typescript-eslint/no-unused-vars + } catch (error) { + // expected + } + + // Verify that bo can update the group pinned frame + await boGroup.updateGroupPinnedFrameUrl('new pinned frame 2') + await boGroup.sync() + assert( + (await boGroup.groupPinnedFrameUrl()) === 'new pinned frame 2', + `boGroup.groupPinnedFrameUrl should be "new pinned frame 2" but was ${boGroup.groupPinnedFrameUrl}` + ) + + // Verify that bo can update the pinned frame permission + await boGroup.updateGroupPinnedFrameUrlPermission('allow') + await boGroup.sync() + assert( + (await boGroup.permissionPolicySet()).updateGroupPinnedFrameUrlPolicy === + 'allow', + `boGroup.permissionPolicySet.updateGroupPinnedFrameUrlPolicy should be allow but was ${(await boGroup.permissionPolicySet()).updateGroupPinnedFrameUrlPolicy}` + ) + + // Verify that Alix can now update pinned frames + await alixGroup.updateGroupPinnedFrameUrl('new pinned frame 3') + await alixGroup.sync() + await boGroup.sync() + assert( + (await boGroup.groupPinnedFrameUrl()) === 'new pinned frame 3', + `alixGroup.groupPinnedFrameUrl should be "new pinned frame 3" but was ${boGroup.groupPinnedFrameUrl}` + ) + + return true +}) diff --git a/src/index.ts b/src/index.ts index 97f21dd15..4e0fd2e13 100644 --- a/src/index.ts +++ b/src/index.ts @@ -169,8 +169,15 @@ export async function createGroup< permissionLevel: 'all_members' | 'admin_only' = 'all_members', name: string = '', imageUrlSquare: string = '', - description: string = '' + description: string = '', + pinnedFrameUrl: string = '' ): Promise> { + const options: CreateGroupParams = { + name, + imageUrlSquare, + description, + pinnedFrameUrl, + } return new Group( client, JSON.parse( @@ -178,9 +185,7 @@ export async function createGroup< client.inboxId, peerAddresses, permissionLevel, - name, - imageUrlSquare, - description + JSON.stringify(options) ) ) ) @@ -364,6 +369,21 @@ export function updateGroupName( return XMTPModule.updateGroupName(inboxId, id, groupName) } +export function groupPinnedFrameUrl( + inboxId: string, + id: string +): string | PromiseLike { + return XMTPModule.groupPinnedFrameUrl(inboxId, id) +} + +export function updateGroupPinnedFrameUrl( + inboxId: string, + id: string, + pinnedFrameUrl: string +): Promise { + return XMTPModule.updateGroupPinnedFrameUrl(inboxId, id, pinnedFrameUrl) +} + export async function sign( inboxId: string, digest: Uint8Array, @@ -964,6 +984,18 @@ export async function updateGroupDescriptionPermission( ) } +export async function updateGroupPinnedFrameUrlPermission( + clientInboxId: string, + id: string, + permissionOption: PermissionUpdateOption +): Promise { + return XMTPModule.updateGroupPinnedFrameUrlPermission( + clientInboxId, + id, + permissionOption + ) +} + export async function permissionPolicySet( clientInboxId: string, id: string @@ -1066,6 +1098,13 @@ interface AuthParams { historySyncUrl?: string } +interface CreateGroupParams { + name: string + imageUrlSquare: string + description: string + pinnedFrameUrl: string +} + export * from './XMTP.types' export { Client } from './lib/Client' export * from './lib/ContentCodec' diff --git a/src/lib/Conversations.ts b/src/lib/Conversations.ts index e6eeeeb2d..15f6030fb 100644 --- a/src/lib/Conversations.ts +++ b/src/lib/Conversations.ts @@ -182,7 +182,8 @@ export default class Conversations< opts?.permissionLevel, opts?.name, opts?.imageUrlSquare, - opts?.description + opts?.description, + opts?.pinnedFrameUrl ) } diff --git a/src/lib/Group.ts b/src/lib/Group.ts index 8174e258a..3333a1881 100644 --- a/src/lib/Group.ts +++ b/src/lib/Group.ts @@ -286,6 +286,30 @@ export class Group< ) } + /** + * Returns the group pinned frame. + * To get the latest group pinned frame url from the network, call sync() first. + * @returns {string} A Promise that resolves to the group pinned frame url. + */ + async groupPinnedFrameUrl(): Promise { + return XMTP.groupPinnedFrameUrl(this.client.inboxId, this.id) + } + + /** + * Updates the group pinned frame url. + * Will throw if the user does not have the required permissions. + * @param {string} pinnedFrameUrl new group pinned frame url + * @returns + */ + + async updateGroupPinnedFrameUrl(pinnedFrameUrl: string): Promise { + return XMTP.updateGroupPinnedFrameUrl( + this.client.inboxId, + this.id, + pinnedFrameUrl + ) + } + /** * Returns whether the group is active. * To get the latest active status from the network, call sync() first @@ -495,6 +519,22 @@ export class Group< ) } + /** + * + * @param {PermissionOption} permissionOption + * @returns {Promise} A Promise that resolves when the groupPinnedFrameUrl permission is updated for the group. + * Will throw if the user does not have the required permissions. + */ + async updateGroupPinnedFrameUrlPermission( + permissionOption: PermissionUpdateOption + ): Promise { + return XMTP.updateGroupPinnedFrameUrlPermission( + this.client.inboxId, + this.id, + permissionOption + ) + } + /** * * @returns {Promise} A {PermissionPolicySet} object representing the group's permission policy set. diff --git a/src/lib/types/CreateGroupOptions.ts b/src/lib/types/CreateGroupOptions.ts index c527f026e..7f075d6ee 100644 --- a/src/lib/types/CreateGroupOptions.ts +++ b/src/lib/types/CreateGroupOptions.ts @@ -3,4 +3,5 @@ export type CreateGroupOptions = { name?: string | undefined imageUrlSquare?: string | undefined description?: string | undefined + pinnedFrameUrl?: string | undefined } diff --git a/src/lib/types/PermissionPolicySet.ts b/src/lib/types/PermissionPolicySet.ts index db33ce18e..2e7968604 100644 --- a/src/lib/types/PermissionPolicySet.ts +++ b/src/lib/types/PermissionPolicySet.ts @@ -13,4 +13,5 @@ export type PermissionPolicySet = { updateGroupNamePolicy: PermissionOption updateGroupDescriptionPolicy: PermissionOption updateGroupImagePolicy: PermissionOption + updateGroupPinnedFrameUrlPolicy: PermissionOption } From 91968adf8febbc46ebcf21f8737b1fe66daf8cc7 Mon Sep 17 00:00:00 2001 From: cameronvoell Date: Tue, 2 Jul 2024 21:33:57 -0700 Subject: [PATCH 2/3] updating to correct android release --- android/build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 606f471f8..b65302888 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -98,7 +98,7 @@ repositories { dependencies { implementation project(':expo-modules-core') implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}" - implementation "org.xmtp:android:0.14.2" + implementation "org.xmtp:android:0.14.3" 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" @@ -108,9 +108,9 @@ dependencies { // 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.7.3' + // implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0' // implementation 'org.web3j:crypto:5.0.0' // 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.61.1' + // api 'org.xmtp:proto-kotlin:3.62.1' } From fb74c003b268e5bf7e1f2c6a20496ab48dec7481 Mon Sep 17 00:00:00 2001 From: cameronvoell Date: Tue, 2 Jul 2024 22:23:12 -0700 Subject: [PATCH 3/3] feat: added pinned frame url --- example/ios/Podfile.lock | 14 +++--- example/src/tests/groupPermissionsTests.ts | 1 - ios/Wrappers/CreateGroupParamsWrapper.swift | 25 ++++++++++ ios/Wrappers/GroupWrapper.swift | 4 -- ios/Wrappers/PermissionPolicySetWrapper.swift | 3 +- ios/XMTPModule.swift | 46 ++++++++++++++++++- ios/XMTPReactNative.podspec | 2 +- 7 files changed, 79 insertions(+), 16 deletions(-) create mode 100644 ios/Wrappers/CreateGroupParamsWrapper.swift diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index ac598fabd..39186dddb 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -56,7 +56,7 @@ PODS: - hermes-engine/Pre-built (= 0.71.14) - hermes-engine/Pre-built (0.71.14) - libevent (2.1.12) - - LibXMTP (0.5.4-beta1) + - LibXMTP (0.5.4-beta2) - Logging (1.0.0) - MessagePacker (0.4.7) - MMKV (1.3.5): @@ -449,16 +449,16 @@ PODS: - GenericJSON (~> 2.0) - Logging (~> 1.0.0) - secp256k1.swift (~> 0.1) - - XMTP (0.13.2): + - XMTP (0.13.3): - Connect-Swift (= 0.12.0) - GzipSwift - - LibXMTP (= 0.5.4-beta1) + - LibXMTP (= 0.5.4-beta2) - web3.swift - XMTPReactNative (0.1.0): - ExpoModulesCore - MessagePacker - secp256k1.swift - - XMTP (= 0.13.2) + - XMTP (= 0.13.3) - Yoga (1.14.0) DEPENDENCIES: @@ -711,7 +711,7 @@ SPEC CHECKSUMS: GzipSwift: 893f3e48e597a1a4f62fafcb6514220fcf8287fa hermes-engine: d7cc127932c89c53374452d6f93473f1970d8e88 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 - LibXMTP: f080197cea545a7daf3bc8476d97efc3b225a8d8 + LibXMTP: 16096f324c99d44712ed40876fe25150f694feab Logging: 9ef4ecb546ad3169398d5a723bc9bea1c46bef26 MessagePacker: ab2fe250e86ea7aedd1a9ee47a37083edd41fd02 MMKV: 506311d0494023c2f7e0b62cc1f31b7370fa3cfb @@ -763,8 +763,8 @@ SPEC CHECKSUMS: secp256k1.swift: a7e7a214f6db6ce5db32cc6b2b45e5c4dd633634 SwiftProtobuf: 407a385e97fd206c4fbe880cc84123989167e0d1 web3.swift: 2263d1e12e121b2c42ffb63a5a7beb1acaf33959 - XMTP: 76ac90da19ba43afbde1382d57fbcdbdfe9491d8 - XMTPReactNative: d3104af9a1504fb42b16c60888993d1d0516afae + XMTP: ca70dd11d709df02999325663e677fe775623d1e + XMTPReactNative: 1b79a6c8748387062ebcebe2c345f77f4998cae2 Yoga: e71803b4c1fff832ccf9b92541e00f9b873119b9 PODFILE CHECKSUM: 95d6ace79946933ecf80684613842ee553dd76a2 diff --git a/example/src/tests/groupPermissionsTests.ts b/example/src/tests/groupPermissionsTests.ts index bdc0960e3..71f3e8406 100644 --- a/example/src/tests/groupPermissionsTests.ts +++ b/example/src/tests/groupPermissionsTests.ts @@ -304,7 +304,6 @@ test('can not remove a super admin from a group', async () => { // Now bo can remove Alix from the group await boGroup.removeMembers([alix.address]) - console.log('alix inbox id:' + String(alix.inboxId)) await boGroup.sync() numMembers = (await boGroup.memberInboxIds()).length assert( diff --git a/ios/Wrappers/CreateGroupParamsWrapper.swift b/ios/Wrappers/CreateGroupParamsWrapper.swift new file mode 100644 index 000000000..cbd5ab5cf --- /dev/null +++ b/ios/Wrappers/CreateGroupParamsWrapper.swift @@ -0,0 +1,25 @@ +import Foundation + +struct CreateGroupParamsWrapper { + let groupName: String + let groupImageUrlSquare: String + let groupDescription: String + let groupPinnedFrameUrl: String + + static func createGroupParamsFromJson(_ authParams: String) -> CreateGroupParamsWrapper { + let data = authParams.data(using: .utf8) ?? Data() + let jsonOptions = (try? JSONSerialization.jsonObject(with: data, options: [])) as? [String: Any] ?? [:] + + let groupName = jsonOptions["name"] as? String ?? "" + let groupImageUrlSquare = jsonOptions["imageUrlSquare"] as? String ?? "" + let groupDescription = jsonOptions["description"] as? String ?? "" + let groupPinnedFrameUrl = jsonOptions["pinnedFrameUrl"] as? String ?? "" + + return CreateGroupParamsWrapper( + groupName: groupName, + groupImageUrlSquare: groupImageUrlSquare, + groupDescription: groupDescription, + groupPinnedFrameUrl: groupPinnedFrameUrl + ) + } +} diff --git a/ios/Wrappers/GroupWrapper.swift b/ios/Wrappers/GroupWrapper.swift index a2f021835..47d49f547 100644 --- a/ios/Wrappers/GroupWrapper.swift +++ b/ios/Wrappers/GroupWrapper.swift @@ -11,7 +11,6 @@ import XMTP // Wrapper around XMTP.Group to allow passing these objects back into react native. struct GroupWrapper { static func encodeToObj(_ group: XMTP.Group, client: XMTP.Client) throws -> [String: Any] { - let permissionPolicySet = try PermissionPolicySetWrapper.encodeToJsonString(group.permissionPolicySet()) return [ "clientAddress": client.address, "id": group.id.toHex, @@ -20,10 +19,7 @@ struct GroupWrapper { "version": "GROUP", "topic": group.topic, "creatorInboxId": try group.creatorInboxId(), - "name": try group.groupName(), "isActive": try group.isActive(), - "imageUrlSquare": try group.groupImageUrlSquare(), - "description": try group.groupDescription(), ] } diff --git a/ios/Wrappers/PermissionPolicySetWrapper.swift b/ios/Wrappers/PermissionPolicySetWrapper.swift index 8c8d3d3c8..1ca923c84 100644 --- a/ios/Wrappers/PermissionPolicySetWrapper.swift +++ b/ios/Wrappers/PermissionPolicySetWrapper.swift @@ -32,7 +32,8 @@ class PermissionPolicySetWrapper { "removeAdminPolicy": fromPermissionOption(policySet.removeAdminPolicy), "updateGroupNamePolicy": fromPermissionOption(policySet.updateGroupNamePolicy), "updateGroupDescriptionPolicy": fromPermissionOption(policySet.updateGroupDescriptionPolicy), - "updateGroupImagePolicy": fromPermissionOption(policySet.updateGroupImagePolicy) + "updateGroupImagePolicy": fromPermissionOption(policySet.updateGroupImagePolicy), + "updateGroupPinnedFrameUrlPolicy": fromPermissionOption(policySet.updateGroupPinnedFrameUrlPolicy) ] } diff --git a/ios/XMTPModule.swift b/ios/XMTPModule.swift index 21bdb513f..ea1401ffa 100644 --- a/ios/XMTPModule.swift +++ b/ios/XMTPModule.swift @@ -696,7 +696,7 @@ public class XMTPModule: Module { } } - AsyncFunction("createGroup") { (inboxId: String, peerAddresses: [String], permission: String, groupName: String, groupImageUrlSquare: String, groupDescription: String) -> String in + AsyncFunction("createGroup") { (inboxId: String, peerAddresses: [String], permission: String, groupOptionsJson: String) -> String in guard let client = await clientsManager.getClient(key: inboxId) else { throw Error.noClient } @@ -709,7 +709,15 @@ public class XMTPModule: Module { } }() do { - let group = try await client.conversations.newGroup(with: peerAddresses, permissions: permissionLevel, name: groupName, imageUrlSquare: groupImageUrlSquare, description: groupDescription) + let createGroupParams = CreateGroupParamsWrapper.createGroupParamsFromJson(groupOptionsJson) + let group = try await client.conversations.newGroup( + with: peerAddresses, + permissions: permissionLevel, + name: createGroupParams.groupName, + imageUrlSquare: createGroupParams.groupImageUrlSquare, + description: createGroupParams.groupDescription, + pinnedFrameUrl: createGroupParams.groupPinnedFrameUrl + ) return try GroupWrapper.encode(group, client: client) } catch { print("ERRRO!: \(error.localizedDescription)") @@ -877,6 +885,30 @@ public class XMTPModule: Module { try await group.updateGroupDescription(groupDescription: description) } + + AsyncFunction("groupPinnedFrameUrl") { (inboxId: String, id: String) -> String in + guard let client = await clientsManager.getClient(key: inboxId) else { + throw Error.noClient + } + + guard let group = try await findGroup(inboxId: inboxId, id: id) else { + throw Error.conversationNotFound("no group found for \(id)") + } + + return try group.groupPinnedFrameUrl() + } + + AsyncFunction("updateGroupPinnedFrameUrl") { (inboxId: String, id: String, pinnedFrameUrl: String) in + guard let client = await clientsManager.getClient(key: inboxId) else { + throw Error.noClient + } + + guard let group = try await findGroup(inboxId: inboxId, id: id) else { + throw Error.conversationNotFound("no group found for \(id)") + } + + try await group.updateGroupPinnedFrameUrl(groupPinnedFrameUrl: pinnedFrameUrl) + } AsyncFunction("isGroupActive") { (inboxId: String, id: String) -> Bool in guard let client = await clientsManager.getClient(key: inboxId) else { @@ -1057,6 +1089,16 @@ public class XMTPModule: Module { } try await group.updateGroupDescriptionPermission(newPermissionOption: getPermissionOption(permission: newPermission)) } + + AsyncFunction("updateGroupPinnedFrameUrlPermission") { (clientInboxId: String, id: String, newPermission: String) in + guard let client = await clientsManager.getClient(key: clientInboxId) else { + throw Error.noClient + } + guard let group = try await findGroup(inboxId: clientInboxId, id: id) else { + throw Error.conversationNotFound("no group found for \(id)") + } + try await group.updateGroupPinnedFrameUrlPermission(newPermissionOption: getPermissionOption(permission: newPermission)) + } AsyncFunction("permissionPolicySet") { (inboxId: String, id: String) async throws -> String in diff --git a/ios/XMTPReactNative.podspec b/ios/XMTPReactNative.podspec index 703513b2d..6cbed859f 100644 --- a/ios/XMTPReactNative.podspec +++ b/ios/XMTPReactNative.podspec @@ -26,5 +26,5 @@ Pod::Spec.new do |s| s.source_files = "**/*.{h,m,swift}" s.dependency 'secp256k1.swift' s.dependency "MessagePacker" - s.dependency "XMTP", "= 0.13.2" + s.dependency "XMTP", "= 0.13.3" end