UNPKG

stream-chat-react-native-core

Version:

The official React Native and Expo components for Stream Chat, a service for building chat applications

148 lines (130 loc) 4.45 kB
import { Attachment, AttachmentPreUploadMiddleware, FileReference, isLocalImageAttachment, isLocalVideoAttachment, LocalAttachment, MessageComposer, MessageComposerMiddlewareState, MessageCompositionMiddleware, MessageDraftComposerMiddlewareValueState, MessageDraftCompositionMiddleware, MiddlewareHandlerParams, } from 'stream-chat'; import { isLocalUrl } from '../utils/utils'; export const localAttachmentToAttachment = (localAttachment: LocalAttachment) => { const { localMetadata, ...attachment } = localAttachment; if (isLocalImageAttachment(localAttachment)) { const isRemoteUri = !!attachment.image_url && !isLocalUrl(attachment.image_url); if (isRemoteUri) return attachment as Attachment; return { ...attachment, image_url: localMetadata?.previewUri, localId: localMetadata?.id, originalFile: localMetadata.file, } as Attachment; } else { const isRemoteUri = !!attachment.asset_url && !isLocalUrl(attachment.asset_url); if (isRemoteUri) return attachment as Attachment; return { ...attachment, asset_url: (localMetadata.file as FileReference).uri, localId: localMetadata?.id, originalFile: localMetadata.file, } as Attachment; } }; export const createAttachmentsCompositionMiddleware = ( composer: MessageComposer, ): MessageCompositionMiddleware => ({ handlers: { compose: ({ state, next, forward, }: MiddlewareHandlerParams<MessageComposerMiddlewareState>) => { const { attachmentManager } = composer; if (!attachmentManager) return forward(); const attachments = (state.message.attachments ?? []).concat( attachmentManager.attachments // Blocked attachments (e.g. over the size limit) are permanent // validation failures the server will reject, so never serialize // them into the outgoing message. .filter((attachment) => attachment.localMetadata.uploadState !== 'blocked') .map(localAttachmentToAttachment), ); // prevent introducing attachments array into the payload sent to the server if (!attachments.length) return forward(); return next({ ...state, localMessage: { ...state.localMessage, attachments: [...attachments], }, message: { ...state.message, attachments: [...attachments], }, }); }, }, id: 'stream-io/message-composer-middleware/attachments', }); export const createDraftAttachmentsCompositionMiddleware = ( composer: MessageComposer, ): MessageDraftCompositionMiddleware => ({ handlers: { compose: ({ state, next, forward, }: MiddlewareHandlerParams<MessageDraftComposerMiddlewareValueState>) => { const { attachmentManager } = composer; if (!attachmentManager) return forward(); const attachments = (state.draft.attachments ?? []).concat( attachmentManager.attachments // Don't persist blocked attachments (e.g. over the size limit) into // the draft — they are permanent validation failures. .filter((attachment) => attachment.localMetadata.uploadState !== 'blocked') .map(localAttachmentToAttachment), ); return next({ ...state, draft: { ...state.draft, attachments, }, }); }, }, id: 'stream-io/message-composer-middleware/draft-attachments', }); const createVideoAttachmentPreviewMiddleware = (): AttachmentPreUploadMiddleware => ({ id: 'stream-io/message-composer-ui-middleware/video-attachment-preview', handlers: { prepare: ({ next, forward, state }) => { const { attachment } = state; if (!attachment || !isLocalVideoAttachment(attachment)) { return forward(); } return next({ ...state, attachment: { ...attachment, localMetadata: { ...attachment.localMetadata, previewUri: attachment.thumb_url, }, }, }); }, }, }); export const setupVideoAttachmentPreviewMiddleware = (messageComposer: MessageComposer) => { messageComposer.attachmentManager.preUploadMiddlewareExecutor.insert({ middleware: [createVideoAttachmentPreviewMiddleware()], position: { after: 'stream-io/attachment-manager-middleware/file-upload-config-check' }, unique: true, }); };