UNPKG

@amityco/ts-sdk-react-native

Version:

Amity Social Cloud Typescript SDK

128 lines (111 loc) 4.03 kB
import { getActiveClient } from '~/client/api/activeClient'; import { createEventSubscriber, fireEvent } from '~/core/events'; import { ingestInCache } from '~/cache/api/ingestInCache'; import { updateSubChannelUnreadFromMessage } from '~/marker/utils/updateSubChannelUnreadFromMessage'; import { reCalculateChannelUnreadInfo } from '~/marker/utils/reCalculateChannelUnreadInfo'; import { getActiveUser } from '~/client/api/activeUser'; import { markReadMessage } from '../utils/markReadMessage'; import { prepareMessagePayload } from '../utils'; import { pullFromCache, pushToCache } from '~/cache/api'; /** * ```js * import { onMessageCreated } from '@amityco/ts-sdk-react-native' * const dispose = onMessageCreated(message => { * // ... * }) * ``` * * Fired when an {@link Amity.Message} has been created * * @param callback The function to call when the event was fired * @param local Trigger when an event occurs from a local event or not * @returns an {@link Amity.Unsubscriber} function to stop listening * * @category Message Events */ export const onMessageCreatedMqtt = ( callback: Amity.Listener<Amity.InternalMessage>, ): Amity.Unsubscriber => { const client = getActiveClient(); const user = getActiveUser(); const filter = async (rawPayload: Amity.MessagePayload) => { const payload = await prepareMessagePayload(rawPayload); // update unreadCountInfo in cache if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) { rawPayload.messages.forEach(message => { updateSubChannelUnreadFromMessage(message); reCalculateChannelUnreadInfo(message.channelId); }); } if (client.useLegacyUnreadCount) { rawPayload.messages.forEach(message => { const channelUnread = pullFromCache<Amity.ChannelUnread>([ 'channelUnread', 'get', message.channelId, ])?.data; if ( !channelUnread || channelUnread.lastSegment >= message.segment || typeof channelUnread.readToSegment !== 'number' || typeof channelUnread.lastMentionedSegment !== 'number' ) return; const lastSegment = message.segment; const isMentionedInMessage = message.mentionedUsers?.some(mention => { return ( mention.type === 'channel' || (mention.type === 'user' && client.userId && mention.userPublicIds.includes(client.userId)) ); }); const lastMentionedSegment = isMentionedInMessage ? message.segment : channelUnread.lastMentionedSegment; const updatedChannelUnread: Amity.ChannelUnread = { ...channelUnread, lastSegment, unreadCount: Math.max(lastSegment - channelUnread.readToSegment, 0), lastMentionedSegment, isMentioned: !(channelUnread.readToSegment >= lastMentionedSegment), }; pushToCache(['channelUnread', 'get', message.channelId], updatedChannelUnread); fireEvent('local.channelUnread.updated', [updatedChannelUnread]); }); } // Update in cache ingestInCache(payload); payload.messages.forEach(message => { if (message.creatorPrivateId === user._id) markReadMessage(message); callback(message); }); }; const disposers = [ createEventSubscriber(client, 'message/onMessageCreated', 'message.created', filter), ]; return () => { disposers.forEach(fn => fn()); }; }; export const onMessageCreatedLocal = ( callback: Amity.Listener<Amity.InternalMessage>, ): Amity.Unsubscriber => { const client = getActiveClient(); const disposers = [ createEventSubscriber( client, 'message/onMessageCreated', 'local.message.created', async payload => { ingestInCache(payload); return payload.messages.forEach(message => { callback(message); }); }, ), ]; return () => { disposers.forEach(fn => fn()); }; };