import cleanAxios from "@/util/CleanAxios"; import axios from "axios"; import { useGlobalSearchParams } from "expo-router"; import React, { useCallback, useEffect, useState } from "react"; import { FlatList, RefreshControl, TouchableOpacity, View } from "react-native"; import ImageView from "react-native-image-viewing"; import { ActivityIndicator, Text } from "react-native-paper"; import { SafeAreaView } from "react-native-safe-area-context"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import env from "../../env"; import { selectBodyshop } from "../../redux/user/user.selectors"; import { DetermineFileType } from "../../util/document-upload.utility"; import ErrorDisplay from "../error/error-display"; import ImageLoader from "./image-loader"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, }); const mapDispatchToProps = (dispatch) => ({}); export default connect( mapStateToProps, mapDispatchToProps )(JobDocumentsComponent); export function JobDocumentsComponent({ bodyshop }) { const [previewVisible, setPreviewVisible] = useState(false); const [fullphotos, setFullPhotos] = useState([]); const [imgIndex, setImgIndex] = useState(0); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const { jobId } = useGlobalSearchParams(); const isLms = bodyshop.uselocalmediaserver; const onRefresh = async () => { return getPhotos(); }; const getPhotos = useCallback(async () => { setError(null); setLoading(true); try { if (!isLms) { const result = await axios.post( `${env.API_URL}/media/imgproxy/thumbnails`, { jobid: jobId, } ); setFullPhotos( result.data.map((doc, idx) => { return { id: idx, videoUrl: DetermineFileType(doc.type) === "video" && doc.originalUrlViaProxyPath, source: DetermineFileType(doc.type) === "video" ? { uri: doc.thumbnailUrl } : { uri: doc.originalUrl }, url: DetermineFileType(doc.type) === "video" ? doc.thumbnailUrl : doc.originalUrl, uri: DetermineFileType(doc.type) === "video" ? doc.originalUrlViaProxyPath : doc.originalUrl, thumbUrl: doc.thumbnailUrl, }; }) ); } else { let localmediaserverhttp = bodyshop.localmediaserverhttp.trim(); if (localmediaserverhttp.endsWith("/")) { localmediaserverhttp = localmediaserverhttp.slice(0, -1); } const imagesFetch = await cleanAxios.post( `${localmediaserverhttp}/jobs/list`, { jobid: jobId, }, { headers: { ims_token: bodyshop.localmediatoken } } ); const normalizedImages = imagesFetch.data .filter((d) => d.type?.mime?.startsWith("image")) .map((d, idx) => { return { ...d, // src: `${localmediaserverhttp}/${d.src}`, uri: `${localmediaserverhttp}${d.src}`, thumbUrl: `${localmediaserverhttp}${d.thumbnail}`, id: idx, }; }); setFullPhotos(normalizedImages); } } catch (error) { setError(error.message || "Unknown error fetching photos."); } setLoading(false); }, [isLms, jobId, bodyshop]); useEffect(() => { getPhotos(); }, [getPhotos]); if (loading) return ; if (error) { return ; } return ( } data={fullphotos} ListFooterComponent={ {`${ fullphotos.length } document${fullphotos.length === 1 ? "" : "s"}`} } numColumns={4} style={{ flex: 1 }} keyExtractor={(item) => item.id} renderItem={(object) => ( { setImgIndex(object.index); setPreviewVisible(true); }} > )} /> setPreviewVisible(false)} visible={previewVisible} images={fullphotos} imageIndex={imgIndex} swipeToCloseEnabled={true} /> ); }