import { ColorsStatus } from "@/constants/ColorsStatus"; import { ConstEnv } from "@/constants/ConstEnv"; import { isImageFile } from "@/constants/FileExtensions"; import Styles from "@/constants/Styles"; import { useTheme } from "@/providers/ThemeProvider"; import { MaterialCommunityIcons } from "@expo/vector-icons"; import * as FileSystem from 'expo-file-system'; import { startActivityAsync } from 'expo-intent-launcher'; import * as Sharing from 'expo-sharing'; import React, { useState } from "react"; import { Dimensions, Platform, Pressable, View } from "react-native"; import { ScrollView } from "react-native-gesture-handler"; import ImageViewing from "react-native-image-viewing"; import * as mime from 'react-native-mime-types'; import Toast from "react-native-toast-message"; import Text from "./Text"; type Props = { title?: string subtitle?: string | React.ReactNode icon: React.ReactNode desc?: string rightTopInfo?: string onPress?: () => void onLongPress?: () => void borderType: 'all' | 'bottom' | 'none' leftBottomInfo?: React.ReactNode | string rightBottomInfo?: React.ReactNode | string titleWeight?: 'normal' | 'bold' bgColor?: 'white' | 'transparent' width?: number descEllipsize?: boolean textColor?: string, colorPress?: boolean titleShowAll?: boolean dataFile: { id: string; idStorage: string; name: string; extension: string }[] } type PropsFile = { id: string; idStorage: string; name: string; extension: string } export default function BorderBottomItem2({ title, subtitle, icon, desc, onPress, onLongPress, rightTopInfo, borderType, leftBottomInfo, rightBottomInfo, titleWeight, bgColor, width, descEllipsize, textColor, colorPress, titleShowAll, dataFile }: Props) { const { colors } = useTheme(); const lebarDim = Dimensions.get("window").width; const lebar = width ? lebarDim * width / 100 : 'auto'; const textColorFix = textColor ? textColor : colors.text; const [isTap, setIsTap] = useState(false); const [loadingOpen, setLoadingOpen] = useState(false) const [chooseFile, setChooseFile] = useState() const [preview, setPreview] = useState(false) function handleChooseFile(item: PropsFile) { setChooseFile(item) setPreview(true) } const openFile = async (item: PropsFile) => { try { setLoadingOpen(true); const remoteUrl = ConstEnv.url_storage + '/files/' + item.idStorage; const fileName = item.name + '.' + item.extension; const localPath = `${FileSystem.documentDirectory}/${fileName}`; const mimeType = mime.lookup(fileName); // Download the file const downloadResult = await FileSystem.downloadAsync(remoteUrl, localPath); if (downloadResult.status !== 200) { throw new Error(`Download failed with status ${downloadResult.status}`); } const contentURL = await FileSystem.getContentUriAsync(downloadResult.uri); try { if (Platform.OS === 'android') { await startActivityAsync( 'android.intent.action.VIEW', { data: contentURL, flags: 1, type: mimeType as string, } ); } else if (Platform.OS === 'ios') { await Sharing.shareAsync(localPath); } } catch (openError) { console.error('Error opening file:', openError); Toast.show({ type: 'error', text1: 'Tidak ada aplikasi yang dapat membuka file ini' }); } } catch (error) { console.error('Error downloading or opening file:', error); Toast.show({ type: 'error', text1: 'Gagal membuka file', text2: 'Silakan coba lagi nanti' }); } finally { setLoadingOpen(false); } }; return ( <> setIsTap(true)} onPressOut={() => setIsTap(false)} style={({ pressed }) => [ borderType == 'bottom' ? [Styles.wrapItemBorderBottom, { borderBottomColor: colors.icon + '20' }] : borderType == 'all' ? [Styles.wrapItemBorderAll, { borderColor: colors.icon + '20' }] : Styles.wrapItemBorderNone, bgColor && bgColor == 'white' && { backgroundColor: colors.card }, // efek warna saat ditekan (sementara) isTap && colorPress && ColorsStatus.pressedGray, ]} > {icon} {title} { subtitle && typeof subtitle == "string" ? {subtitle} : {subtitle} } { rightTopInfo && {rightTopInfo} } {desc && {desc}} { dataFile.length > 0 && ( {dataFile.map((item, index) => ( { isImageFile(item.extension) ? handleChooseFile(item) : openFile(item) }} > {item.name}.{item.extension} ))} ) } { (leftBottomInfo || rightBottomInfo) && ( { typeof leftBottomInfo == 'string' ? {leftBottomInfo} : leftBottomInfo } { typeof rightBottomInfo == 'string' ? {rightBottomInfo} : rightBottomInfo } ) } setPreview(false)} doubleTapToZoomEnabled HeaderComponent={({ imageIndex }) => ( {/* CLOSE */} setPreview(false)} accessibilityRole="button" accessibilityLabel="Close image viewer" > {/* MENU */} chooseFile && openFile(chooseFile)} accessibilityRole="button" accessibilityLabel="Download or share image" disabled={loadingOpen} > )} FooterComponent={({ imageIndex }) => ( {chooseFile?.name}.{chooseFile?.extension} )} /> ) }