diff --git a/ios/Podfile b/ios/Podfile index b008ba9c..a7df6c38 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -56,6 +56,7 @@ target 'NavigatorApp' do pod 'Permission-Contacts', :path => "#{permissions_path}/Contacts" pod 'Permission-Camera', :path => "#{permissions_path}/Camera" # pod 'RNDeviceInfo', :path => '../node_modules/react-native-device-info' + pod 'RNFileViewer', :path => '../node_modules/react-native-file-viewer' target 'NavigatorAppTests' do inherit! :complete diff --git a/package.json b/package.json index 086a9c83..125c6e13 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ }, "dependencies": { "@babel/plugin-proposal-async-generator-functions": "^7.17.12", - "@fleetbase/sdk": "1.2.7", + "@fleetbase/sdk": "1.2.8", "@fortawesome/fontawesome-svg-core": "^1.2.35", "@fortawesome/free-brands-svg-icons": "^5.15.4", "@fortawesome/free-solid-svg-icons": "^5.15.3", @@ -73,6 +73,7 @@ "react-native-dropdown-picker": "^5.4.6", "react-native-event-listeners": "^1.0.7", "react-native-fast-image": "^8.5.11", + "react-native-file-viewer": "^2.1.5", "react-native-fs": "^2.18.0", "react-native-geolocation-service": "^5.3.0-beta.1", "react-native-gesture-handler": "^1.10.3", diff --git a/src/features/Shared/OrderScreen.js b/src/features/Shared/OrderScreen.js index 66f8c9aa..ba6f331a 100644 --- a/src/features/Shared/OrderScreen.js +++ b/src/features/Shared/OrderScreen.js @@ -1,5 +1,5 @@ import { Order } from '@fleetbase/sdk'; -import { faBell, faLightbulb, faMapMarkerAlt, faMoneyBillWave, faRoute, faTimes } from '@fortawesome/free-solid-svg-icons'; +import { faBell, faFile, faLightbulb, faMapMarkerAlt, faMoneyBillWave, faRoute, faTimes } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome'; import { useNetInfo } from '@react-native-community/netinfo'; import OrderStatusBadge from 'components/OrderStatusBadge'; @@ -11,6 +11,8 @@ import { ActivityIndicator, Alert, Dimensions, Linking, RefreshControl, ScrollVi import ActionSheet from 'react-native-actions-sheet'; import { EventRegister } from 'react-native-event-listeners'; import FastImage from 'react-native-fast-image'; +import FileViewer from 'react-native-file-viewer'; +import RNFS from 'react-native-fs'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import tailwind from 'tailwind'; import { calculatePercentage, formatCurrency, formatMetaValue, getColorCode, getStatusColors, isArray, isEmpty, logError, titleize, translate } from 'utils'; @@ -29,7 +31,6 @@ const isObjectEmpty = obj => isEmpty(obj) || Object.values(obj).length === 0; const OrderScreen = ({ navigation, route }) => { const { data } = route.params; const { isConnected } = useNetInfo(); - const [netInfo, setNetInfo] = useState(''); const insets = useSafeAreaInsets(); const isMounted = useMountedState(); const actionSheetRef = createRef(); @@ -39,7 +40,6 @@ const OrderScreen = ({ navigation, route }) => { const [order, setOrder] = useState(new Order(data, fleetbase.getAdapter())); const [isLoadingAction, setIsLoadingAction] = useState(false); - const [isLoading, setIsLoading] = useState(false); const [isLoadingActivity, setIsLoadingActivity] = useState(false); const [isRefreshing, setIsRefreshing] = useState(false); const [nextActivity, setNextActivity] = useState(null); @@ -65,7 +65,7 @@ const OrderScreen = ({ navigation, route }) => { const isAdhoc = order.getAttribute('adhoc') === true; const isDriverAssigned = order.getAttribute('driver_assigned') !== null; const isOrderPing = isDriverAssigned === false && isAdhoc === true && !['completed', 'canceled'].includes(order.getAttribute('status')); - + const documents = order.getAttribute('files', []); const entitiesByDestination = (() => { const groups = []; @@ -418,6 +418,49 @@ const OrderScreen = ({ navigation, route }) => { focusPlaceOnMap(destination); } + const openMedia = async url => { + // Extract filename from URL + const fileNameParts = url?.split('/')?.pop()?.split('?'); + const fileName = fileNameParts.length > 0 ? fileNameParts[0] : ''; + + // Create local file path + const localFile = `${RNFS.DocumentDirectoryPath}/${fileName}`; + + // Set up download options + const options = { + fromUrl: url, + toFile: localFile, + }; + + RNFS.downloadFile(options).promise.then(() => { + RNFS.readDir(RNFS.DocumentDirectoryPath); + FileViewer.open(localFile); + }); + }; + + const checkIsImage = documentType => { + return documentType.content_type.startsWith('image/'); + }; + + const renderDocumentItem = (document, index) => { + return ( + + { + openMedia(document.url); + }}> + {checkIsImage(document) ? ( + + ) : ( + + + + )} + + + ); + }; + return ( @@ -515,10 +558,6 @@ const OrderScreen = ({ navigation, route }) => { Change - {/* - - Optimize - */} @@ -779,6 +818,16 @@ const OrderScreen = ({ navigation, route }) => { )} + + + + + Documents & Files + + + {documents.map((document, index) => renderDocumentItem(document, index))} + + {isArray(order.getAttribute('payload.entities', [])) && order.getAttribute('payload.entities', []).length > 0 && (