Update jobline display and related jobs.
This commit is contained in:
6
app.json
6
app.json
@@ -6,7 +6,7 @@
|
|||||||
"scheme": "imex-mobile-scheme",
|
"scheme": "imex-mobile-scheme",
|
||||||
"userInterfaceStyle": "automatic",
|
"userInterfaceStyle": "automatic",
|
||||||
"extra": {
|
"extra": {
|
||||||
"expover": "18",
|
"expover": "19",
|
||||||
"eas": {
|
"eas": {
|
||||||
"projectId": "ffe01f3a-d507-4698-82cd-da1f1cad450b"
|
"projectId": "ffe01f3a-d507-4698-82cd-da1f1cad450b"
|
||||||
}
|
}
|
||||||
@@ -34,7 +34,9 @@
|
|||||||
"permissions": [
|
"permissions": [
|
||||||
"android.permission.READ_EXTERNAL_STORAGE",
|
"android.permission.READ_EXTERNAL_STORAGE",
|
||||||
"android.permission.WRITE_EXTERNAL_STORAGE",
|
"android.permission.WRITE_EXTERNAL_STORAGE",
|
||||||
"android.permission.ACCESS_MEDIA_LOCATION"
|
"android.permission.ACCESS_MEDIA_LOCATION",
|
||||||
|
"android.permission.READ_MEDIA_IMAGES",
|
||||||
|
"android.permission.READ_MEDIA_VIDEO"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"splash": {
|
"splash": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { openImagePicker } from "@/redux/photos/photos.actions";
|
import { openImagePicker } from "@/redux/photos/photos.actions";
|
||||||
import * as Haptics from "expo-haptics";
|
import * as Haptics from "expo-haptics";
|
||||||
import { Stack, useLocalSearchParams } from "expo-router";
|
import { Stack, useGlobalSearchParams } from "expo-router";
|
||||||
import { useCallback } from "react";
|
import { useCallback } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { IconButton } from "react-native-paper";
|
import { IconButton } from "react-native-paper";
|
||||||
@@ -13,7 +13,7 @@ export default connect(null, mapDispatchToProps)(JobsStack);
|
|||||||
|
|
||||||
function JobsStack({ openImagePicker }) {
|
function JobsStack({ openImagePicker }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { jobId } = useLocalSearchParams();
|
const { jobId } = useGlobalSearchParams();
|
||||||
|
|
||||||
const handleUpload = useCallback(() => {
|
const handleUpload = useCallback(() => {
|
||||||
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
|
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<babeledit_project be_version="2.7.1" version="1.2">
|
<babeledit_project version="1.2" be_version="2.7.1">
|
||||||
<!--
|
<!--
|
||||||
|
|
||||||
BabelEdit project file
|
BabelEdit project file
|
||||||
@@ -4585,6 +4585,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>related_ros</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>repairtotal</name>
|
<name>repairtotal</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { GET_JOB_BY_PK } from "@/graphql/jobs.queries";
|
import { GET_JOB_LINES } from "@/graphql/jobs.queries";
|
||||||
import { useQuery } from "@apollo/client";
|
import { useQuery } from "@apollo/client";
|
||||||
import { useGlobalSearchParams } from "expo-router";
|
import { useGlobalSearchParams } from "expo-router";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
@@ -10,7 +10,7 @@ import ErrorDisplay from "../error/error-display";
|
|||||||
export default function JobLines() {
|
export default function JobLines() {
|
||||||
const { jobId } = useGlobalSearchParams();
|
const { jobId } = useGlobalSearchParams();
|
||||||
|
|
||||||
const { loading, error, data, refetch } = useQuery(GET_JOB_BY_PK, {
|
const { loading, error, data, refetch } = useQuery(GET_JOB_LINES, {
|
||||||
variables: {
|
variables: {
|
||||||
id: jobId,
|
id: jobId,
|
||||||
},
|
},
|
||||||
@@ -47,13 +47,13 @@ export default function JobLines() {
|
|||||||
<DataTable.Title style={{ flex: 2 }}>
|
<DataTable.Title style={{ flex: 2 }}>
|
||||||
{t("jobdetail.labels.lines_lbr_ty")}
|
{t("jobdetail.labels.lines_lbr_ty")}
|
||||||
</DataTable.Title>
|
</DataTable.Title>
|
||||||
<DataTable.Title style={{ flex: 1 }} numeric>
|
<DataTable.Title style={{ flex: 1 }}>
|
||||||
{t("jobdetail.labels.lines_lb_hrs")}
|
{t("jobdetail.labels.lines_lb_hrs")}
|
||||||
</DataTable.Title>
|
</DataTable.Title>
|
||||||
<DataTable.Title style={{ flex: 2 }}>
|
<DataTable.Title style={{ flex: 2 }}>
|
||||||
{t("jobdetail.labels.lines_part_type")}
|
{t("jobdetail.labels.lines_part_type")}
|
||||||
</DataTable.Title>
|
</DataTable.Title>
|
||||||
<DataTable.Title style={{ flex: 1 }} numeric>
|
<DataTable.Title style={{ flex: 1 }}>
|
||||||
{t("jobdetail.labels.lines_qty")}
|
{t("jobdetail.labels.lines_qty")}
|
||||||
</DataTable.Title>
|
</DataTable.Title>
|
||||||
</DataTable.Header>
|
</DataTable.Header>
|
||||||
@@ -71,15 +71,13 @@ export default function JobLines() {
|
|||||||
<DataTable.Cell style={{ flex: 2 }}>
|
<DataTable.Cell style={{ flex: 2 }}>
|
||||||
{item.mod_lbr_ty && t(`jobdetail.lbr_types.${item.mod_lbr_ty}`)}
|
{item.mod_lbr_ty && t(`jobdetail.lbr_types.${item.mod_lbr_ty}`)}
|
||||||
</DataTable.Cell>
|
</DataTable.Cell>
|
||||||
<DataTable.Cell style={{ flex: 1 }} numeric>
|
<DataTable.Cell style={{ flex: 1 }}>
|
||||||
{item.mod_lb_hrs}
|
{item.mod_lb_hrs}
|
||||||
</DataTable.Cell>
|
</DataTable.Cell>
|
||||||
<DataTable.Cell style={{ flex: 2 }}>
|
<DataTable.Cell style={{ flex: 2 }}>
|
||||||
{item.part_type && t(`jobdetail.part_types.${item.part_type}`)}
|
{item.part_type && t(`jobdetail.part_types.${item.part_type}`)}
|
||||||
</DataTable.Cell>
|
</DataTable.Cell>
|
||||||
<DataTable.Cell style={{ flex: 1 }} numeric>
|
<DataTable.Cell style={{ flex: 1 }}>{item.part_qty}</DataTable.Cell>
|
||||||
{item.part_qty}
|
|
||||||
</DataTable.Cell>
|
|
||||||
</DataTable.Row>
|
</DataTable.Row>
|
||||||
))}
|
))}
|
||||||
</DataTable>
|
</DataTable>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { GET_JOB_BY_PK } from "@/graphql/jobs.queries";
|
import { GET_JOB_NOTES } from "@/graphql/jobs.queries";
|
||||||
import { useQuery } from "@apollo/client";
|
import { useQuery } from "@apollo/client";
|
||||||
import { AntDesign } from "@expo/vector-icons";
|
import { AntDesign } from "@expo/vector-icons";
|
||||||
import { useGlobalSearchParams } from "expo-router";
|
import { useGlobalSearchParams } from "expo-router";
|
||||||
@@ -22,7 +22,7 @@ export default function JobNotes() {
|
|||||||
const showNoteModal = () => setNoteModalVisible(true);
|
const showNoteModal = () => setNoteModalVisible(true);
|
||||||
const hideNoteModal = () => setNoteModalVisible(false);
|
const hideNoteModal = () => setNoteModalVisible(false);
|
||||||
|
|
||||||
const { loading, error, data, refetch } = useQuery(GET_JOB_BY_PK, {
|
const { loading, error, data, refetch } = useQuery(GET_JOB_NOTES, {
|
||||||
variables: {
|
variables: {
|
||||||
id: jobId,
|
id: jobId,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { GET_JOB_BY_PK } from "@/graphql/jobs.queries";
|
import { GET_JOB_NOTES } from "@/graphql/jobs.queries";
|
||||||
import { INSERT_NEW_NOTE } from "@/graphql/notes.queries";
|
import { INSERT_NEW_NOTE } from "@/graphql/notes.queries";
|
||||||
import { selectCurrentUser } from "@/redux/user/user.selectors";
|
import { selectCurrentUser } from "@/redux/user/user.selectors";
|
||||||
import { useMutation } from "@apollo/client";
|
import { useMutation } from "@apollo/client";
|
||||||
@@ -97,7 +97,7 @@ const NewNoteModal = ({
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const [insertNote, { loading }] = useMutation(INSERT_NEW_NOTE, {
|
const [insertNote, { loading }] = useMutation(INSERT_NEW_NOTE, {
|
||||||
refetchQueries: [{ query: GET_JOB_BY_PK, variables: { id: jobId } }],
|
refetchQueries: [{ query: GET_JOB_NOTES, variables: { id: jobId } }],
|
||||||
awaitRefetchQueries: true,
|
awaitRefetchQueries: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
import { GET_JOB_BY_PK } from "@/graphql/jobs.queries";
|
import { GET_JOB_TOMBSTONE } from "@/graphql/jobs.queries";
|
||||||
import { selectBodyshop } from "@/redux/user/user.selectors";
|
import { selectBodyshop } from "@/redux/user/user.selectors";
|
||||||
import { useQuery } from "@apollo/client";
|
import { useQuery } from "@apollo/client";
|
||||||
import { useLocalSearchParams } from "expo-router";
|
import { useLocalSearchParams, useRouter } from "expo-router";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { RefreshControl, ScrollView, StyleSheet, View } from "react-native";
|
import {
|
||||||
|
RefreshControl,
|
||||||
|
ScrollView,
|
||||||
|
StyleSheet,
|
||||||
|
TouchableOpacity,
|
||||||
|
View
|
||||||
|
} from "react-native";
|
||||||
import { ActivityIndicator, Card, Chip, Text } from "react-native-paper";
|
import { ActivityIndicator, Card, Chip, Text } from "react-native-paper";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
@@ -20,7 +26,8 @@ export default connect(mapStateToProps, mapDispatchToProps)(JobTombstone);
|
|||||||
|
|
||||||
function JobTombstone({ bodyshop }) {
|
function JobTombstone({ bodyshop }) {
|
||||||
const { jobId } = useLocalSearchParams();
|
const { jobId } = useLocalSearchParams();
|
||||||
const { loading, error, data, refetch } = useQuery(GET_JOB_BY_PK, {
|
const router = useRouter();
|
||||||
|
const { loading, error, data, refetch } = useQuery(GET_JOB_TOMBSTONE, {
|
||||||
variables: {
|
variables: {
|
||||||
id: jobId,
|
id: jobId,
|
||||||
},
|
},
|
||||||
@@ -100,7 +107,8 @@ function JobTombstone({ bodyshop }) {
|
|||||||
title={t("jobdetail.labels.jobinfo")}
|
title={t("jobdetail.labels.jobinfo")}
|
||||||
titleVariant="titleLarge"
|
titleVariant="titleLarge"
|
||||||
/>
|
/>
|
||||||
<Card.Content>
|
<Card.Content style={localStyles.twoColumnCard}>
|
||||||
|
<View style={localStyles.twoColumnCardColumn}>
|
||||||
<DataLabelComponent
|
<DataLabelComponent
|
||||||
label={t("objects.jobs.fields.status")}
|
label={t("objects.jobs.fields.status")}
|
||||||
content={
|
content={
|
||||||
@@ -129,6 +137,35 @@ function JobTombstone({ bodyshop }) {
|
|||||||
content={<Text>{job.production_vars.note}</Text>}
|
content={<Text>{job.production_vars.note}</Text>}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
</View>
|
||||||
|
<View style={localStyles.twoColumnCardColumn}>
|
||||||
|
<DataLabelComponent
|
||||||
|
label={t("objects.jobs.fields.related_ros")}
|
||||||
|
content={
|
||||||
|
<View
|
||||||
|
style={{ flexDirection: "row", flexWrap: "wrap", gap: 8 }}
|
||||||
|
>
|
||||||
|
{job.vehicle?.jobs
|
||||||
|
?.filter((ro) => ro.id !== job.id)
|
||||||
|
.map((ro) => (
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => {
|
||||||
|
router.navigate({
|
||||||
|
pathname: `/jobs/${ro.id}`,
|
||||||
|
params: {
|
||||||
|
title: ro.ro_number || t("general.labels.na"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
key={ro.id}
|
||||||
|
>
|
||||||
|
<Chip mode="outlined">{ro.ro_number || "N/A"}</Chip>
|
||||||
|
</TouchableOpacity>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
</Card.Content>
|
</Card.Content>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
|||||||
@@ -924,3 +924,173 @@ export const generate_UPDATE_JOB_KANBAN = (
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export const GET_JOB_TOMBSTONE = gql`
|
||||||
|
query GET_JOB_TOMBSTONE($id: uuid!) {
|
||||||
|
jobs_by_pk(id: $id) {
|
||||||
|
updated_at
|
||||||
|
employee_body_rel {
|
||||||
|
id
|
||||||
|
first_name
|
||||||
|
last_name
|
||||||
|
}
|
||||||
|
employee_refinish_rel {
|
||||||
|
id
|
||||||
|
first_name
|
||||||
|
last_name
|
||||||
|
}
|
||||||
|
employee_prep_rel {
|
||||||
|
id
|
||||||
|
first_name
|
||||||
|
last_name
|
||||||
|
}
|
||||||
|
employee_csr_rel {
|
||||||
|
id
|
||||||
|
first_name
|
||||||
|
last_name
|
||||||
|
}
|
||||||
|
loss_desc
|
||||||
|
kmin
|
||||||
|
kmout
|
||||||
|
referral_source
|
||||||
|
unit_number
|
||||||
|
po_number
|
||||||
|
special_coverage_policy
|
||||||
|
scheduled_delivery
|
||||||
|
converted
|
||||||
|
ro_number
|
||||||
|
clm_total
|
||||||
|
inproduction
|
||||||
|
vehicleid
|
||||||
|
plate_no
|
||||||
|
v_vin
|
||||||
|
v_model_yr
|
||||||
|
v_model_desc
|
||||||
|
v_make_desc
|
||||||
|
v_color
|
||||||
|
clm_no
|
||||||
|
area_of_damage
|
||||||
|
ins_co_nm
|
||||||
|
ins_addr1
|
||||||
|
ins_city
|
||||||
|
ins_ct_ln
|
||||||
|
ins_ct_fn
|
||||||
|
ins_ea
|
||||||
|
ins_ph1
|
||||||
|
est_co_nm
|
||||||
|
est_ct_fn
|
||||||
|
est_ct_ln
|
||||||
|
pay_date
|
||||||
|
est_ph1
|
||||||
|
est_ea
|
||||||
|
regie_number
|
||||||
|
scheduled_completion
|
||||||
|
id
|
||||||
|
ded_amt
|
||||||
|
ded_status
|
||||||
|
depreciation_taxes
|
||||||
|
production_vars
|
||||||
|
other_amount_payable
|
||||||
|
towing_payable
|
||||||
|
storage_payable
|
||||||
|
adjustment_bottom_line
|
||||||
|
job_totals
|
||||||
|
ownr_fn
|
||||||
|
ownr_ln
|
||||||
|
ownr_ea
|
||||||
|
ownr_addr1
|
||||||
|
ownr_addr2
|
||||||
|
ownr_city
|
||||||
|
ownr_st
|
||||||
|
ownr_zip
|
||||||
|
ownr_ctry
|
||||||
|
ownr_ph1
|
||||||
|
actual_in
|
||||||
|
scheduled_completion
|
||||||
|
scheduled_in
|
||||||
|
actual_completion
|
||||||
|
scheduled_delivery
|
||||||
|
actual_delivery
|
||||||
|
date_estimated
|
||||||
|
date_open
|
||||||
|
date_scheduled
|
||||||
|
date_invoiced
|
||||||
|
date_exported
|
||||||
|
status
|
||||||
|
owner_owing
|
||||||
|
vehicle {
|
||||||
|
id
|
||||||
|
jobs {
|
||||||
|
id
|
||||||
|
ro_number
|
||||||
|
status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
`;
|
||||||
|
export const GET_JOB_LINES = gql`
|
||||||
|
query GET_JOB_LINES($id: uuid!) {
|
||||||
|
jobs_by_pk(id: $id) {
|
||||||
|
id
|
||||||
|
joblines(where: { removed: { _eq: false } }, order_by: { line_no: asc }) {
|
||||||
|
id
|
||||||
|
unq_seq
|
||||||
|
line_ind
|
||||||
|
tax_part
|
||||||
|
line_desc
|
||||||
|
prt_dsmk_p
|
||||||
|
prt_dsmk_m
|
||||||
|
part_type
|
||||||
|
oem_partno
|
||||||
|
db_price
|
||||||
|
act_price
|
||||||
|
part_qty
|
||||||
|
mod_lbr_ty
|
||||||
|
db_hrs
|
||||||
|
mod_lb_hrs
|
||||||
|
lbr_op
|
||||||
|
lbr_amt
|
||||||
|
op_code_desc
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
export const GET_JOB_NOTES = gql`
|
||||||
|
query GET_JOB_NOTES($id: uuid!) {
|
||||||
|
jobs_by_pk(id: $id) {
|
||||||
|
id
|
||||||
|
|
||||||
|
notes(order_by: { created_at: desc }) {
|
||||||
|
id
|
||||||
|
text
|
||||||
|
critical
|
||||||
|
private
|
||||||
|
pinned
|
||||||
|
created_at
|
||||||
|
updated_at
|
||||||
|
created_by
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
export const GET_JOB_MEDIA = gql`
|
||||||
|
query GET_JOB_MEDIA($id: uuid!) {
|
||||||
|
jobs_by_pk(id: $id) {
|
||||||
|
id
|
||||||
|
|
||||||
|
documents(order_by: { takenat: desc }) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
key
|
||||||
|
created_at
|
||||||
|
type
|
||||||
|
extension
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import Constants from "expo-constants";
|
|
||||||
import * as FileSystem from "expo-file-system/legacy";
|
import * as FileSystem from "expo-file-system/legacy";
|
||||||
import * as ImagePicker from "expo-image-picker";
|
import * as ImagePicker from "expo-image-picker";
|
||||||
import * as MediaLibrary from "expo-media-library";
|
import * as MediaLibrary from "expo-media-library";
|
||||||
@@ -63,7 +62,7 @@ export function* onOpenImagePicker() {
|
|||||||
|
|
||||||
export function* openImagePickerAction({ payload: jobid }) {
|
export function* openImagePickerAction({ payload: jobid }) {
|
||||||
try {
|
try {
|
||||||
if (Constants.platform.ios) {
|
// if (Constants.platform.ios) {
|
||||||
const cameraRollStatus =
|
const cameraRollStatus =
|
||||||
yield ImagePicker.requestMediaLibraryPermissionsAsync();
|
yield ImagePicker.requestMediaLibraryPermissionsAsync();
|
||||||
const cameraStatus = yield ImagePicker.requestCameraPermissionsAsync();
|
const cameraStatus = yield ImagePicker.requestCameraPermissionsAsync();
|
||||||
@@ -74,12 +73,13 @@ export function* openImagePickerAction({ payload: jobid }) {
|
|||||||
alert("Photo and Camera permissions have not been granted. Please open the settings app and allow these permissions to upload photos.");
|
alert("Photo and Camera permissions have not been granted. Please open the settings app and allow these permissions to upload photos.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
// }
|
||||||
let result = yield ImagePicker.launchImageLibraryAsync({
|
let result = yield ImagePicker.launchImageLibraryAsync({
|
||||||
mediaTypes: ["images", "videos"],
|
mediaTypes: ["images", "videos"],
|
||||||
aspect: [4, 3],
|
aspect: [4, 3],
|
||||||
quality: 1,
|
quality: 1,
|
||||||
allowsMultipleSelection: true,
|
allowsMultipleSelection: true,
|
||||||
|
allowsEditing: false,
|
||||||
exif: true,
|
exif: true,
|
||||||
});
|
});
|
||||||
if (!(result.canceled)) {
|
if (!(result.canceled)) {
|
||||||
@@ -411,19 +411,55 @@ function* mediaUploadCompletedAction({ payload: photos }) {
|
|||||||
const filesToDelete = Object.keys(progress).filter((key) => progress[key].status === 'completed').map((key) => progress[key]);
|
const filesToDelete = Object.keys(progress).filter((key) => progress[key].status === 'completed').map((key) => progress[key]);
|
||||||
|
|
||||||
if (Platform.OS === "android") {
|
if (Platform.OS === "android") {
|
||||||
|
yield MediaLibrary.getPermissionsAsync(false);
|
||||||
|
const asset = filesToDelete[0];
|
||||||
|
let assetIdToDelete = asset.assetId;
|
||||||
|
|
||||||
|
// 2. ANDROID FIX: Find the original asset ID
|
||||||
|
if (!assetIdToDelete && Platform.OS === 'android') {
|
||||||
|
// Fetch the last 50 images from the gallery
|
||||||
|
const recentAssets = yield call(MediaLibrary.getAssetsAsync, {
|
||||||
|
first: 50,
|
||||||
|
sortBy: [MediaLibrary.SortBy.creationTime],
|
||||||
|
mediaType: MediaLibrary.MediaType.photo,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Try to match based on width, height, and proximity of creation time
|
||||||
|
// Note: The cache file timestamp might differ slightly from the original
|
||||||
|
const foundAsset = recentAssets.assets.find(libraryItem => {
|
||||||
|
console.log("Comparing library item:", moment(asset.exif.DateTime, "YYYY:MM:DD HH:mm:ss").valueOf(), libraryItem.creationTime);
|
||||||
|
return (
|
||||||
|
libraryItem.width === asset.exif.ImageWidth &&
|
||||||
|
libraryItem.height === asset.exif.ImageLength &&
|
||||||
|
Math.abs(moment(asset.exif.DateTimeOriginal, "YYYY:MM:DD HH:mm:ss").valueOf() - libraryItem.creationTime) < 1000
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (foundAsset) {
|
||||||
|
assetIdToDelete = foundAsset.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Upload and Delete
|
||||||
|
if (assetIdToDelete) {
|
||||||
|
// await uploadFunction(asset.uri);
|
||||||
|
yield call(MediaLibrary.deleteAssetsAsync, assetIdToDelete);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Create a new asset with the first file to delete.
|
//Create a new asset with the first file to delete.
|
||||||
// console.log('Trying new delete.');
|
// console.log('Trying new delete.');
|
||||||
yield MediaLibrary.getPermissionsAsync(false);
|
|
||||||
|
|
||||||
const album = yield call(MediaLibrary.createAlbumAsync,
|
const album = yield call(MediaLibrary.createAlbumAsync,
|
||||||
"ImEX Mobile Deleted",
|
"ImEX Mobile Deleted",
|
||||||
filesToDelete.pop(),
|
filesToDelete.pop().assetId,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
//Move the rest.
|
//Move the rest.
|
||||||
if (filesToDelete.length > 0) {
|
if (filesToDelete.length > 0) {
|
||||||
const moveResult = yield call(MediaLibrary.addAssetsToAlbumAsync,
|
const moveResult = yield call(MediaLibrary.addAssetsToAlbumAsync,
|
||||||
filesToDelete,
|
filesToDelete.map(f => f.assetId),
|
||||||
album,
|
album,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
@@ -447,7 +483,7 @@ function* onMediaUploadFailure() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function* mediaUploadFailureAction({ payload: errorMessage }) {
|
function* mediaUploadFailureAction({ payload: errorMessage }) {
|
||||||
Alert.alert("Upload Error", `An error occurred during upload: ${errorMessage}`);
|
Alert.alert("Upload Error", `An error occurred during upload: ${JSON.stringify(errorMessage)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -271,6 +271,7 @@
|
|||||||
"rate_matd": "Tire Disposal",
|
"rate_matd": "Tire Disposal",
|
||||||
"referralsource": "Referral Source",
|
"referralsource": "Referral Source",
|
||||||
"regie_number": "Registration #",
|
"regie_number": "Registration #",
|
||||||
|
"related_ros": "Related Jobs",
|
||||||
"repairtotal": "Repair Total",
|
"repairtotal": "Repair Total",
|
||||||
"ro_number": "RO #",
|
"ro_number": "RO #",
|
||||||
"scheduled_completion": "Scheduled Completion",
|
"scheduled_completion": "Scheduled Completion",
|
||||||
|
|||||||
@@ -271,6 +271,7 @@
|
|||||||
"rate_matd": "Tasa de eliminación de neumáticos",
|
"rate_matd": "Tasa de eliminación de neumáticos",
|
||||||
"referralsource": "Fuente de referencia",
|
"referralsource": "Fuente de referencia",
|
||||||
"regie_number": "N. ° de registro",
|
"regie_number": "N. ° de registro",
|
||||||
|
"related_ros": "",
|
||||||
"repairtotal": "Reparación total",
|
"repairtotal": "Reparación total",
|
||||||
"ro_number": "RO #",
|
"ro_number": "RO #",
|
||||||
"scheduled_completion": "Finalización programada",
|
"scheduled_completion": "Finalización programada",
|
||||||
|
|||||||
@@ -271,6 +271,7 @@
|
|||||||
"rate_matd": "Taux d'élimination des pneus",
|
"rate_matd": "Taux d'élimination des pneus",
|
||||||
"referralsource": "Source de référence",
|
"referralsource": "Source de référence",
|
||||||
"regie_number": "Enregistrement #",
|
"regie_number": "Enregistrement #",
|
||||||
|
"related_ros": "",
|
||||||
"repairtotal": "Réparation totale",
|
"repairtotal": "Réparation totale",
|
||||||
"ro_number": "RO #",
|
"ro_number": "RO #",
|
||||||
"scheduled_completion": "Achèvement planifié",
|
"scheduled_completion": "Achèvement planifié",
|
||||||
|
|||||||
Reference in New Issue
Block a user