Skip to content

Commit

Permalink
Add Conversation Join method (#1097)
Browse files Browse the repository at this point in the history
* Add Conversation Join method

* remove unnecessary changes

* include unit test

* include changeset

* include join for chat
  • Loading branch information
iAmmar7 authored Jul 17, 2024
1 parent 15960e7 commit b500783
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 42 deletions.
5 changes: 5 additions & 0 deletions .changeset/weak-pigs-deliver.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@signalwire/js': minor
---

CF SDK: Add Conversations Join API
19 changes: 16 additions & 3 deletions internal/playground-js/src/fabric-http/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,11 @@ <h2 class="title mt-2"></h2>
</div>
</div>
<!-- Messages will be loaded here -->
<ul id="messageList" class="list-group list-group-flush mt-4">
<ul
id="messageList"
class="overflow-auto list-group list-group-flush mt-4"
style="max-height: calc(100vh - 50vh)"
>
<li class="list-group-item">
<span class="placeholder placeholder-lg col-6"></span>
<span class="placeholder placeholder-lg col-12"></span>
Expand All @@ -237,8 +241,17 @@ <h2 class="title mt-2"></h2>
</li>
</ul>
<div class="input-group mt-4 container-fluid">
<input type="text" id="new-conversation-message" class="form-control" placeholder="Message..." aria-label="Chat Message" aria-describedby="button-addon2">
<button class="btn btn-primary" type="button" id="send-message"><i class="bi-send"></i></button>
<input
type="text"
id="new-conversation-message"
class="form-control"
placeholder="Message..."
aria-label="Chat Message"
aria-describedby="button-addon2"
/>
<button class="btn btn-primary" type="button" id="send-message">
<i class="bi-send"></i>
</button>
</div>
</div>
</div>
Expand Down
12 changes: 8 additions & 4 deletions internal/playground-js/src/fabric-http/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import { SignalWire } from '@signalwire/js'

const searchInput = document.getElementById('searchInput')
const searchType = document.getElementById('searchType')
const conversationMessageInput = document.getElementById('new-conversation-message')
const conversationMessageInput = document.getElementById(
'new-conversation-message'
)
const sendMessageBtn = document.getElementById('send-message')

let client = null
Expand Down Expand Up @@ -159,10 +161,9 @@ const createAddressListItem = (address) => {
button.className = 'btn btn-sm btn-success'

const icon = document.createElement('i')
if (channelName != 'messaging') {
if (channelName !== 'messaging') {
button.addEventListener('click', () => dialAddress(channelValue))
} else {

button.addEventListener('click', () => {
subscribeToNewMessages()
openMessageModal(address)
Expand Down Expand Up @@ -198,7 +199,7 @@ function updateAddressUI() {
addresses
.map(createAddressListItem)
.forEach((item) => addressUl.appendChild(item))
subscribeToNewMessages();
subscribeToNewMessages()
}

async function fetchAddresses() {
Expand Down Expand Up @@ -525,6 +526,9 @@ async function fetchMessages(id) {
addressId: id,
})
window.__messageData = messages
await client.conversation.join({
addressId: id,
})
updateMessageUI()
} catch (error) {
console.error('Unable to fetch messages', error)
Expand Down
2 changes: 1 addition & 1 deletion internal/playground-js/src/fabric/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ window.connect = async () => {
await call.start()
console.debug('Call Obj', call)

// Render video element using custom function
/* --------- Render video element using custom function ---------- */
// setTimeout(async () => {
// const { unsubscribe } = await buildVideoElement({
// room: call,
Expand Down
42 changes: 42 additions & 0 deletions packages/js/src/fabric/Conversation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,48 @@ describe('Conversation', () => {
})
})

describe('joinConversation', () => {
it('should join a conversation', async () => {
const addressId = uuid()
const expectedResponse = {
table: {
conversation_id: addressId,
},
}
;(httpClient.fetch as jest.Mock).mockResolvedValue({
body: expectedResponse,
})

const result = await conversation.joinConversation({
addressId,
})

expect(result).toEqual(expectedResponse)
expect(httpClient.fetch).toHaveBeenCalledWith('/api/fabric/conversations/join', {
method: 'POST',
body: {
conversation_id: addressId,
},
})
})

it('should handles errors with joinConversation', async () => {
;(httpClient.fetch as jest.Mock).mockRejectedValue(
new Error('Network error')
)

try {
await conversation.joinConversation({
addressId: uuid(),
})
fail('Expected joinConversation to throw error.')
} catch (error) {
expect(error).toBeInstanceOf(Error)
expect(error.message).toBe('Error joining a conversation!')
}
})
})

describe('subscribe', () => {
let callback

Expand Down
52 changes: 38 additions & 14 deletions packages/js/src/fabric/Conversation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import type {
ConversationChatMessagesSubsribeParams,
ConversationChatMessagesSubsribeResult,
GetConversationChatMessageResult,
JoinConversationParams,
JoinConversationResponse,
JoinConversationResult,
} from './types'
import { conversationWorker } from './workers'
import { buildPaginatedResult } from '../utils/paginatedResult'
Expand Down Expand Up @@ -59,11 +62,20 @@ export class Conversation {
})
}

/** @internal */
public handleEvent(event: ConversationEventParams) {
if (this.callbacks.length) {
this.callbacks.forEach((callback) => {
callback(event)
})
}
}

public async sendMessage(
options: SendConversationMessageParams
params: SendConversationMessageParams
): Promise<SendConversationMessageResult> {
try {
const { addressId, text } = options
const { addressId, text } = params
const path = '/api/fabric/messages'
const { body } =
await this.httpClient.fetch<SendConversationMessageResponse>(path, {
Expand All @@ -80,10 +92,10 @@ export class Conversation {
}

public async getConversations(
options?: GetConversationsParams
params?: GetConversationsParams
): Promise<GetConversationsResult> {
try {
const { pageSize } = options || {}
const { pageSize } = params || {}

const path = '/api/fabric/conversations'
const queryParams = new URLSearchParams()
Expand All @@ -105,10 +117,10 @@ export class Conversation {
}

public async getMessages(
options?: GetMessagesParams
params?: GetMessagesParams
): Promise<GetMessagesResult> {
try {
const { pageSize } = options || {}
const { pageSize } = params || {}

const path = '/api/fabric/messages'
const queryParams = new URLSearchParams()
Expand All @@ -131,10 +143,10 @@ export class Conversation {
}

public async getConversationMessages(
options: GetConversationMessagesParams
params: GetConversationMessagesParams
): Promise<GetConversationMessagesResult> {
try {
const { addressId, pageSize } = options || {}
const { addressId, pageSize } = params || {}

const path = `/api/fabric/conversations/${addressId}/messages`
const queryParams = new URLSearchParams()
Expand Down Expand Up @@ -210,12 +222,24 @@ export class Conversation {
}
}

/** @internal */
public handleEvent(event: ConversationEventParams) {
if (this.callbacks.length) {
this.callbacks.forEach((callback) => {
callback(event)
})
public async joinConversation(
params: JoinConversationParams
): Promise<JoinConversationResult> {
try {
const { addressId } = params
const path = '/api/fabric/conversations/join'
const { body } = await this.httpClient.fetch<JoinConversationResponse>(
path,
{
method: 'POST',
body: {
conversation_id: addressId,
},
}
)
return body
} catch (error) {
throw new Error('Error joining a conversation!', error)
}
}
}
14 changes: 7 additions & 7 deletions packages/js/src/fabric/ConversationAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,20 @@ import {
} from './types'

export class ConversationAPI implements ConversationContract {
constructor(
private conversation: Conversation,
private data: ConversationResponse
) {}

get id() {
return this.data.id
}

get created_at() {
get createdAt() {
return this.data.created_at
}

get last_message_at() {
get lastMessageAt() {
return this.data.last_message_at
}

Expand All @@ -27,11 +32,6 @@ export class ConversationAPI implements ConversationContract {
return this.data.name
}

constructor(
private conversation: Conversation,
private data: ConversationResponse
) {}

sendMessage(params: ConversationAPISendMessageParams) {
return this.conversation.sendMessage({
addressId: this.id,
Expand Down
5 changes: 3 additions & 2 deletions packages/js/src/fabric/SignalWire.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ export const SignalWire = (
conversation.getConversationMessages.bind(conversation),
subscribe: conversation.subscribe.bind(conversation),
sendMessage: conversation.sendMessage.bind(conversation),
join: conversation.joinConversation.bind(conversation),
},
chat: {
getMessages:
conversation.getChatMessages.bind(conversation),
getMessages: conversation.getChatMessages.bind(conversation),
subscribe: conversation.subscribeChatMessages.bind(conversation),
sendMessage: conversation.sendMessage.bind(conversation),
join: conversation.joinConversation.bind(conversation),
},
// @ts-expect-error
__httpClient: httpClient,
Expand Down
37 changes: 26 additions & 11 deletions packages/js/src/fabric/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,13 @@ export interface SignalWireContract {
getConversationMessages: Conversation['getConversationMessages']
subscribe: Conversation['subscribe']
sendMessage: Conversation['sendMessage']
join: Conversation['joinConversation']
}
chat: {
getMessages: Conversation['getChatMessages']
subscribe: Conversation['subscribeChatMessages']
sendMessage: Conversation['sendMessage']
join: Conversation['joinConversation']
}
}

Expand Down Expand Up @@ -189,8 +191,8 @@ export type GetAddressesResult = PaginatedResult<GetAddressResponse>
*/
export interface ConversationContract {
readonly id: string
readonly created_at: number
readonly last_message_at: number
readonly createdAt: number
readonly lastMessageAt: number
readonly metadata: Record<string, any>
readonly name: string
sendMessage(
Expand All @@ -208,6 +210,15 @@ export interface SendConversationMessageParams {
details?: Record<string, any>
}

export interface SendConversationMessageResponse {
table: {
conversation_id: string
text: string
}
}

export type SendConversationMessageResult = SendConversationMessageResponse

export interface GetConversationsParams {
pageSize?: number
}
Expand All @@ -220,15 +231,6 @@ export interface ConversationResponse {
name: string
}

export interface SendConversationMessageResponse {
table: {
conversation_id: string
text: string
}
}

export type SendConversationMessageResult = SendConversationMessageResponse

export type GetConversationsResponse = PaginatedResponse<ConversationResponse>

export type GetConversationsResult = PaginatedResult<ConversationContract>
Expand All @@ -246,6 +248,19 @@ export interface ConversationChatMessagesSubsribeResult {
cancel: () => CoversationSubscribeCallback[]
}

export interface JoinConversationParams {
addressId: string
}

export interface JoinConversationResponse {
table: {
conversation_id: string
text: string
}
}

export type JoinConversationResult = JoinConversationResponse

/**
* Conversation Messages
*/
Expand Down

0 comments on commit b500783

Please sign in to comment.