import React, { useEffect, useState } from 'react'; import { StatusBar, StyleSheet, TouchableOpacity, View } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { Icon, Image, LoadingSpinner, Text, createStyleSheet, useAlert, useHeaderStyle, useToast, useUIKitTheme, } from '@gathertown/uikit-react-native-foundation'; import type { SendbirdFileMessage } from '@gathertown/uikit-utils'; import { Logger, getFileExtension, getFileType, isMyMessage, toMegabyte, truncate, useIIFE, } from '@gathertown/uikit-utils'; import { useLocalization, usePlatformService, useSendbirdChat } from '../hooks/useContext'; type Props = { fileMessage: SendbirdFileMessage; deleteMessage: () => Promise; onClose: () => void; onPressDownload?: (message: SendbirdFileMessage) => void; onPressDelete?: (message: SendbirdFileMessage) => void; headerShown?: boolean; headerTopInset?: number; }; const FileViewer = ({ headerShown = true, deleteMessage, headerTopInset, fileMessage, onPressDownload, onPressDelete, onClose, }: Props) => { const [loading, setLoading] = useState(true); const { bottom } = useSafeAreaInsets(); const { currentUser } = useSendbirdChat(); const { palette } = useUIKitTheme(); const { topInset, statusBarTranslucent, defaultHeight } = useHeaderStyle(); const { STRINGS } = useLocalization(); const { fileService, mediaService } = usePlatformService(); const toast = useToast(); const { alert } = useAlert(); const basicTopInset = statusBarTranslucent ? topInset : 0; const canDelete = isMyMessage(fileMessage, currentUser?.userId); const fileType = getFileType(fileMessage.type || getFileExtension(fileMessage.url)); useEffect(() => { if (fileType === 'file') onClose(); }, []); const fileViewer = useIIFE(() => { switch (fileType) { case 'image': { return ( setLoading(false)} /> ); } case 'video': case 'audio': { return ( setLoading(false)} /> ); } default: { return null; } } }); const _onPressDelete = () => { if (!canDelete) return; if (onPressDelete) { onPressDelete(fileMessage); } else { alert({ title: STRINGS.LABELS.CHANNEL_MESSAGE_DELETE_CONFIRM_TITLE, buttons: [ { text: STRINGS.LABELS.CHANNEL_MESSAGE_DELETE_CONFIRM_CANCEL, }, { text: STRINGS.LABELS.CHANNEL_MESSAGE_DELETE_CONFIRM_OK, style: 'destructive', onPress: () => { deleteMessage() .then(() => { onClose(); }) .catch(() => { toast.show(STRINGS.TOAST.DELETE_MSG_ERROR, 'error'); }); }, }, ], }); } }; const _onPressDownload = () => { if (onPressDownload) { onPressDownload(fileMessage); } else { if (toMegabyte(fileMessage.size) > 4) { toast.show(STRINGS.TOAST.DOWNLOAD_START, 'success'); } fileService .save({ fileUrl: fileMessage.url, fileName: fileMessage.name, fileType: fileMessage.type }) .then((response) => { toast.show(STRINGS.TOAST.DOWNLOAD_OK, 'success'); Logger.log('File saved to', response); }) .catch((err) => { toast.show(STRINGS.TOAST.DOWNLOAD_ERROR, 'error'); Logger.log('File save failure', err); }); } }; return ( {fileViewer} {loading && } {headerShown && ( )} ); }; type HeaderProps = { topInset: number; onClose: () => void; title: string; subtitle: string; }; const FileViewerHeader = ({ topInset, onClose, subtitle, title }: HeaderProps) => { const { palette } = useUIKitTheme(); const { defaultHeight } = useHeaderStyle(); const { left, right } = useSafeAreaInsets(); return ( {truncate(title, { mode: 'mid', maxLen: 18 })} {subtitle} ); }; type FooterProps = { bottomInset: number; deleteShown: boolean; onPressDelete: () => void; onPressDownload: () => void; }; const FileViewerFooter = ({ bottomInset, deleteShown, onPressDelete, onPressDownload }: FooterProps) => { const { palette } = useUIKitTheme(); const { defaultHeight } = useHeaderStyle(); const { left, right } = useSafeAreaInsets(); return ( {deleteShown && } ); }; const styles = createStyleSheet({ headerContainer: { top: 0, left: 0, right: 0, position: 'absolute', flexDirection: 'row', alignItems: 'center', justifyContent: 'center', paddingHorizontal: 12, }, barButton: { width: 32, height: 32, alignItems: 'center', justifyContent: 'center', }, barTitleContainer: { flex: 1, alignItems: 'center', justifyContent: 'center', }, headerTitle: { marginBottom: 2, }, footerContainer: { position: 'absolute', left: 0, right: 0, bottom: 0, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', paddingHorizontal: 12, }, }); export default FileViewer;