diff --git a/components/camera-controls/camera-controls.component.jsx b/components/camera-controls/camera-controls.component.jsx
new file mode 100644
index 0000000..95db222
--- /dev/null
+++ b/components/camera-controls/camera-controls.component.jsx
@@ -0,0 +1,102 @@
+// src/toolbar.component.js file
+import { Ionicons } from "@expo/vector-icons";
+import { Camera } from "expo-camera";
+import React from "react";
+import {
+ StyleSheet,
+ TouchableOpacity,
+ TouchableWithoutFeedback,
+ View,
+} from "react-native";
+
+const styles = StyleSheet.create({
+ alignCenter: {
+ flex: 1,
+ alignItems: "center",
+ justifyContent: "center",
+ },
+ bottomToolbar: {
+ marginTop: "auto",
+ height: 100,
+ display: "flex",
+ justifyContent: "space-evenly",
+ alignItems: "center",
+ flexDirection: "row",
+ },
+ captureBtn: {
+ width: 60,
+ height: 60,
+ borderWidth: 2,
+ borderRadius: 60,
+ borderColor: "#FFFFFF",
+ },
+ captureBtnActive: {
+ width: 80,
+ height: 80,
+ },
+ captureBtnInternal: {
+ width: 76,
+ height: 76,
+ borderWidth: 2,
+ borderRadius: 76,
+ backgroundColor: "red",
+ borderColor: "transparent",
+ },
+});
+
+const { FlashMode: CameraFlashModes, Type: CameraTypes } = Camera.Constants;
+
+export default function CameraControls({
+ capturing = false,
+ cameraType = CameraTypes.back,
+ flashMode = CameraFlashModes.off,
+ setFlashMode,
+ setCameraType,
+ onCaptureIn,
+ onCaptureOut,
+ onLongCapture,
+ onShortCapture,
+}) {
+ return (
+
+
+ setFlashMode(
+ flashMode === CameraFlashModes.on
+ ? CameraFlashModes.off
+ : CameraFlashModes.on
+ )
+ }
+ >
+
+
+
+
+
+ {capturing && }
+
+
+
+
+ setCameraType(
+ cameraType === CameraTypes.back
+ ? CameraTypes.front
+ : CameraTypes.back
+ )
+ }
+ >
+
+
+
+ );
+}
diff --git a/components/job-list-item/job-list-item.component.jsx b/components/job-list-item/job-list-item.component.jsx
index 0e0c780..f4ee995 100644
--- a/components/job-list-item/job-list-item.component.jsx
+++ b/components/job-list-item/job-list-item.component.jsx
@@ -9,6 +9,7 @@ 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 Dinero from "dinero.js";
import styles from "../styles";
const mapStateToProps = createStructuredSelector({
@@ -71,7 +72,11 @@ export function JobListItem({ setCameraJob, setCameraJobId, item }) {
{item.ins_co_nm || ""}
- {item.clm_total || ""}
+
+ {Dinero({
+ amount: Math.round(item.clm_total * 100),
+ }).toFormat() || ""}
+
diff --git a/components/screen-camera/screen-camera.component.jsx b/components/screen-camera/screen-camera.component.jsx
index 7ae1a04..40d3634 100644
--- a/components/screen-camera/screen-camera.component.jsx
+++ b/components/screen-camera/screen-camera.component.jsx
@@ -1,12 +1,7 @@
-import {
- FontAwesome,
- Ionicons,
- MaterialCommunityIcons,
-} from "@expo/vector-icons";
+import { Ionicons } from "@expo/vector-icons";
import { useNavigation } from "@react-navigation/native";
import { Camera } from "expo-camera";
import * as FileSystem from "expo-file-system";
-import * as Permissions from "expo-permissions";
import React, { useEffect, useRef, useState } from "react";
import { SafeAreaView, Text, TouchableOpacity, View } from "react-native";
import { connect } from "react-redux";
@@ -16,6 +11,7 @@ import {
selectCurrentCameraJobId,
} from "../../redux/app/app.selectors";
import { addPhoto } from "../../redux/photos/photos.actions";
+import CameraControls from "../camera-controls/camera-controls.component";
const mapStateToProps = createStructuredSelector({
cameraJobId: selectCurrentCameraJobId,
@@ -28,29 +24,29 @@ const mapDispatchToProps = (dispatch) => ({
export function ScreenCamera({ cameraJobId, cameraJob, addPhoto }) {
const navigation = useNavigation();
const [hasPermission, setHasPermission] = useState(null);
- const [rollPermision, setRollPermission] = useState(null);
- const [type, setType] = useState(Camera.Constants.Type.back);
+ const [state, setState] = useState({
+ flashMode: Camera.Constants.FlashMode.off,
+ capturing: null,
+ cameraType: Camera.Constants.Type.back,
+ });
const cameraRef = useRef(null);
useEffect(() => {
(async () => {
const { status } = await Camera.requestPermissionsAsync();
setHasPermission(status === "granted");
- // camera roll
- const { cam_roll } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
- setRollPermission(cam_roll === "granted");
})();
}, []);
- const handleCameraType = () => {
- setType(
- type === Camera.Constants.Type.back
- ? Camera.Constants.Type.front
- : Camera.Constants.Type.back
- );
+ const setFlashMode = (flashMode) => setState({ ...state, flashMode });
+ const setCameraType = (cameraType) => setState({ ...state, cameraType });
+ const handleCaptureIn = () => setState({ ...state, capturing: true });
+
+ const handleCaptureOut = () => {
+ if (state.capturing) cameraRef.current.stopRecording();
};
- const handleTakePicture = async () => {
+ const handleShortCapture = async () => {
console.log("Taking the picture!");
if (cameraRef.current) {
const options = {
@@ -60,6 +56,7 @@ export function ScreenCamera({ cameraJobId, cameraJob, addPhoto }) {
};
let photo = await cameraRef.current.takePictureAsync(options);
+ setState({ ...state, capturing: false });
console.log("ScreenCamera -> photo", photo);
const filename = photo.uri.substring(photo.uri.lastIndexOf("/") + 1);
@@ -70,24 +67,60 @@ export function ScreenCamera({ cameraJobId, cameraJob, addPhoto }) {
to: newUri,
});
- addPhoto({ ...photo, id: filename, uri: newUri, jobId: cameraJobId });
+ addPhoto({
+ ...photo,
+ id: filename,
+ uri: newUri,
+ jobId: cameraJobId,
+ video: false,
+ });
+ }
+ };
+
+ const handleLongCapture = async () => {
+ console.log("Taking a video!");
+ if (cameraRef.current) {
+ let video = await cameraRef.current.recordAsync();
+ setState({ ...state, capturing: false });
+
+ const filename = video.uri.substring(video.uri.lastIndexOf("/") + 1);
+ const newUri = FileSystem.documentDirectory + "photos/" + filename;
+
+ await FileSystem.copyAsync({
+ from: video.uri,
+ to: newUri,
+ });
+
+ addPhoto({
+ ...video,
+ id: filename,
+ uri: newUri,
+ jobId: cameraJobId,
+ video: true,
+ });
}
};
if (hasPermission === null) {
return ;
}
+
if (hasPermission === false) {
return No access to camera;
}
+
+ const { hasCameraPermission, flashMode, cameraType, capturing } = state;
+
return (
-
+
{cameraJobId}
- {
+ navigation.push("MediaCache");
+ }}
style={{
- flex: 1,
- flexDirection: "row",
- justifyContent: "space-between",
- margin: 20,
+ alignSelf: "flex-start",
+ alignItems: "center",
+ fontSize: 20,
+ fontWeight: "bold",
}}
>
-
-
-
-
-
-
- {
- navigation.push("MediaCache");
- }}
- style={{
- alignSelf: "flex-end",
- alignItems: "center",
- backgroundColor: "transparent",
- }}
- >
-
-
-
+
+
+
+
diff --git a/components/screen-media-cache/screen-media-cache.component.jsx b/components/screen-media-cache/screen-media-cache.component.jsx
index 5d0056e..3d2f827 100644
--- a/components/screen-media-cache/screen-media-cache.component.jsx
+++ b/components/screen-media-cache/screen-media-cache.component.jsx
@@ -1,11 +1,11 @@
import { Button, Text as NBText, Thumbnail, View } from "native-base";
import React from "react";
-import { SafeAreaView, Text } from "react-native";
-
+import { FlatList, SafeAreaView, Text } from "react-native";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { removeAllPhotos } from "../../redux/photos/photos.actions";
import { selectPhotos } from "../../redux/photos/photos.selectors";
+
const mapStateToProps = createStructuredSelector({
photos: selectPhotos,
});
@@ -22,22 +22,19 @@ export function ScreenMediaCache({ photos, removeAllPhotos }) {
Delete all
{photos.length}
-
- The View
- {photos.map((i, idx) => (
+
+ item.id}
+ renderItem={(object) => (
- {i.uri}
-
+ {object.item.uri}
+
- ))}
-
+ )}
+ //ItemSeparatorComponent={FlatListItemSeparator}
+ />
);
}
diff --git a/package.json b/package.json
index 87d56eb..fa388fd 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
"react-dom": "16.13.1",
"react-i18next": "^11.7.3",
"react-native": "https://github.com/expo/react-native/archive/sdk-39.0.3.tar.gz",
+ "react-native-easy-grid": "^0.2.2",
"react-native-gesture-handler": "~1.7.0",
"react-native-indicators": "^0.17.0",
"react-native-reanimated": "~1.13.0",
diff --git a/redux/photos/photos.sagas.js b/redux/photos/photos.sagas.js
index eb17913..e6e6a5d 100644
--- a/redux/photos/photos.sagas.js
+++ b/redux/photos/photos.sagas.js
@@ -1,5 +1,6 @@
import { all, call, takeLatest } from "redux-saga/effects";
import PhotosActionTypes from "./photos.types";
+import * as FileSystem from "expo-file-system";
export function* onRemoveAllPhotos() {
yield takeLatest(PhotosActionTypes.REMOVE_ALL_PHOTOS, removeAllPhotosAction);