IO-760 Delete pictures in bulk & other minor fixes
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useMemo } from "react";
|
||||
import React, { useMemo, useState } from "react";
|
||||
import {
|
||||
FlatList,
|
||||
Image,
|
||||
@@ -32,6 +32,8 @@ export default function JobDocumentsComponent({ job, loading, refetch }) {
|
||||
[job.documents]
|
||||
);
|
||||
|
||||
console.log("fullphotos", fullphotos);
|
||||
|
||||
return (
|
||||
<View style={{ flex: 1 }}>
|
||||
<FlatList
|
||||
@@ -40,6 +42,7 @@ export default function JobDocumentsComponent({ job, loading, refetch }) {
|
||||
}
|
||||
data={job.documents}
|
||||
numColumns={4}
|
||||
style={{ flex: 1 }}
|
||||
keyExtractor={(item) => item.id}
|
||||
renderItem={(object) => (
|
||||
<View
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import React, { useRef } from "react";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Animated } from "react-native";
|
||||
import { TouchableOpacity } from "react-native-gesture-handler";
|
||||
import { Button, List, Title } from "react-native-paper";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { logImEXEvent } from "../../firebase/firebase.utils";
|
||||
import { setCameraJob, setCameraJobId } from "../../redux/app/app.actions";
|
||||
import styles from "../styles";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
@@ -20,35 +17,35 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
export function JobListItem({ setCameraJob, setCameraJobId, item }) {
|
||||
const { t } = useTranslation();
|
||||
const navigation = useNavigation();
|
||||
const _swipeableRow = useRef(null);
|
||||
// const _swipeableRow = useRef(null);
|
||||
|
||||
const RenderRightAction = (progress, dragX) => {
|
||||
const scale = dragX.interpolate({
|
||||
inputRange: [-100, 0],
|
||||
outputRange: [0.7, 0],
|
||||
});
|
||||
// const RenderRightAction = (progress, dragX) => {
|
||||
// const scale = dragX.interpolate({
|
||||
// inputRange: [-100, 0],
|
||||
// outputRange: [0.7, 0],
|
||||
// });
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={[styles.swipe_view, styles.swipe_view_blue]}
|
||||
onPress={() => {
|
||||
logImEXEvent("imexmobile_setcamerajobid_swipe");
|
||||
setCameraJobId(item.id);
|
||||
setCameraJob(item);
|
||||
navigation.navigate("MediaBrowserTab");
|
||||
_swipeableRow.current.close();
|
||||
}}
|
||||
>
|
||||
<Animated.View
|
||||
style={{
|
||||
transform: [{ scale }],
|
||||
}}
|
||||
>
|
||||
<Ionicons name="ios-camera" size={64} color="white" />
|
||||
</Animated.View>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
||||
// return (
|
||||
// <TouchableOpacity
|
||||
// style={[styles.swipe_view, styles.swipe_view_blue]}
|
||||
// onPress={() => {
|
||||
// logImEXEvent("imexmobile_setcamerajobid_swipe");
|
||||
// setCameraJobId(item.id);
|
||||
// setCameraJob(item);
|
||||
// navigation.navigate("MediaBrowserTab");
|
||||
// _swipeableRow.current.close();
|
||||
// }}
|
||||
// >
|
||||
// <Animated.View
|
||||
// style={{
|
||||
// transform: [{ scale }],
|
||||
// }}
|
||||
// >
|
||||
// <Ionicons name="ios-camera" size={64} color="white" />
|
||||
// </Animated.View>
|
||||
// </TouchableOpacity>
|
||||
// );
|
||||
// };
|
||||
|
||||
const onPress = () => {
|
||||
logImEXEvent("imexmobile_view_job_detail");
|
||||
@@ -59,35 +56,33 @@ export function JobListItem({ setCameraJob, setCameraJobId, item }) {
|
||||
};
|
||||
|
||||
return (
|
||||
<TouchableOpacity onPress={onPress}>
|
||||
<List.Item
|
||||
title={<Title>{item.ro_number || t("general.labels.na")}</Title>}
|
||||
description={`${item.ownr_fn || ""} ${item.ownr_ln || ""} ${
|
||||
item.ownr_co_nm || ""
|
||||
} - ${item.v_model_yr || ""} ${item.v_make_desc || ""} ${
|
||||
item.v_model_desc || ""
|
||||
}`}
|
||||
right={({ style }) => (
|
||||
<Button
|
||||
style={style}
|
||||
onPress={() => {
|
||||
logImEXEvent("imexmobile_setcamerajobid_swipe");
|
||||
setCameraJobId(item.id);
|
||||
setCameraJob(item);
|
||||
navigation.navigate("MediaBrowserTab");
|
||||
_swipeableRow.current.close();
|
||||
}}
|
||||
>
|
||||
<Ionicons
|
||||
style={style}
|
||||
name="ios-add"
|
||||
size={32}
|
||||
color="dodgerblue"
|
||||
/>
|
||||
</Button>
|
||||
)}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
<List.Item
|
||||
onPress={onPress}
|
||||
title={<Title>{item.ro_number || t("general.labels.na")}</Title>}
|
||||
description={`${item.ownr_fn || ""} ${item.ownr_ln || ""} ${
|
||||
item.ownr_co_nm || ""
|
||||
} - ${item.v_model_yr || ""} ${item.v_make_desc || ""} ${
|
||||
item.v_model_desc || ""
|
||||
}`}
|
||||
right={({ style }) => (
|
||||
<Button
|
||||
style={[style, { alignSelf: "center" }]}
|
||||
onPress={() => {
|
||||
logImEXEvent("imexmobile_setcamerajobid_swipe");
|
||||
setCameraJobId(item.id);
|
||||
setCameraJob(item);
|
||||
navigation.navigate("MediaBrowserTab");
|
||||
}}
|
||||
>
|
||||
<Ionicons
|
||||
style={[style, { alignSelf: "center" }]}
|
||||
name="ios-add"
|
||||
size={32}
|
||||
color="dodgerblue"
|
||||
/>
|
||||
</Button>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import React from "react";
|
||||
import { Modal } from "react-native";
|
||||
import { Modal, SafeAreaView, TouchableOpacity, View } from "react-native";
|
||||
import Gallery from "react-native-image-gallery";
|
||||
|
||||
export default function MediaCacheOverlay({
|
||||
photos,
|
||||
previewVisible,
|
||||
@@ -9,7 +9,6 @@ export default function MediaCacheOverlay({
|
||||
imgIndex,
|
||||
setImgIndex,
|
||||
}) {
|
||||
console.log("photos :>> ", photos);
|
||||
return (
|
||||
<Modal
|
||||
onDismiss={() => setPreviewVisible(false)}
|
||||
@@ -17,7 +16,20 @@ export default function MediaCacheOverlay({
|
||||
visible={previewVisible}
|
||||
transparent={false}
|
||||
>
|
||||
<Gallery initialPage={imgIndex} style={{ flex: 1 }} images={photos} />
|
||||
<SafeAreaView style={{ flex: 1, backgroundColor: "black" }}>
|
||||
<Gallery initialPage={imgIndex} images={photos} />
|
||||
<TouchableOpacity
|
||||
style={{ position: "absolute" }}
|
||||
onPress={() => setPreviewVisible(false)}
|
||||
>
|
||||
<Ionicons
|
||||
name="ios-close"
|
||||
size={64}
|
||||
color="dodgerblue"
|
||||
style={{ margin: 20 }}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</SafeAreaView>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ import { Ionicons } from "@expo/vector-icons";
|
||||
import { AssetsSelector } from "expo-images-picker";
|
||||
import * as MediaLibrary from "expo-media-library";
|
||||
import _ from "lodash";
|
||||
import plimit from "p-limit";
|
||||
import React, { useCallback, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { StyleSheet, Text, View } from "react-native";
|
||||
@@ -22,7 +21,7 @@ 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";
|
||||
|
||||
const limit = plimit(2);
|
||||
//const limit = plimit(2);
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
currentUser: selectCurrentUser,
|
||||
@@ -52,50 +51,49 @@ export function ImageBrowserScreen({
|
||||
async function handleOnSuccess(uri, id) {
|
||||
console.log("Succesful upload!", uri);
|
||||
logImEXEvent("imexmobile_successful_upload");
|
||||
if (deleteAfterUpload) {
|
||||
try {
|
||||
const result = await MediaLibrary.deleteAssetsAsync([id]);
|
||||
console.log("Delete result :>> ", result);
|
||||
} catch (error) {
|
||||
console.log("Unable to delete picture.", error);
|
||||
}
|
||||
}
|
||||
setUploads((prevUploads) => _.omit(prevUploads, uri));
|
||||
}
|
||||
|
||||
const onDone = async (data) => {
|
||||
logImEXEvent("imexmobile_upload_documents", { count: data.length });
|
||||
const actions = [];
|
||||
data.forEach(function (p) {
|
||||
let filename;
|
||||
//Appears to work for android.
|
||||
//iOS provides the filename, android doe snot.
|
||||
filename = p.filename || p.uri.split("/").pop();
|
||||
actions.push(
|
||||
limit(
|
||||
handleUpload(
|
||||
{
|
||||
//iOS provides the file name. Android does not.
|
||||
uri: p.uri,
|
||||
filename,
|
||||
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,
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
});
|
||||
await Promise.all(actions);
|
||||
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();
|
||||
//navigation.goBack();
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import _ from "lodash";
|
||||
import React, { useMemo } from "react";
|
||||
import {
|
||||
ScrollView,
|
||||
@@ -8,7 +9,6 @@ import {
|
||||
View,
|
||||
} from "react-native";
|
||||
import * as Progress from "react-native-progress";
|
||||
import _ from "lodash";
|
||||
export default function UploadProgress({ uploads, setUploads }) {
|
||||
const uploadKeys = useMemo(() => {
|
||||
if (uploads) return Object.keys(uploads);
|
||||
@@ -46,7 +46,6 @@ export default function UploadProgress({ uploads, setUploads }) {
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
display: "flex",
|
||||
//flex: 1,
|
||||
},
|
||||
progressItem: {
|
||||
display: "flex",
|
||||
|
||||
Reference in New Issue
Block a user