Skip to content

Commit

Permalink
Merge pull request #23 from xmtp/np/add-message-pagination
Browse files Browse the repository at this point in the history
Add message pagination
  • Loading branch information
nplasterer authored May 1, 2023
2 parents 3e9eb4f + a580b45 commit 5cfbc67
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,22 +106,27 @@ class XMTPModule : Module() {
AsyncFunction("auth") { address: String, environment: String ->
val reactSigner = ReactNativeSigner(module = this@XMTPModule, address = address)
signer = reactSigner
val options = ClientOptions(api = apiEnvironments[environment] ?: apiEnvironments["dev"]!!)
val options =
ClientOptions(api = apiEnvironments[environment] ?: apiEnvironments["dev"]!!)
client = Client().create(account = reactSigner, options = options)
signer = null
sendEvent("authed")
}

Function("receiveSignature") { requestID: String, signature: String ->
signer?.handle(id = requestID, signature = signature)
}

// Generate a random wallet and set the client to that
AsyncFunction("createRandom") { environment: String ->
val privateKey = PrivateKeyBuilder()
val options = ClientOptions(api = apiEnvironments[environment] ?: apiEnvironments["dev"]!!)
val options =
ClientOptions(api = apiEnvironments[environment] ?: apiEnvironments["dev"]!!)
val randomClient = Client().create(account = privateKey, options = options)
client = randomClient
randomClient.address
}

//
// Client API
AsyncFunction("listConversations") { ->
Expand All @@ -134,16 +139,21 @@ class XMTPModule : Module() {
ConversationWrapper.encode(conversation)
}
}
// TODO: Support pagination
AsyncFunction("loadMessages") { conversationTopic: String, conversationID: String? ->

AsyncFunction("loadMessages") { conversationTopic: String, conversationID: String?, limit: Int?, before: Long?, after: Long? ->
if (client == null) {
throw XMTPException("No client")
}
val conversation =
findConversation(topic = conversationTopic, conversationId = conversationID)
?: throw XMTPException("no conversation found for $conversationTopic")
conversation.messages(after = Date(0)).map { DecodedMessageWrapper.encode(it) }
val beforeDate = if(before != null) Date(before) else null
val afterDate = if(after != null) Date(after) else null

conversation.messages(limit = limit, before = beforeDate, after = afterDate)
.map { DecodedMessageWrapper.encode(it) }
}

// TODO: Support content types
AsyncFunction("sendMessage") { conversationTopic: String, conversationID: String?, content: String ->
if (client == null) {
Expand All @@ -157,6 +167,7 @@ class XMTPModule : Module() {
preparedMessage.send()
DecodedMessageWrapper.encode(decodedMessage)
}

AsyncFunction("createConversation") { peerAddress: String, conversationID: String? ->
if (client == null) {
throw XMTPException("No client")
Expand All @@ -171,9 +182,11 @@ class XMTPModule : Module() {
}

Function("subscribeToConversations") { subscribeToConversations() }

AsyncFunction("subscribeToMessages") { topic: String, conversationID: String? ->
subscribeToMessages(topic = topic, conversationId = conversationID)
}

AsyncFunction("unsubscribeFromMessages") { topic: String, conversationID: String? ->
unsubscribeFromMessages(topic = topic, conversationId = conversationID)
}
Expand Down
7 changes: 4 additions & 3 deletions ios/XMTPModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -148,17 +148,18 @@ public class XMTPModule: Module {
}
}

// TODO: Support pagination
AsyncFunction("loadMessages") { (conversationTopic: String, conversationID: String?) -> [String] in
AsyncFunction("loadMessages") { (conversationTopic: String, conversationID: String?, limit: Int?, before: Double?, after: Double?) -> [String] in
guard let client else {
throw Error.noClient
}

guard let conversation = try await findConversation(topic: conversationTopic, conversationID: conversationID) else {
throw Error.conversationNotFound("no conversation found for \(conversationTopic)")
}
let beforeDate = before != nil ? Date(timeIntervalSince1970: before!) : nil
let afterDate = after != nil ? Date(timeIntervalSince1970: after!) : nil

return try await conversation.messages(after: Date.init(timeIntervalSince1970: 0)).map { try DecodedMessageWrapper.encode($0) }
return try await conversation.messages(limit: limit, before: beforeDate, after: afterDate).map { try DecodedMessageWrapper.encode($0) }
}

// TODO: Support content types
Expand Down
7 changes: 5 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@ export async function listConversations(): Promise<Conversation[]> {

export async function listMessages(
conversationTopic: string,
conversationID: string | undefined
conversationID: string | undefined,
limit?: number | undefined,
before?: Date | undefined,
after?: Date | undefined
): Promise<DecodedMessage[]> {
return (await XMTPModule.loadMessages(conversationTopic, conversationID)).map(
return (await XMTPModule.loadMessages(conversationTopic, conversationID, limit, before?.getTime, after?.getTime)).map(
(json: string) => {
return JSON.parse(json);
}
Expand Down
4 changes: 2 additions & 2 deletions src/lib/Conversation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ export class Conversation {
}

// TODO: Support pagination and conversation ID here
async messages(): Promise<DecodedMessage[]> {
async messages(limit?: number | undefined, before?: Date | undefined, after?: Date | undefined): Promise<DecodedMessage[]> {
try {
return await XMTP.listMessages(this.topic, this.conversationID);
return await XMTP.listMessages(this.topic, this.conversationID, limit, before, after);
} catch (e) {
console.info("ERROR in listMessages", e);
return [];
Expand Down

0 comments on commit 5cfbc67

Please sign in to comment.