import { Image as NativeImage, Pressable, Text, View } from "react-native"; import { type ExternalPathString, useRouter } from "expo-router"; import MaterialIcons from "@expo/vector-icons/MaterialIcons"; import { styles } from "@/styles/components/fileDisplay"; import type { APIFile, DashURL } from "@/types/zipline"; import type { Mimetypes } from "@/types/mimetypes"; import { guessExtension } from "@/functions/util"; import { useEffect, useState } from "react"; import * as db from "@/functions/database"; import { Image } from "expo-image"; interface Props { uri: string; name: string; alt?: string; width: number; file?: APIFile; height?: number; mimetype?: string; openable?: boolean; maxHeight?: number; autoHeight?: boolean; passwordProtected?: boolean; originalName?: string | null; onPress?: () => void | Promise; } export default function FileDisplay({ uri, alt, name, file, mimetype, maxHeight, width = 200, originalName, height = width, openable = true, autoHeight = false, passwordProtected = false, onPress, }: Props) { const router = useRouter(); const dashUrl = db.get("url") as DashURL | null; const [imageHeight, setImageHeight] = useState(height); useEffect(() => { if (autoHeight) { (async () => { const size = await NativeImage.getSize(uri); let scaledHeight = (width * size.height) / size.width; if (maxHeight && scaledHeight > maxHeight) scaledHeight = maxHeight; setImageHeight(scaledHeight); })(); } }, [uri, width, maxHeight, autoHeight]); if (file) { mimetype = file.type; uri = mimetype.startsWith("video/") && file.thumbnail ? file.thumbnail : `${dashUrl}/raw/${file.name}`; name = file.name; originalName = file.originalName; passwordProtected = file.password; } if (passwordProtected) { return ( {openable ? "Click to view password " : ""} {originalName || name} ); } if (!mimetype) { const uriExtension = uri.split(".").pop(); const nameExtension = name.split(".").pop(); const originalNameExtension = originalName?.split(".").pop(); const isOctetStream = [ uriExtension, nameExtension, originalNameExtension, ].some((extension) => extension === "so"); mimetype = guessExtension(uriExtension as Mimetypes[keyof Mimetypes]); if ( mimetype === "application/octet-stream" && !isOctetStream && nameExtension ) mimetype = guessExtension(nameExtension as Mimetypes[keyof Mimetypes]); if ( mimetype === "application/octet-stream" && !isOctetStream && originalNameExtension ) mimetype = guessExtension( originalNameExtension as Mimetypes[keyof Mimetypes], ); } const displayableMimetypes = [ "image/webp", "image/apng", "image/png", "image/avif", "image/heic", "image/jpeg", "image/gif", "image/x-icon", "image/svg+xml", ]; if ( displayableMimetypes.includes(mimetype) || (mimetype.startsWith("video/") && file?.thumbnail) ) return ( {alt ); return ( {openable ? "Click to view " : ""} {originalName || name} ); function onPressDefault() { if (file) router.replace(`${dashUrl}${file.url}` as ExternalPathString); } }