import * as React from 'react'; import { Dimensions, Image } from 'react-native'; import type { IconNameType } from '../../assets'; import { gCustomMessageCardEventType, gCustomMessageCreateGroupEventType, gCustomMessageCreateThreadTip, gCustomMessageRecallEventType, gMessageAttributeQuote, gMessageAttributeVoiceReadFlag, userInfoFromMessage, } from '../../chat'; import { useConfigContext } from '../../config'; import { uilog } from '../../const'; import { ChatCustomMessageBody, ChatImageMessageBody, ChatMessage, ChatMessageChatType, ChatMessageDirection, ChatMessageStatus, ChatMessageType, ChatVideoMessageBody, } from '../../rename.chat'; import { Services } from '../../services'; import { LocalPath } from '../../utils'; import type { MessageStateType } from './types'; export function getPaddingWidth(params: { avatarWidth: number; triangleWidth: number; }) { const { avatarWidth, triangleWidth } = params; const paddingWidth = avatarWidth + triangleWidth + 12 + 8; return paddingWidth; } export function isSupportMessage(msg: ChatMessage) { if (msg.body.type === ChatMessageType.CMD) { return false; } else if (msg.body.type === ChatMessageType.LOCATION) { return false; } else if (msg.body.type === ChatMessageType.CUSTOM) { const body = msg.body as ChatCustomMessageBody; if (body.event === gCustomMessageCardEventType) { return true; } return false; } return true; } export function getMessageState(msg: ChatMessage): MessageStateType { let ret: MessageStateType = 'none'; if (msg.direction === ChatMessageDirection.RECEIVE) { switch (msg.body.type) { case ChatMessageType.VOICE: { const r = msg.attributes?.[gMessageAttributeVoiceReadFlag] as | boolean | undefined; ret = r !== true ? 'no-play' : 'none'; } } } else { if (msg.status === ChatMessageStatus.SUCCESS) { ret = 'send-success'; } else if (msg.status === ChatMessageStatus.FAIL) { ret = 'send-fail'; } else { ret = 'sending'; } if ( msg.chatType === ChatMessageChatType.PeerChat && msg.hasDeliverAck === true ) { ret = 'send-to-peer'; } if ( msg.chatType === ChatMessageChatType.PeerChat && msg.hasReadAck === true ) { ret = 'peer-read'; } } return ret; } export function getStateIcon(state: MessageStateType): IconNameType { let ret = 'loading' as IconNameType; switch (state) { case 'loading-attachment': ret = 'loading'; break; case 'send-success': ret = 'check'; break; case 'send-fail': ret = 'exclamation_mark_in_circle'; break; case 'send-to-peer': ret = 'check_2'; break; case 'peer-read': ret = 'check_2'; break; case 'sending': ret = 'loading'; break; case 'no-play': ret = 'dot_1'; break; case 'none': ret = 'loading'; break; default: break; } return ret; } export function getStateIconColor(state: MessageStateType): string { let ret = 'common'; switch (state) { case 'loading-attachment': ret = 'common'; break; case 'send-success': ret = 'common'; break; case 'send-fail': ret = 'red'; break; case 'send-to-peer': ret = 'common'; break; case 'peer-read': ret = 'green'; break; case 'sending': ret = 'common'; break; case 'no-play': ret = 'red'; break; case 'none': ret = 'common'; break; default: break; } return ret; } export async function getImageThumbUrl(msg: ChatMessage) { const body = msg.body as ChatImageMessageBody; // const tmp = '/Users/asterisk/Library/Developer/CoreSimulator/Devices/604D801A-1119-460B-8FA8-EB305EC1D5E8/data/Containers/Data/Application/9B034A2E-24F3-4233-8E7D-1FEF570F17CC/Library/Application Support/HyphenateSDK/appdata/zuoyu/zd2/thumb_b8b30d30-b466-11ee-b157-fb4184017b8e?em-redirect=true&share-secret=uLM0QLRmEe6iMvuXVj8Kki5KRZPAkp9oJpQiiLtDDEG-j8lH'; // const tmp2 = encodeURIComponent(tmp); // return tmp2; // // return tmp; // return localUrlEscape(ImageUrl(tmp)); // return 'file:///data/user/0/com.hyphenate.rn.ChatUikitExample/cache/rn_image_picker_lib_temp_8ecb3509-71d9-4574-8ada-4d92e6f947e6.jpg'; let isExisted = await Services.dcs.isExistedFile(body.thumbnailLocalPath); if (isExisted) { return LocalPath.showImage(body.thumbnailLocalPath); } isExisted = await Services.dcs.isExistedFile(body.localPath); if (isExisted) { return LocalPath.showImage(body.localPath); } return body.thumbnailRemotePath; } export async function getVideoThumbUrl(msg: ChatMessage) { const body = msg.body as ChatVideoMessageBody; let isExisted = await Services.dcs.isExistedFile(body.thumbnailLocalPath); if (isExisted) { return LocalPath.showImage(body.thumbnailLocalPath); // return localUrlEscape(ImageUrl(body.thumbnailLocalPath)); // return `file://${body.thumbnailLocalPath}`; } return body.thumbnailRemotePath; } const hw = (params: { height: number; width: number; maxWidth: number; }): { width: number; height: number } => { const { height, width, maxWidth } = params; let ret; if (width / height >= 10) { const w = maxWidth; ret = { width: w, height: w * 0.1, }; } else if (width * 4 >= 3 * height) { const w = maxWidth; ret = { width: w, height: w * (height / width), }; } else if (width * 10 >= 1 * height) { const h = (maxWidth * 4) / 3; ret = { width: (width / height) * h, height: h, }; } else { // width / height < 1 / 10 const h = (maxWidth * 4) / 3; ret = { width: 0.1 * h, height: h, }; } return ret; }; export function getImageShowSize(msg: ChatMessage, maxW?: number) { const maxWidth = maxW ?? Dimensions.get('window').width * 0.6; const body = msg.body as ChatImageMessageBody | ChatVideoMessageBody; const width = body.width; const height = body.height; if ( width !== undefined && height !== undefined && width !== null && height !== null && width !== 0 && height !== 0 ) { return hw({ width, height, maxWidth }); } else { return { width: maxWidth, height: maxWidth, }; } } export function getImageSizeFromUrl( url: string, onFinished: (result: { isOk: boolean; width?: number; height?: number; }) => void ) { Image.getSize( url, (width: number, height: number) => { onFinished({ isOk: true, width, height }); }, (error: any) => { uilog.log('dev:getImageSizeFromUrl', url, error); onFinished({ isOk: false }); } ); } export function getFileSize(size: number) { if (size === undefined) { return '0B'; } if (size < 1024) { return `${size}B`; } else if (size < 1024 * 1024) { return `${(size / 1024).toFixed(1)}KB`; } else if (size < 1024 * 1024 * 1024) { return `${(size / 1024 / 1024).toFixed(1)}MB`; } else { return `${(size / 1024 / 1024 / 1024).toFixed(1)}GB`; } } export function getMessageBubblePadding(msg: ChatMessage) { if (msg.body.type === ChatMessageType.IMAGE) { return { paddingHorizontal: undefined, paddingVertical: undefined, hasBorderRadius: true, }; } else if (msg.body.type === ChatMessageType.VIDEO) { return { paddingHorizontal: undefined, paddingVertical: undefined, hasBorderRadius: true, }; } else if (msg.body.type === ChatMessageType.CUSTOM) { const body = msg.body as ChatCustomMessageBody; if (body.event === gCustomMessageCardEventType) { return { paddingHorizontal: undefined, paddingVertical: undefined, }; } } else if (msg.body.type === ChatMessageType.FILE) { return { paddingHorizontal: undefined, paddingVertical: undefined, }; } else if (msg.body.type === ChatMessageType.TXT) { return { paddingHorizontal: undefined, paddingVertical: undefined, }; } return { paddingHorizontal: 12, paddingVertical: 7, }; } export function isQuoteMessage(msg: ChatMessage, _msgQuote?: ChatMessage) { const quote = msg.attributes?.[gMessageAttributeQuote]; return quote !== undefined; } export function getQuoteAttribute(msg: ChatMessage, _msgQuote?: ChatMessage) { const quoteAttributes = msg.attributes?.[gMessageAttributeQuote] as | { msgID: string; msgPreview: string; msgSender: string; msgType: ChatMessageType; } | undefined; return quoteAttributes; } export function getSystemTip( msg: ChatMessage, tr: (key: string, ...args: any[]) => string ): string { if (msg.body.type !== ChatMessageType.CUSTOM) { return ''; } const body = msg.body as ChatCustomMessageBody; if (body.event === gCustomMessageRecallEventType) { try { const content = body.params as { text: string; self: string; from: string; fromName: string; }; return tr( content.text, content.self === content.from, content.fromName ?? content.from ); } catch (event: any) { uilog.warn('getSystemTip:error:', event); return tr('_uikit_msg_tip_recall'); } } else if (body.event === gCustomMessageCreateGroupEventType) { try { const content = body.params as { text: string; name: string; }; return tr(content.text, content.name); } catch (event: any) { uilog.warn('getSystemTip:error:', event); return tr('_uikit_msg_tip_create_group_success_with_params'); } } else if (body.event === gCustomMessageCreateThreadTip) { try { const ret = userInfoFromMessage(msg); return tr( '_uikit_msg_tip_create_thread_finish', ret?.userName ?? ret?.userId ); } catch (event: any) { uilog.warn('getSystemTip:error:', event); return tr('_uikit_msg_tip_create_thread_finish'); } } return ''; } export function useSystemTip() { const { onSystemTip } = useConfigContext(); const systemTip = React.useCallback( (msg: ChatMessage, tr: (key: string, ...args: any[]) => string) => { return onSystemTip?.(msg, tr) ?? getSystemTip(msg, tr); }, [onSystemTip] ); const systemTipType = React.useCallback((msg: ChatMessage) => { if (msg.body.type !== ChatMessageType.CUSTOM) { return 'none'; } const body = msg.body as ChatCustomMessageBody; return body.event; }, []); return { systemTip, systemTipType, }; }