Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add group image url #418

Merged
merged 4 commits into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ repositories {
dependencies {
implementation project(':expo-modules-core')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
implementation "org.xmtp:android:0.12.4"
implementation "org.xmtp:android:0.12.5"
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 @@ -785,15 +785,20 @@ class XMTPModule : Module() {
ConversationWrapper.encode(client, conversation)
}
}
AsyncFunction("createGroup") Coroutine { inboxId: String, peerAddresses: List<String>, permission: String ->
AsyncFunction("createGroup") Coroutine { inboxId: String, peerAddresses: List<String>, permission: String, groupName: String, groupImageUrlSquare: String ->
withContext(Dispatchers.IO) {
logV("createGroup")
val client = clients[inboxId] ?: throw XMTPException("No client")
val permissionLevel = when (permission) {
"admin_only" -> GroupPermissions.ADMIN_ONLY
else -> GroupPermissions.ALL_MEMBERS
}
val group = client.conversations.newGroup(peerAddresses, permissionLevel)
val group = client.conversations.newGroup(
peerAddresses,
permissionLevel,
groupName,
groupImageUrlSquare
)
GroupWrapper.encode(client, group)
}
}
Expand Down Expand Up @@ -893,6 +898,26 @@ class XMTPModule : Module() {
}
}

AsyncFunction("groupImageUrlSquare") Coroutine { inboxId: String, id: String ->
withContext(Dispatchers.IO) {
logV("groupImageUrlSquare")
val client = clients[inboxId] ?: throw XMTPException("No client")
val group = findGroup(inboxId, id)

group?.imageUrlSquare
}
}

AsyncFunction("updateGroupImageUrlSquare") Coroutine { inboxId: String, id: String, groupImageUrl: String ->
withContext(Dispatchers.IO) {
logV("updateGroupImageUrlSquare")
val client = clients[inboxId] ?: throw XMTPException("No client")
val group = findGroup(inboxId, id)

group?.updateGroupImageUrlSquare(groupImageUrl)
}
}

AsyncFunction("isGroupActive") Coroutine { inboxId: String, id: String ->
withContext(Dispatchers.IO) {
logV("isGroupActive")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ class GroupWrapper {
"permissionLevel" to permissionString,
"creatorInboxId" to group.creatorInboxId(),
"name" to group.name,
"isActive" to group.isActive()
"isActive" to group.isActive(),
"imageUrlSquare" to group.imageUrlSquare
)
}

Expand Down
14 changes: 7 additions & 7 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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.1-beta1)
- LibXMTP (0.5.1-beta2)
- Logging (1.0.0)
- MessagePacker (0.4.7)
- MMKV (1.3.5):
Expand Down Expand Up @@ -449,16 +449,16 @@ PODS:
- GenericJSON (~> 2.0)
- Logging (~> 1.0.0)
- secp256k1.swift (~> 0.1)
- XMTP (0.11.6):
- XMTP (0.11.7):
- Connect-Swift (= 0.12.0)
- GzipSwift
- LibXMTP (= 0.5.1-beta1)
- LibXMTP (= 0.5.1-beta2)
- web3.swift
- XMTPReactNative (0.1.0):
- ExpoModulesCore
- MessagePacker
- secp256k1.swift
- XMTP (= 0.11.6)
- XMTP (= 0.11.7)
- Yoga (1.14.0)

DEPENDENCIES:
Expand Down Expand Up @@ -711,7 +711,7 @@ SPEC CHECKSUMS:
GzipSwift: 893f3e48e597a1a4f62fafcb6514220fcf8287fa
hermes-engine: d7cc127932c89c53374452d6f93473f1970d8e88
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
LibXMTP: f897dba3ea05dd5f8b9d098176cd9cb7c73ad505
LibXMTP: 954acfb393be3b19bf44ea9009af558c00222450
Logging: 9ef4ecb546ad3169398d5a723bc9bea1c46bef26
MessagePacker: ab2fe250e86ea7aedd1a9ee47a37083edd41fd02
MMKV: 506311d0494023c2f7e0b62cc1f31b7370fa3cfb
Expand Down Expand Up @@ -763,8 +763,8 @@ SPEC CHECKSUMS:
secp256k1.swift: a7e7a214f6db6ce5db32cc6b2b45e5c4dd633634
SwiftProtobuf: 407a385e97fd206c4fbe880cc84123989167e0d1
web3.swift: 2263d1e12e121b2c42ffb63a5a7beb1acaf33959
XMTP: 5986c7bc1400b8b054569d4c7c6d2f673d992be1
XMTPReactNative: ed4824399c26767008b8266992085461f0cece98
XMTP: b8ab59997ee95106778f445992fa00adce6c2d71
XMTPReactNative: fc0eae046a9a3e3031c6d3b9921e15a6d5b13e09
Yoga: e71803b4c1fff832ccf9b92541e00f9b873119b9

PODFILE CHECKSUM: 95d6ace79946933ecf80684613842ee553dd76a2
Expand Down
57 changes: 56 additions & 1 deletion example/src/tests/groupTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1004,12 +1004,67 @@ test('can stream all messages', async () => {
return true
})

test('can make a group with metadata', async () => {
const [alix, bo] = await createClients(2)

const alixGroup = await alix.conversations.newGroup([bo.address], {
name: 'Start Name',
imageUrlSquare: 'starturl.com',
alexrisch marked this conversation as resolved.
Show resolved Hide resolved
})

const groupName1 = await alixGroup.groupName()
const groupImageUrl1 = await alixGroup.groupImageUrlSquare()
assert(
groupName1 === 'Start Name',
`the group should start with a name of Start Name not ${groupName1}`
)

assert(
groupImageUrl1 === 'starturl.com',
`the group should start with a name of starturl.com not ${groupImageUrl1}`
)

await alixGroup.updateGroupName('New Name')
await alixGroup.updateGroupImageUrlSquare('newurl.com')
await alixGroup.sync()
await bo.conversations.syncGroups()
const boGroups = await bo.conversations.listGroups()
const boGroup = boGroups[0]
await boGroup.sync()

const groupName2 = await alixGroup.groupName()
const groupImageUrl2 = await alixGroup.groupImageUrlSquare()
assert(
groupName2 === 'New Name',
`the group should start with a name of New Name not ${groupName2}`
)

assert(
groupImageUrl2 === 'newurl.com',
`the group should start with a name of newurl.com not ${groupImageUrl2}`
)

const groupName3 = await boGroup.groupName()
const groupImageUrl3 = await boGroup.groupImageUrlSquare()
assert(
groupName3 === 'New Name',
`the group should start with a name of New Name not ${groupName3}`
)

assert(
groupImageUrl3 === 'newurl.com',
`the group should start with a name of newurl.com not ${groupImageUrl3}`
)

return true
})

test('can make a group with admin permissions', async () => {
const [adminClient, anotherClient] = await createClients(2)

const group = await adminClient.conversations.newGroup(
[anotherClient.address],
'admin_only'
{ permissionLevel: 'admin_only' }
)

if (group.permissionLevel !== 'admin_only') {
Expand Down
3 changes: 2 additions & 1 deletion ios/Wrappers/GroupWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ struct GroupWrapper {
"permissionLevel": permissionString,
"creatorInboxId": try group.creatorInboxId(),
"name": try group.groupName(),
"isActive": try group.isActive()
"isActive": try group.isActive(),
"imageUrlSquare": try group.groupImageUrlSquare(),
]
}

Expand Down
29 changes: 26 additions & 3 deletions ios/XMTPModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@ public class XMTPModule: Module {
}
}

AsyncFunction("createGroup") { (inboxId: String, peerAddresses: [String], permission: String) -> String in
AsyncFunction("createGroup") { (inboxId: String, peerAddresses: [String], permission: String, groupName: String, groupImageUrlSquare: String) -> String in
guard let client = await clientsManager.getClient(key: inboxId) else {
throw Error.noClient
}
Expand All @@ -672,7 +672,7 @@ public class XMTPModule: Module {
}
}()
do {
let group = try await client.conversations.newGroup(with: peerAddresses, permissions: permissionLevel)
let group = try await client.conversations.newGroup(with: peerAddresses, permissions: permissionLevel, name: groupName, imageUrlSquare: groupImageUrlSquare)
return try GroupWrapper.encode(group, client: client)
} catch {
print("ERRRO!: \(error.localizedDescription)")
Expand Down Expand Up @@ -769,7 +769,6 @@ public class XMTPModule: Module {
try await group.removeMembersByInboxId(inboxIds: inboxIds)
}


AsyncFunction("groupName") { (inboxId: String, id: String) -> String in
guard let client = await clientsManager.getClient(key: inboxId) else {
throw Error.noClient
Expand All @@ -794,6 +793,30 @@ public class XMTPModule: Module {
try await group.updateGroupName(groupName: groupName)
}

AsyncFunction("groupImageUrlSquare") { (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.groupImageUrlSquare()
}

AsyncFunction("updateGroupImageUrlSquare") { (inboxId: String, id: String, groupImageUrl: 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.updateGroupImageUrlSquare(imageUrlSquare: groupImageUrl)
}

AsyncFunction("isGroupActive") { (inboxId: String, id: String) -> Bool in
guard let client = await clientsManager.getClient(key: inboxId) else {
throw Error.noClient
Expand Down
2 changes: 1 addition & 1 deletion ios/XMTPReactNative.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -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.11.6"
s.dependency "XMTP", "= 0.11.7"
end
23 changes: 21 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import { ConversationSendPayload } from './lib/types'
import { DefaultContentTypes } from './lib/types/DefaultContentType'
import { getAddress } from './utils/address'
import { InboxId } from './lib/Client'

Check warning on line 26 in src/index.ts

View workflow job for this annotation

GitHub Actions / lint

`./lib/Client` import should occur before import of `./lib/ConsentListEntry`

export * from './context'
export * from './hooks'
Expand Down Expand Up @@ -127,15 +127,19 @@
>(
client: Client<ContentTypes>,
peerAddresses: string[],
permissionLevel: 'all_members' | 'admin_only' = 'all_members'
permissionLevel: 'all_members' | 'admin_only' = 'all_members',
name: string = '',
imageUrlSquare: string = ''
): Promise<Group<ContentTypes>> {
return new Group(
client,
JSON.parse(
await XMTPModule.createGroup(
client.inboxId,
peerAddresses,
permissionLevel
permissionLevel,
name,
imageUrlSquare
)
)
)
Expand Down Expand Up @@ -254,6 +258,21 @@
return XMTPModule.removeGroupMembersByInboxId(inboxId, id, inboxIds)
}

export function groupImageUrlSquare(
inboxId: string,
id: string
): string | PromiseLike<string> {
return XMTPModule.groupImageUrlSquare(inboxId, id)
}

export function updateGroupImageUrlSquare(
inboxId: string,
id: string,
imageUrlSquare: string
): Promise<void> {
return XMTPModule.updateGroupImageUrlSquare(inboxId, id, imageUrlSquare)
}

export function groupName(
inboxId: string,
id: string
Expand Down
7 changes: 5 additions & 2 deletions src/lib/Conversations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import * as XMTPModule from '../index'
import { ContentCodec } from '../index'
import { getAddress } from '../utils/address'
import { CreateGroupOptions } from './types/CreateGroupOptions'

Check warning on line 16 in src/lib/Conversations.ts

View workflow job for this annotation

GitHub Actions / lint

`./types/CreateGroupOptions` import should occur before import of `./types/EventTypes`

export default class Conversations<
ContentTypes extends ContentCodec<any>[] = [],
Expand Down Expand Up @@ -151,12 +152,14 @@
*/
async newGroup(
peerAddresses: string[],
permissionLevel: 'all_members' | 'admin_only' = 'all_members'
opts?: CreateGroupOptions | undefined
): Promise<Group<ContentTypes>> {
return await XMTPModule.createGroup(
this.client,
peerAddresses,
permissionLevel
opts?.permissionLevel,
opts?.name,
opts?.imageUrlSquare
)
}

Expand Down
27 changes: 27 additions & 0 deletions src/lib/Group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export class Group<
permissionLevel: 'all_members' | 'admin_only'
name: string
isGroupActive: boolean
imageUrlSquare: string

constructor(
client: XMTP.Client<ContentTypes>,
Expand All @@ -38,6 +39,7 @@ export class Group<
topic: string
name: string
isGroupActive: boolean
imageUrlSquare: string
}
) {
this.client = client
Expand All @@ -49,6 +51,7 @@ export class Group<
this.permissionLevel = params.permissionLevel
this.name = params.name
this.isGroupActive = params.isGroupActive
this.imageUrlSquare = params.imageUrlSquare
}

/**
Expand Down Expand Up @@ -235,6 +238,30 @@ export class Group<
return XMTP.updateGroupName(this.client.inboxId, this.id, groupName)
}

/**
* Returns the group image url square.
* To get the latest group image url square from the network, call sync() first.
* @returns {string} A Promise that resolves to the group name.
*/
async groupImageUrlSquare(): Promise<string> {
return XMTP.groupImageUrlSquare(this.client.inboxId, this.id)
}

/**
* Updates the group image url square.
* Will throw if the user does not have the required permissions.
* @param {string} imageUrlSquare new group profile image url
* @returns
*/

async updateGroupImageUrlSquare(imageUrlSquare: string): Promise<void> {
return XMTP.updateGroupImageUrlSquare(
this.client.inboxId,
this.id,
imageUrlSquare
)
}

/**
* Returns whether the group is active.
* To get the latest active status from the network, call sync() first
Expand Down
5 changes: 5 additions & 0 deletions src/lib/types/CreateGroupOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export type CreateGroupOptions = {
permissionLevel?: 'all_members' | 'admin_only' | undefined
name?: string | undefined
imageUrlSquare?: string | undefined
}
Loading