UNPKG

@pusher/chatkit

Version:

Pusher Chatkit client library for browsers and react native

94 lines (85 loc) 2.45 kB
import { head, isEmpty } from 'ramda' import { parseBasicMessage } from './parsers' import { urlEncode } from './utils' import { Message } from './message' export class MessageSubscription { constructor (options) { this.roomId = options.roomId this.hooks = options.hooks this.messageLimit = options.messageLimit this.userId = options.userId this.instance = options.instance this.userStore = options.userStore this.roomStore = options.roomStore this.typingIndicators = options.typingIndicators this.messageBuffer = [] // { message, ready } this.logger = options.logger } connect () { return new Promise((resolve, reject) => { this.sub = this.instance.subscribeResuming({ path: `/rooms/${this.roomId}?${urlEncode({ message_limit: this.messageLimit })}`, listeners: { onOpen: resolve, onError: reject, onEvent: this.onEvent } }) }) } cancel () { try { this.sub && this.sub.unsubscribe() } catch (err) { this.logger.debug('error when cancelling message subscription', err) } } onEvent = ({ body }) => { switch (body.event_name) { case 'new_message': this.onNewMessage(body.data) break case 'is_typing': this.onIsTyping(body.data) break } } onNewMessage = data => { const pending = { message: new Message( parseBasicMessage(data), this.userStore, this.roomStore ), ready: false } this.messageBuffer.push(pending) this.userStore.fetchMissingUsers([pending.message.senderId]) .catch(err => { this.logger.error('error fetching missing user information:', err) }) .then(() => { pending.ready = true this.flushBuffer() }) } flushBuffer = () => { while (!isEmpty(this.messageBuffer) && head(this.messageBuffer).ready) { const message = this.messageBuffer.shift().message if ( this.hooks.rooms[this.roomId] && this.hooks.rooms[this.roomId].onNewMessage ) { this.hooks.rooms[this.roomId].onNewMessage(message) } } } onIsTyping = ({ user_id: userId }) => { if (userId !== this.userId) { Promise.all([this.roomStore.get(this.roomId), this.userStore.get(userId)]) .then(([room, user]) => this.typingIndicators.onIsTyping(room, user)) } } }