Skip to content

Commit

Permalink
Merge pull request #479 from xmtp/np/sync-all-groups
Browse files Browse the repository at this point in the history
Add ability to sync all groups
  • Loading branch information
nplasterer authored Aug 22, 2024
2 parents a83ffb0 + 0db7558 commit 8ac886b
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 36 deletions.
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.15.4"
implementation "org.xmtp:android:0.15.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 @@ -225,8 +225,7 @@ class XMTPModule : Module() {
// Conversation
"conversationMessage",
// Group
"groupMessage"

"groupMessage",
)

Function("address") { inboxId: String ->
Expand Down Expand Up @@ -953,6 +952,14 @@ class XMTPModule : Module() {
}
}

AsyncFunction("syncAllGroups") Coroutine { inboxId: String ->
withContext(Dispatchers.IO) {
logV("syncAllGroups")
val client = clients[inboxId] ?: throw XMTPException("No client")
client.conversations.syncAllGroups()
}
}

AsyncFunction("syncGroup") Coroutine { inboxId: String, id: String ->
withContext(Dispatchers.IO) {
logV("syncGroup")
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.7-beta4)
- LibXMTP (0.5.8-beta0)
- Logging (1.0.0)
- MessagePacker (0.4.7)
- MMKV (1.3.9):
Expand Down Expand Up @@ -449,16 +449,16 @@ PODS:
- GenericJSON (~> 2.0)
- Logging (~> 1.0.0)
- secp256k1.swift (~> 0.1)
- XMTP (0.14.7):
- XMTP (0.14.8):
- Connect-Swift (= 0.12.0)
- GzipSwift
- LibXMTP (= 0.5.7-beta4)
- LibXMTP (= 0.5.8-beta0)
- web3.swift
- XMTPReactNative (0.1.0):
- ExpoModulesCore
- MessagePacker
- secp256k1.swift
- XMTP (= 0.14.7)
- XMTP (= 0.14.8)
- Yoga (1.14.0)

DEPENDENCIES:
Expand Down Expand Up @@ -711,7 +711,7 @@ SPEC CHECKSUMS:
GzipSwift: 893f3e48e597a1a4f62fafcb6514220fcf8287fa
hermes-engine: d7cc127932c89c53374452d6f93473f1970d8e88
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
LibXMTP: 794ebc442e5d66ca808b87142bb91bc6c7f4661f
LibXMTP: f4fbf472602ab8db976984a32cec71161bcc376c
Logging: 9ef4ecb546ad3169398d5a723bc9bea1c46bef26
MessagePacker: ab2fe250e86ea7aedd1a9ee47a37083edd41fd02
MMKV: 817ba1eea17421547e01e087285606eb270a8dcb
Expand Down Expand Up @@ -763,8 +763,8 @@ SPEC CHECKSUMS:
secp256k1.swift: a7e7a214f6db6ce5db32cc6b2b45e5c4dd633634
SwiftProtobuf: 407a385e97fd206c4fbe880cc84123989167e0d1
web3.swift: 2263d1e12e121b2c42ffb63a5a7beb1acaf33959
XMTP: 65c9c75509211f99a251cecd0d90a6552c523269
XMTPReactNative: 82df4ffb174a36f0d3e16c842421f2881c55b6a0
XMTP: 98158fdc19763dccdf0bb6da7bf52de1a190c836
XMTPReactNative: 2b5bd98ff66306912bc14e5c240c895179e75981
Yoga: e71803b4c1fff832ccf9b92541e00f9b873119b9

PODFILE CHECKSUM: 0e6fe50018f34e575d38dc6a1fdf1f99c9596cdd
Expand Down
68 changes: 44 additions & 24 deletions example/src/tests/groupTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,28 @@ function test(name: string, perform: () => Promise<boolean>) {
groupTests.push({ name: String(counter++) + '. ' + name, run: perform })
}

async function createGroups(
client: Client,
peers: Client[],
numGroups: number,
numMessages: number
): Promise<Group[]> {
const groups = []
const addresses: string[] = peers.map((client) => client.address)
for (let i = 0; i < numGroups; i++) {
const group = await client.conversations.newGroup(addresses, {
name: `group ${i}`,
imageUrlSquare: `www.group${i}.com`,
description: `group ${i}`,
})
groups.push(group)
for (let i = 0; i < numMessages; i++) {
await group.send({ text: `Message ${i}` })
}
}
return groups
}

test('can make a MLS V3 client', async () => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const keyBytes = new Uint8Array([
Expand All @@ -44,28 +66,6 @@ test('can make a MLS V3 client', async () => {
return true
})

async function createGroups(
client: Client,
peers: Client[],
numGroups: number,
numMessages: number
): Promise<Group[]> {
const groups = []
const addresses: string[] = peers.map((client) => client.address)
for (let i = 0; i < numGroups; i++) {
const group = await client.conversations.newGroup(addresses, {
name: `group ${i}`,
imageUrlSquare: `www.group${i}.com`,
description: `group ${i}`,
})
groups.push(group)
for (let i = 0; i < numMessages; i++) {
await group.send({ text: `Message ${i}` })
}
}
return groups
}

test('calls preAuthenticateToInboxCallback when supplied', async () => {
let isCallbackCalled = 0
let isPreAuthCalled = false
Expand Down Expand Up @@ -949,7 +949,7 @@ test('can stream groups', async () => {
throw Error('Unexpected num groups (should be 1): ' + groups.length)
}

assert(groups[0].members.length == 2, "should be 2")
assert(groups[0].members.length == 2, 'should be 2')

Check warning on line 952 in example/src/tests/groupTests.ts

View workflow job for this annotation

GitHub Actions / lint

Expected '===' and instead saw '=='

// bo creates a group with alix so a stream callback is fired
// eslint-disable-next-line @typescript-eslint/no-unused-vars
Expand Down Expand Up @@ -2070,7 +2070,6 @@ test('can create new installation without breaking group', async () => {
`client 2 should see 2 members`
)

await client2.dropLocalDatabaseConnection()
await client2.deleteLocalDatabase()

// Recreating a client with wallet 2 (new installation!)
Expand Down Expand Up @@ -2109,6 +2108,27 @@ test('can list many groups members in parallel', async () => {
return true
})

test('can sync all groups', async () => {
const [alix, bo] = await createClients(2)
const groups: Group[] = await createGroups(alix, [bo], 50, 0)

const alixGroup = groups[0]
await bo.conversations.syncGroups()
const boGroup = await bo.conversations.findGroup(alixGroup.id)
await alixGroup.send('hi')
assert(
(await boGroup?.messages())?.length === 0,
`messages should be empty before sync but was ${boGroup?.messages?.length}`
)

await bo.conversations.syncAllGroups()
assert(
(await boGroup?.messages())?.length === 1,
`messages should be 4 after sync but was ${boGroup?.messages?.length}`
)
return true
})

// Commenting this out so it doesn't block people, but nice to have?
// test('can stream messages for a long time', async () => {
// const bo = await Client.createRandom({ env: 'local', enableV3: true })
Expand Down
7 changes: 7 additions & 0 deletions ios/XMTPModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,13 @@ public class XMTPModule: Module {
}
try await client.conversations.sync()
}

AsyncFunction("syncAllGroups") { (inboxId: String) in
guard let client = await clientsManager.getClient(key: inboxId) else {
throw Error.noClient
}
try await client.conversations.syncAllGroups()
}

AsyncFunction("syncGroup") { (inboxId: String, id: String) in
guard let client = await clientsManager.getClient(key: inboxId) else {
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.14.7"
s.dependency "XMTP", "= 0.14.8"
end
4 changes: 4 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,10 @@ export async function syncGroups(inboxId: string) {
await XMTPModule.syncGroups(inboxId)
}

export async function syncAllGroups(inboxId: string) {
await XMTPModule.syncAllGroups(inboxId)
}

export async function syncGroup(inboxId: string, id: string) {
await XMTPModule.syncGroup(inboxId, id)
}
Expand Down
12 changes: 11 additions & 1 deletion src/lib/Conversations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,13 +214,23 @@ export default class Conversations<
}

/**
* Executes a network request to fetch the latest list of groups assoociated with the client
* Executes a network request to fetch the latest list of groups associated with the client
* and save them to the local state.
*/
async syncGroups() {
await XMTPModule.syncGroups(this.client.inboxId)
}

/**
* Executes a network request to fetch the latest list of messages for all local groups associated with the client
* and save them to the local state.
*
* @warning call {@linkcode Conversations.syncGroups | syncGroups()} first to get the latest list of groups locally
*/
async syncAllGroups() {
await XMTPModule.syncAllGroups(this.client.inboxId)
}

/**
* Sets up a real-time stream to listen for new conversations being started.
*
Expand Down

0 comments on commit 8ac886b

Please sign in to comment.