import * as MediaLibrary from "expo-media-library"; import { DateTime } from "luxon"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { ActivityIndicator, Alert, Modal, StyleSheet, Text, View, } from "react-native"; import { ProgressBar } from "react-native-paper"; import Toast from "react-native-toast-message"; 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 { formatBytes } from "../../util/document-upload.utility"; import { handleLocalUpload } from "../../util/local-document-upload.utility"; const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser, bodyshop: selectBodyshop, selectedCameraJobId: selectCurrentCameraJobId, deleteAfterUpload: selectDeleteAfterUpload, }); export default connect(mapStateToProps, null)(UploadProgress); export function UploadProgress({ currentUser, bodyshop, selectedCameraJobId, deleteAfterUpload, uploads, setUploads, forceRerender, }) { const [progress, setProgress] = useState({ loading: false, uploadInProgress: false, speed: 0, }); let filesToDelete = []; const { t } = useTranslation(); useEffect(() => { //Set the state of uploads to do. if (uploads) { beginUploads(uploads); setUploads(null); } }, [uploads]); function handleOnSuccess({ duration }) { //If it's not in production, show a toast with the time. Toast.show({ type: "success", text1: ` Upload completed in ${duration}.`, // // text2: duration, }); logImEXEvent("imexmobile_successful_upload"); setProgress({ ...progress, speed: 0, percent: 1, uploadInProgress: false }); } function handleOnProgress({ percent, loaded }) { setProgress((progress) => ({ ...progress, speed: loaded - progress.loaded, loaded: loaded, percent, })); } function handleOnError({ assetid, error }) { logImEXEvent("imexmobile_upload_documents_error"); Toast.show({ type: "error", text1: "Unable to upload documents.", text2: (error && error.message) || JSON.stringify(error), autoHide: false, }); } const beginUploads = async (data) => { //Validate to make sure the totals for the file sizes do not exceed the total on the job. setProgress({ percent: 0, loaded: 0, uploadInProgress: true, start: new Date(), average: 0, }); await handleLocalUpload({ files: data, onError: ({ assetid, error }) => handleOnError({ assetid, error }), onProgress: ({ percent, loaded }) => handleOnProgress({ percent, loaded }), onSuccess: ({ duration }) => handleOnSuccess({ duration }), context: { jobid: selectedCameraJobId !== "temp" ? selectedCameraJobId : "temporary", }, }); if (deleteAfterUpload) { try { const a = await MediaLibrary.getAssetsAsync(); const res = await Promise.all( filesToDelete.map((f) => { return MediaLibrary.removeAssetsFromAlbumAsync(f, f.albumId); }) ); const deleteResult = await MediaLibrary.deleteAssetsAsync( filesToDelete.map((f) => f.id) ); } catch (error) { console.log("Unable to delete picture.", error); } } filesToDelete = []; setProgress({ loading: false, speed: 0, uploadInProgress: false, }); forceRerender(); }; console.log(progress); return ( { Alert.alert("Cancel?", "Do you want to abort the upload?", [ { text: "Yes", onPress: () => { setUploads(null); setProgress(null); }, }, { text: "No" }, ]); }} > {`${formatBytes( progress.speed )}/sec`} {`Avg. ${formatBytes( progress.loaded / ((new Date() - progress.start) / 1000) )}/sec`} {`Total Uploaded ${formatBytes(progress.loaded)}/sec`} {`Duration ${( (new Date() - progress.start) / 1000 ).toFixed(1)} sec`} ); } const styles = StyleSheet.create({ modalContainer: { display: "flex", flex: 1, justifyContent: "center", }, modal: { // flex: 1, display: "flex", marginLeft: 20, marginRight: 20, backgroundColor: "white", borderRadius: 20, padding: 18, shadowColor: "#000", shadowOffset: { width: 0, height: 2, }, shadowOpacity: 0.25, shadowRadius: 4, elevation: 5, }, });