| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- import PubNub from 'pubnub'
-
- import { ChatMessage } from '../entities/index.js'
-
- const MAIN_CHANNEL = 'Channel-Siimee'
-
- /**
- * Provider method holder
- * We always reference this object so
- * we don't have to hardcode provider specific
- * methods for doing chat things.
- *
- * This gets overloaded later in the program
- */
- const _providerMethods = {
- publish: () => console.error('no provider publish method set'),
- subscribe: () => console.error('no provider subscribe method set'),
- listen: () => console.error('no provider listen method set'),
- }
-
- /**
- * Breaking out as much pubnub specific flavor
- */
- const _setPubnubKeys = testing => {
- let keys = {}
- if (testing) {
- keys = testing
- } else {
- ;(keys.publishKey = import.meta.env.VITE_PUBNUB_PUBLISH_KEY),
- (keys.subscribeKey = import.meta.env.VITE_PUBNUB_SUBSCRIBE_KEY)
- }
- return keys
- }
- const _setupPubnub = async (uuid, testing) => {
- if (!uuid) return console.error('no pubnub uuid set')
- const keys = _setPubnubKeys(testing)
- const pubnubClient = await new PubNub({
- publishKey: keys.publishKey,
- subscribeKey: keys.subscribeKey,
- logVerbosity: false,
- uuid,
- })
- // Pass pubnub specific methods to our placeholder obj
- _providerMethods['publish'] = pubnubClient.publish
- _providerMethods['subscribe'] = pubnubClient.subscribe
- _providerMethods['listen'] = pubnubClient.addListener
-
- return pubnubClient
- }
-
- /** Singleton that holds all our chat information */
- class Chatter {
- /**
- * Create our chatter instance
- * @return {Chatter} our chatter instance object
- */
- constructor() {
- // Our pubnub instance
- this.provider = null
- this.uuid = null
- this._subscriptions = [MAIN_CHANNEL]
-
- this.listeners = {
- status: async e => {
- if (e.category !== 'PNConnectedCategory') return
- },
- message: null, // Set manually in chat view
- presence: this._onPresence,
- }
- }
- get subscriptions() {
- let truncated = this._subscriptions
-
- // Do NOT include the main channel as part of subscriptions
- const mainChanIndex = truncated.indexOf(MAIN_CHANNEL)
- if (mainChanIndex > -1) {
- truncated.splice(mainChanIndex, 1)
- }
-
- return truncated
- }
- async _onPresence(e) {
- console.log('presence :', e)
- return
- }
- setOnMessage(cb) {
- this.listeners.message = cb
- }
-
- async setup(uuid, groupings, testing = false) {
- this.uuid = `${uuid}`
-
- // Pass api keys in ugle fasion for testing purposes
- // TODO: refactor this with a mock
- this.provider = await _setupPubnub(this.uuid, testing)
-
- // step_1: build the this.groupings object from the backend
- // await for the groupings to be fetched before subscribing to channels
- await this._setupAllChannels(groupings)
- this._listenFor({ listeners: this.listeners })
- this.subscribe({ channels: this._subscriptions })
- return this.subscriptions
- }
- async getHistory(channel, count = 10) {
- console.warn('[chatter] grabbing history for channel:', channel)
- let pastMessages = null
- try {
- pastMessages = await this.provider.fetchMessages({
- channels: [channel],
- count: count,
- includeMessageType: true,
- includeUUID: true,
- includeMeta: true,
- includeMessageActions: false,
- })
- } catch (error) {
- console.error('[chatter]', error)
- }
- const channelHistory =
- pastMessages && pastMessages.channels
- ? pastMessages.channels[channel]
- : null
- console.log('channelHistory :>> ', channelHistory)
- return channelHistory
- ? channelHistory.map(msg => ({
- publisher: msg.uuid,
- message: new ChatMessage(msg.message.description),
- timetoken: msg.timetoken,
- }))
- : []
- }
- /**
- * Send a message to a channel
- * example = new ChatMessage({ title: 'example', description: 'ni' })
- * Facade so we can hide provider specific methods
- * @param {string} channel
- * @param {ChatMessage} message
- * @return {object} timestamp
- */
- async publish(channel, message) {
- return _providerMethods.publish({
- channel,
- message: new ChatMessage(message),
- })
- }
- /**
- * Subscribe to a channels
- * Facade so we can hide provider specific methods
- * @param {array} channels grouping name
- */
- subscribe({ channels }) {
- _providerMethods.subscribe({ channels })
- }
- /**
- * Listen to events and set callbacks
- * Facade so we can hide provider specific methods
- */
- _listenFor({ listeners }) {
- _providerMethods.listen(listeners)
- }
- /**
- * Get all groupings for this profile and
- * then store them as subscriptions
- */
- async _setupAllChannels(groupings) {
- groupings.forEach(grouping => {
- this._subscriptions.push(grouping.grouping_name)
- })
- }
- stop() {
- this._subscriptions = [MAIN_CHANNEL]
- console.warn('chatter stop not implemented')
- }
- }
-
- export { Chatter, MAIN_CHANNEL }
|