diff --git a/components/job-list-item/job-list-item.component.jsx b/components/job-list-item/job-list-item.component.jsx
index f33ba6b..0e0c780 100644
--- a/components/job-list-item/job-list-item.component.jsx
+++ b/components/job-list-item/job-list-item.component.jsx
@@ -6,25 +6,40 @@ import { useTranslation } from "react-i18next";
import { StyleSheet, Text, View } from "react-native";
import { TouchableOpacity } from "react-native-gesture-handler";
import Swipeable from "react-native-gesture-handler/Swipeable";
+import { connect } from "react-redux";
+import { createStructuredSelector } from "reselect";
+import { setCameraJob, setCameraJobId } from "../../redux/app/app.actions";
import styles from "../styles";
-const RenderRightAction = (props) => {
- const navigation = useNavigation();
- const { t } = useTranslation();
- return (
- navigation.push("JobCamera")}
- >
-
- {t("joblist.actions.swipecamera")}
-
- );
-};
+const mapStateToProps = createStructuredSelector({
+ //currentUser: selectCurrentUser
+});
+const mapDispatchToProps = (dispatch) => ({
+ setCameraJobId: (id) => dispatch(setCameraJobId(id)),
+ setCameraJob: (job) => dispatch(setCameraJob(job)),
+});
-export default function JobListItem({ item }) {
+export function JobListItem({ setCameraJob, setCameraJobId, item }) {
const navigation = useNavigation();
-
+ const RenderRightAction = (props) => {
+ const navigation = useNavigation();
+ const { t } = useTranslation();
+ return (
+ {
+ setCameraJobId(item.id);
+ setCameraJob(item);
+ navigation.navigate("TabCamera");
+ }}
+ >
+
+
+ {t("joblist.actions.swipecamera")}
+
+
+ );
+ };
const onPress = () => {
navigation.push("JobDetail", {
jobId: item.id,
@@ -73,3 +88,4 @@ const localStyles = StyleSheet.create({
marginLeft: 15,
},
});
+export default connect(mapStateToProps, mapDispatchToProps)(JobListItem);
diff --git a/components/screen-camera-job-search/screen-camera-job-search.component.jsx b/components/screen-camera-job-search/screen-camera-job-search.component.jsx
new file mode 100644
index 0000000..2c3b6dc
--- /dev/null
+++ b/components/screen-camera-job-search/screen-camera-job-search.component.jsx
@@ -0,0 +1,10 @@
+import React from "react";
+import { Text, View } from "react-native";
+
+export default function ScreenCameraJobSearch() {
+ return (
+
+ This is the media cache screen.
+
+ );
+}
diff --git a/components/screen-camera-roll/screen-camera-roll.component.jsx b/components/screen-camera-roll/screen-camera-roll.component.jsx
new file mode 100644
index 0000000..bcf5b97
--- /dev/null
+++ b/components/screen-camera-roll/screen-camera-roll.component.jsx
@@ -0,0 +1,213 @@
+import React, { Component } from "react";
+import {
+ ActivityIndicator,
+ Button,
+ Clipboard,
+ Image,
+ Share,
+ StatusBar,
+ StyleSheet,
+ Text,
+ TouchableOpacity,
+ View,
+} from "react-native";
+import { Constants } from "expo";
+import * as Permissions from "expo-permissions";
+import * as ImagePicker from "expo-image-picker";
+export default class ScreenCameraRoll extends Component {
+ state = {
+ image: null,
+ uploading: false,
+ };
+
+ render() {
+ let { image } = this.state;
+
+ return (
+
+
+
+
+ Example: Upload ImagePicker result
+
+
+
+
+
+
+ {this._maybeRenderImage()}
+ {this._maybeRenderUploadingOverlay()}
+
+ );
+ }
+
+ _maybeRenderUploadingOverlay = () => {
+ if (this.state.uploading) {
+ return (
+
+
+
+ );
+ }
+ };
+
+ _maybeRenderImage = () => {
+ let { image } = this.state;
+
+ if (!image) {
+ return;
+ }
+
+ return (
+
+
+
+
+
+
+ {image}
+
+
+ );
+ };
+
+ _share = () => {
+ Share.share({
+ message: this.state.image,
+ title: "Check out this photo",
+ url: this.state.image,
+ });
+ };
+
+ _copyToClipboard = () => {
+ Clipboard.setString(this.state.image);
+ alert("Copied image URL to clipboard");
+ };
+
+ _takePhoto = async () => {
+ const { status: cameraPerm } = await Permissions.askAsync(
+ Permissions.CAMERA
+ );
+
+ const { status: cameraRollPerm } = await Permissions.askAsync(
+ Permissions.CAMERA_ROLL
+ );
+
+ // only if user allows permission to camera AND camera roll
+ if (cameraPerm === "granted" && cameraRollPerm === "granted") {
+ let pickerResult = await ImagePicker.launchCameraAsync({
+ allowsMultipleSelection: true,
+ quality: 0.8,
+ //allowsEditing: true,
+ aspect: [4, 3],
+ });
+
+ if (!pickerResult.cancelled) {
+ this.setState({ image: pickerResult.uri });
+ }
+
+ this.uploadImageAsync(pickerResult.uri);
+ }
+ };
+
+ _pickImage = async () => {
+ const { status: cameraRollPerm } = await Permissions.askAsync(
+ Permissions.CAMERA_ROLL
+ );
+
+ // only if user allows permission to camera roll
+ if (cameraRollPerm === "granted") {
+ let pickerResult = await ImagePicker.launchImageLibraryAsync({
+ allowsEditing: true,
+ base64: true,
+ aspect: [4, 3],
+ });
+
+ if (!pickerResult.cancelled) {
+ this.setState({ image: pickerResult.uri });
+ }
+
+ this.uploadImageAsync(pickerResult.uri);
+ }
+ };
+
+ uploadImageAsync(pictureuri) {
+ let apiUrl = "http://123.123.123.123/ABC";
+
+ var data = new FormData();
+ data.append("file", {
+ uri: pictureuri,
+ name: "file",
+ type: "image/jpg",
+ });
+
+ fetch(apiUrl, {
+ headers: {
+ Accept: "application/json",
+ "Content-Type": "multipart/form-data",
+ },
+ method: "POST",
+ body: data,
+ })
+ .then((response) => {
+ console.log("succ ");
+ console.log(response);
+ })
+ .catch((err) => {
+ console.log("err ");
+ console.log(err);
+ });
+ }
+}
+
+const styles = StyleSheet.create({
+ container: {
+ alignItems: "center",
+ flex: 1,
+ justifyContent: "center",
+ },
+ exampleText: {
+ fontSize: 20,
+ marginBottom: 20,
+ marginHorizontal: 15,
+ textAlign: "center",
+ },
+ maybeRenderUploading: {
+ alignItems: "center",
+ backgroundColor: "rgba(0,0,0,0.4)",
+ justifyContent: "center",
+ },
+ maybeRenderContainer: {
+ borderRadius: 3,
+ elevation: 2,
+ marginTop: 30,
+ shadowColor: "rgba(0,0,0,1)",
+ shadowOpacity: 0.2,
+ shadowOffset: {
+ height: 4,
+ width: 4,
+ },
+ shadowRadius: 5,
+ width: 250,
+ },
+ maybeRenderImageContainer: {
+ borderTopLeftRadius: 3,
+ borderTopRightRadius: 3,
+ overflow: "hidden",
+ },
+ maybeRenderImage: {
+ height: 250,
+ width: 250,
+ },
+ maybeRenderImageText: {
+ paddingHorizontal: 10,
+ paddingVertical: 10,
+ },
+});
diff --git a/components/screen-camera/screen-camera.component.jsx b/components/screen-camera/screen-camera.component.jsx
index 1f448ef..c28078f 100644
--- a/components/screen-camera/screen-camera.component.jsx
+++ b/components/screen-camera/screen-camera.component.jsx
@@ -1,5 +1,5 @@
import React, { useState, useEffect, useRef } from "react";
-import { Text, View, TouchableOpacity } from "react-native";
+import { Text, View, TouchableOpacity, SafeAreaView } from "react-native";
import { Camera } from "expo-camera";
import {
Ionicons,
@@ -11,7 +11,20 @@ import * as FileSystem from "expo-file-system";
import * as Permissions from "expo-permissions";
import * as MediaLibrary from "expo-media-library";
-export default function ScreenCamera() {
+import { connect } from "react-redux";
+import { createStructuredSelector } from "reselect";
+import {
+ selectCurrentCameraJobId,
+ selectCurrentCameraJob,
+} from "../../redux/app/app.selectors";
+
+const mapStateToProps = createStructuredSelector({
+ cameraJobId: selectCurrentCameraJobId,
+ cameraJob: selectCurrentCameraJob,
+});
+const mapDispatchToProps = (dispatch) => ({});
+
+export function ScreenCamera({ cameraJobId, cameraJob }) {
const navigation = useNavigation();
const [hasPermission, setHasPermission] = useState(null);
const [rollPermision, setRollPermission] = useState(null);
@@ -86,57 +99,94 @@ export default function ScreenCamera() {
return (
-
navigation.push("CameraJobSearch")}
style={{
- alignSelf: "flex-end",
+ display: "flex",
+ width: "100%",
+ alignSelf: "flex-start",
alignItems: "center",
- backgroundColor: "transparent",
+ backgroundColor: "rgba(112, 128, 144, 0.3)",
+ fontSize: 20,
+ fontWeight: "bold",
}}
>
-
+
+ {cameraJob && cameraJob.ro_number}
+
+
+ {cameraJob &&
+ `${cameraJob && cameraJob.ownr_fn} ${
+ cameraJob && cameraJob.ownr_ln
+ }`}
+
+ {cameraJobId}
-
-
-
- {
- navigation.push("MediaCache");
- }}
- style={{
- alignSelf: "flex-end",
- alignItems: "center",
- backgroundColor: "transparent",
- }}
- >
-
-
-
+
+
+
+
+
+
+ {
+ navigation.push("MediaCache");
+ }}
+ style={{
+ alignSelf: "flex-end",
+ alignItems: "center",
+ backgroundColor: "transparent",
+ }}
+ >
+
+
+
+
);
}
+export default connect(mapStateToProps, mapDispatchToProps)(ScreenCamera);
diff --git a/components/screen-main/screen-main.component.jsx b/components/screen-main/screen-main.component.jsx
index 556231b..60afd71 100644
--- a/components/screen-main/screen-main.component.jsx
+++ b/components/screen-main/screen-main.component.jsx
@@ -27,8 +27,10 @@ import ScreenSettingsComponent from "../screen-settings/screen-settings.componen
import ScreenSignIn from "../screen-sign-in/screen-sign-in.component";
import ScreenSplash from "../screen-splash/screen-splash.component";
import ScreenMediaCache from "../screen-media-cache/screen-media-cache.component";
+import ScreenCameraJobSearch from "../screen-camera-job-search/screen-camera-job-search.component";
const JobStack = createStackNavigator();
+const CameraStack = createStackNavigator();
const MessagingStack = createStackNavigator();
const BottomTabs = createBottomTabNavigator();
const Drawer = createDrawerNavigator();
@@ -75,24 +77,23 @@ const JobStackNavigator = ({ navigation }) => (
i18n.t("joblist.labels.detail"),
})}
/>
-
-
);
const CameraStackNavigator = ({ navigation }) => (
-
-
+
-
-
+
+
+
+
);
const MessagingStackNavigator = ({ navigation }) => (
diff --git a/components/screen-media-cache/screen-media-cache.component.jsx b/components/screen-media-cache/screen-media-cache.component.jsx
index eb3548f..866b208 100644
--- a/components/screen-media-cache/screen-media-cache.component.jsx
+++ b/components/screen-media-cache/screen-media-cache.component.jsx
@@ -1,247 +1,47 @@
-// import React, { useEffect } from "react";
-// import * as FileSystem from "expo-file-system";
-// import { Button, Image, View, Text } from "react-native";
-// import * as ImagePicker from "expo-image-picker";
-// import Constants from "expo-constants";
-// import * as Permissions from "expo-permissions";
-
-// export default function ScreenMediaCache() {
-// FileSystem.readDirectoryAsync(FileSystem.documentDirectory).then((p) => {
-// console.log(p);
-// });
-
-// useEffect(() => {
-// (async () => {
-// if (Constants.platform.ios) {
-// const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
-// if (status !== "granted") {
-// alert("Sorry, we need camera roll permissions to make this work!");
-// }
-// }
-// })();
-// }, []);
-
-// return (
-//
-// This is the media cache screen.
-//
-// {image && (
-//
-// )}
-//
-// );
-// }
-
-import React, { Component } from "react";
-import {
- ActivityIndicator,
- Button,
- Clipboard,
- Image,
- Share,
- StatusBar,
- StyleSheet,
- Text,
- TouchableOpacity,
- View,
-} from "react-native";
-import { Constants } from "expo";
-import * as Permissions from "expo-permissions";
-import * as ImagePicker from "expo-image-picker";
-export default class App extends Component {
- state = {
- image: null,
- uploading: false,
- };
-
- render() {
- let { image } = this.state;
-
- return (
-
-
-
-
- Example: Upload ImagePicker result
-
-
-
-
-
-
- {this._maybeRenderImage()}
- {this._maybeRenderUploadingOverlay()}
-
- );
- }
-
- _maybeRenderUploadingOverlay = () => {
- if (this.state.uploading) {
- return (
-
-
-
+import * as FileSystem from "expo-file-system";
+import React, { useEffect, useState } from "react";
+import { SafeAreaView, Text } from "react-native";
+import { Button, Text as NBText } from "native-base";
+export default function ScreenMediaCache() {
+ const [images, setImages] = useState([]);
+ useEffect(() => {
+ (async () => {
+ setImages(
+ (
+ await FileSystem.readDirectoryAsync(
+ FileSystem.documentDirectory + "photos"
+ )
+ ).map((f) => {
+ return {
+ uri: FileSystem.documentDirectory + "photos/" + f,
+ dimensions: { width: 2142, height: 4224 },
+ };
+ })
);
- }
- };
+ })();
+ }, []);
- _maybeRenderImage = () => {
- let { image } = this.state;
-
- if (!image) {
- return;
- }
-
- return (
-
-
-
-
-
-
- {image}
-
-
- );
- };
-
- _share = () => {
- Share.share({
- message: this.state.image,
- title: "Check out this photo",
- url: this.state.image,
- });
- };
-
- _copyToClipboard = () => {
- Clipboard.setString(this.state.image);
- alert("Copied image URL to clipboard");
- };
-
- _takePhoto = async () => {
- const { status: cameraPerm } = await Permissions.askAsync(
- Permissions.CAMERA
- );
-
- const { status: cameraRollPerm } = await Permissions.askAsync(
- Permissions.CAMERA_ROLL
- );
-
- // only if user allows permission to camera AND camera roll
- if (cameraPerm === "granted" && cameraRollPerm === "granted") {
- let pickerResult = await ImagePicker.launchCameraAsync({
- allowsMultipleSelection: true,
- quality: 0.8,
- //allowsEditing: true,
- aspect: [4, 3],
- });
-
- if (!pickerResult.cancelled) {
- this.setState({ image: pickerResult.uri });
- }
-
- this.uploadImageAsync(pickerResult.uri);
- }
- };
-
- _pickImage = async () => {
- const { status: cameraRollPerm } = await Permissions.askAsync(
- Permissions.CAMERA_ROLL
- );
-
- // only if user allows permission to camera roll
- if (cameraRollPerm === "granted") {
- let pickerResult = await ImagePicker.launchImageLibraryAsync({
- allowsEditing: true,
- base64: true,
- aspect: [4, 3],
- });
-
- if (!pickerResult.cancelled) {
- this.setState({ image: pickerResult.uri });
- }
-
- this.uploadImageAsync(pickerResult.uri);
- }
- };
-
- uploadImageAsync(pictureuri) {
- let apiUrl = "http://123.123.123.123/ABC";
-
- var data = new FormData();
- data.append("file", {
- uri: pictureuri,
- name: "file",
- type: "image/jpg",
- });
-
- fetch(apiUrl, {
- headers: {
- Accept: "application/json",
- "Content-Type": "multipart/form-data",
- },
- method: "POST",
- body: data,
- })
- .then((response) => {
- console.log("succ ");
- console.log(response);
- })
- .catch((err) => {
- console.log("err ");
- console.log(err);
- });
- }
+ return (
+
+ This is the media cache screen.
+
+
+ );
}
-
-const styles = StyleSheet.create({
- container: {
- alignItems: "center",
- flex: 1,
- justifyContent: "center",
- },
- exampleText: {
- fontSize: 20,
- marginBottom: 20,
- marginHorizontal: 15,
- textAlign: "center",
- },
- maybeRenderUploading: {
- alignItems: "center",
- backgroundColor: "rgba(0,0,0,0.4)",
- justifyContent: "center",
- },
- maybeRenderContainer: {
- borderRadius: 3,
- elevation: 2,
- marginTop: 30,
- shadowColor: "rgba(0,0,0,1)",
- shadowOpacity: 0.2,
- shadowOffset: {
- height: 4,
- width: 4,
- },
- shadowRadius: 5,
- width: 250,
- },
- maybeRenderImageContainer: {
- borderTopLeftRadius: 3,
- borderTopRightRadius: 3,
- overflow: "hidden",
- },
- maybeRenderImage: {
- height: 250,
- width: 250,
- },
- maybeRenderImageText: {
- paddingHorizontal: 10,
- paddingVertical: 10,
- },
-});
diff --git a/package-lock.json b/package-lock.json
index 0bcb5a6..f820008 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4024,6 +4024,22 @@
"fontfaceobserver": "^2.1.0"
}
},
+ "expo-image-picker": {
+ "version": "9.1.1",
+ "resolved": "https://registry.npmjs.org/expo-image-picker/-/expo-image-picker-9.1.1.tgz",
+ "integrity": "sha512-Etz2OQhRflfx+xFbSdma8QLZsnV/yq0M/yqYlsi3/RLiWAQYM/D/VmRfDDPiG10gm+KX3Xb5iKplNjPrWeTuQg==",
+ "requires": {
+ "expo-permissions": "~9.3.0",
+ "uuid": "7.0.2"
+ },
+ "dependencies": {
+ "uuid": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.2.tgz",
+ "integrity": "sha512-vy9V/+pKG+5ZTYKf+VcphF5Oc6EFiu3W8Nv3P3zIh0EqVI80ZxOzuPfe9EHjkFNvf8+xuTHVeei4Drydlx4zjw=="
+ }
+ }
+ },
"expo-keep-awake": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-8.3.0.tgz",
@@ -4057,6 +4073,11 @@
"resolved": "https://registry.npmjs.org/expo-location/-/expo-location-9.0.1.tgz",
"integrity": "sha512-yl4V2IelxrjG1h3nshkyILwghysNJvvEuR4Of0U7oYAsBrT0cq8NxFuaDemRvqt9Yb19wVFNMoVtYFNpthcqpQ=="
},
+ "expo-media-library": {
+ "version": "9.2.1",
+ "resolved": "https://registry.npmjs.org/expo-media-library/-/expo-media-library-9.2.1.tgz",
+ "integrity": "sha512-A9AAGI1200P0oULoXA7U7wQ91zgPWl9GWo5H9EQvVDHp1ABX8tf2qTOad6Y0KotHYWVMIyfsVXzVYAbjJ9LxPQ=="
+ },
"expo-permissions": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/expo-permissions/-/expo-permissions-9.3.0.tgz",
diff --git a/redux/app/app.actions.js b/redux/app/app.actions.js
index 9e536c4..7c906be 100644
--- a/redux/app/app.actions.js
+++ b/redux/app/app.actions.js
@@ -5,6 +5,11 @@ export const setCameraJobId = (jobId) => ({
payload: jobId,
});
+export const setCameraJob = (job) => ({
+ type: AppActionTypes.SET_CAMERA_JOB,
+ payload: job,
+});
+
export const documentUploadStart = (jobId) => ({
type: AppActionTypes.DOCUMENT_UPLOAD_START,
payload: jobId,
diff --git a/redux/app/app.reducer.js b/redux/app/app.reducer.js
index 8799af8..0ed3ae3 100644
--- a/redux/app/app.reducer.js
+++ b/redux/app/app.reducer.js
@@ -2,6 +2,7 @@ import AppActionTypes from "./app.types";
const INITIAL_STATE = {
cameraJobId: null,
+ cameraJob: null,
documentUploadInProgress: null,
documentUploadError: null,
};
@@ -13,6 +14,11 @@ const appReducer = (state = INITIAL_STATE, action) => {
...state,
cameraJobId: action.payload,
};
+ case AppActionTypes.SET_CAMERA_JOB:
+ return {
+ ...state,
+ cameraJob: action.payload,
+ };
case AppActionTypes.DOCUMENT_UPLOAD_START:
return {
...state,
diff --git a/redux/app/app.selectors.js b/redux/app/app.selectors.js
index 537c353..1ea895a 100644
--- a/redux/app/app.selectors.js
+++ b/redux/app/app.selectors.js
@@ -4,13 +4,17 @@ const selectApp = (state) => state.app;
export const selectCurrentCameraJobId = createSelector(
[selectApp],
- (user) => app.cameraJobId
+ (app) => app.cameraJobId
+);
+export const selectCurrentCameraJob = createSelector(
+ [selectApp],
+ (app) => app.cameraJob
);
export const selectDocumentUploadInProgress = createSelector(
[selectApp],
- (user) => app.documentUploadInProgress
+ (app) => app.documentUploadInProgress
);
export const selectDocumentUploadError = createSelector(
[selectApp],
- (user) => app.documentUploadError
+ (app) => app.documentUploadError
);
diff --git a/redux/app/app.types.js b/redux/app/app.types.js
index b370bf7..2cf7f79 100644
--- a/redux/app/app.types.js
+++ b/redux/app/app.types.js
@@ -1,5 +1,6 @@
const AppActionTypes = {
SET_CAMERA_JOB_ID: "SET_CAMERA_JOB_ID",
+ SET_CAMERA_JOB: "SET_CAMERA_JOB",
DOCUMENT_UPLOAD_START: "DOCUMENT_UPLOAD_START",
DOCUMNET_UPLOAD_SUCCESS: "DOCUMNET_UPLOAD_SUCCESS",
DOCUMENT_UPLOAD_FAILURE: "DOCUMENT_UPLOAD_FAILURE",