import { useApolloClient } from "@apollo/client"; import { Ionicons } from "@expo/vector-icons"; import { AssetsSelector } from "expo-images-picker"; import * as MediaLibrary from "expo-media-library"; import _ from "lodash"; import React, { useCallback, useState } from "react"; import { useTranslation } from "react-i18next"; import { StyleSheet, Text, View, Alert } from "react-native"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { logImEXEvent } from "../../firebase/firebase.analytics"; import { selectCurrentCameraJobId, selectDeleteAfterUpload, } from "../../redux/app/app.selectors"; import { selectBodyshop, selectCurrentUser, } from "../../redux/user/user.selectors"; import { handleUpload } from "../../util/document-upload.utility"; import CameraSelectJob from "../camera-select-job/camera-select-job.component"; import UploadDeleteSwitch from "../upload-delete-switch/upload-delete-switch.component"; import UploadProgress from "../upload-progress/upload-progress.component"; import { GET_DOC_SIZE_TOTALS } from "../../graphql/documents.queries"; //const limit = plimit(2); import * as FileSystem from "expo-file-system"; const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser, bodyshop: selectBodyshop, selectedCameraJobId: selectCurrentCameraJobId, deleteAfterUpload: selectDeleteAfterUpload, }); export function ImageBrowserScreen({ currentUser, bodyshop, selectedCameraJobId, deleteAfterUpload, }) { const { t } = useTranslation(); const [uploads, setUploads] = useState({}); function handleOnProgress(uri, percent) { setUploads((prevUploads) => ({ ...prevUploads, [uri]: { percent } })); } const [tick, setTick] = useState(0); const forceRerender = useCallback(() => { setTick((tick) => tick + 1); }, []); const client = useApolloClient(); async function handleOnSuccess(uri, id) { console.log("Succesful upload!", uri); logImEXEvent("imexmobile_successful_upload"); setUploads((prevUploads) => _.omit(prevUploads, uri)); } const onDone = async (data) => { logImEXEvent("imexmobile_upload_documents", { count: data.length }); //Validate to make sure the totals for the file sizes do not exceed the total on the job. const queryData = await client.query({ query: GET_DOC_SIZE_TOTALS, fetchPolicy: "network-only", variables: { jobId: selectedCameraJobId !== "temp" ? selectedCameraJobId : null, }, }); const totalOfUploads = await data.reduce(async (acc, val) => { //Get the size of the file based on URI. const info = await FileSystem.getInfoAsync(val.uri, { size: true }); return (await acc) + info.size; }, 0); console.log("data :>> ", data); console.log( "Size of uploaded documents.", queryData.data.documents_aggregate.aggregate.sum.size, "Shop Limit", bodyshop.jobsizelimit, "Space remaining", bodyshop.jobsizelimit - queryData.data.documents_aggregate.aggregate.sum.size, "Total of uploaded files", totalOfUploads ); if ( bodyshop.jobsizelimit - queryData.data.documents_aggregate.aggregate.sum.size <= totalOfUploads ) { //No more room... abandon ship. Alert.alert( t("mediabrowser.labels.storageexceeded_title"), t("mediabrowser.labels.storageexceeded") ); return; } const ret = await Promise.all( data.map(async (p) => { let filename; //Appears to work for android. //iOS provides the filename, android doe snot. filename = p.filename || p.uri.split("/").pop(); const result = await handleUpload( { //iOS provides the file name. Android does not. uri: p.uri, filename, mediaId: p.id, onError: handleOnError, onProgress: ({ percent }) => handleOnProgress(filename, percent), onSuccess: () => handleOnSuccess(filename, p.id), }, { bodyshop: bodyshop, jobId: selectedCameraJobId !== "temp" ? selectedCameraJobId : null, uploaded_by: currentUser.email, photo: p, } ); return result; }) ); if (deleteAfterUpload) { try { const result = await MediaLibrary.deleteAssetsAsync( ret.map((r) => r.mediaId) ); console.log("Delete result :>> ", result); } catch (error) { console.log("Unable to delete picture.", error); } } forceRerender(); }; return ( {!selectedCameraJobId && ( {t("mediabrowser.labels.selectjobassetselector")} )} {selectedCameraJobId && ( { forceRerender(); }, doneFunction: onDone, }, noAssets: { Component: function NoAsset() { return ( {t("mediabrowser.labels.nomedia")} ); }, }, }} /> )} ); } const styles = StyleSheet.create({ flex: { flex: 1, }, container: { display: "flex", // position: "relative", }, buttonStyle: { //backgroundColor: "tomato", }, // eslint-disable-next-line react-native/no-color-literals textStyle: { color: "dodgerblue", }, }); function handleOnError(...props) { console.log("HandleOnError", props); logImEXEvent("imexmobile_upload_documents_error", { props }); } export default connect(mapStateToProps, null)(ImageBrowserScreen);