Added job select on Camera

This commit is contained in:
Patrick Fic
2021-02-08 19:19:23 -08:00
parent 280b8e38b5
commit 3a0c8b9a5a
13 changed files with 12506 additions and 8055 deletions

45
.estlintrc.json Normal file
View File

@@ -0,0 +1,45 @@
{
"extends": [
"airbnb",
"airbnb/hooks",
"plugin:@typescript-eslint/recommended",
"prettier",
"prettier/react",
"prettier/@typescript-eslint",
"plugin:prettier/recommended"
],
"plugins": ["@typescript-eslint", "react", "prettier"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 2018,
"sourceType": "module",
"project": "./tsconfig.json"
},
"rules": {
"import/no-unresolved": 0,
"react/jsx-filename-extension": [
1,
{
"extensions": [".ts", ".tsx"]
}
],
"prettier/prettier": [
"error",
{
"singleQuote": true,
"trailingComma": "all",
"arrowParens": "avoid",
"endOfLine": "auto"
}
],
"no-use-before-define": "off",
"@typescript-eslint/no-use-before-define": ["error"],
"import/extensions": ["error", "never"],
"react/prop-types": 0,
"no-shadow": "off",
"@typescript-eslint/no-shadow": ["error"]
}
}

7
App.js
View File

@@ -5,6 +5,7 @@ import * as FileSystem from "expo-file-system";
import * as Font from "expo-font"; import * as Font from "expo-font";
import React from "react"; import React from "react";
import { StatusBar as rnStatusBar, StyleSheet } from "react-native"; import { StatusBar as rnStatusBar, StyleSheet } from "react-native";
import { SafeAreaProvider } from "react-native-safe-area-context";
import { Provider } from "react-redux"; import { Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react"; import { PersistGate } from "redux-persist/integration/react";
import * as Sentry from "sentry-expo"; import * as Sentry from "sentry-expo";
@@ -20,7 +21,7 @@ Sentry.init({
dsn: dsn:
"https://8d6c3de1940a4e4f8b81cf4d2150bdea@o492140.ingest.sentry.io/5558869", "https://8d6c3de1940a4e4f8b81cf4d2150bdea@o492140.ingest.sentry.io/5558869",
enableInExpoDevelopment: true, enableInExpoDevelopment: true,
//debug: true, // Sentry will try to print out useful debugging information if something goes wrong with sending an event. Set this to `false` in production. debug: true, // Sentry will try to print out useful debugging information if something goes wrong with sending an event. Set this to `false` in production.
}); });
Sentry.Native.nativeCrash(); Sentry.Native.nativeCrash();
@@ -55,7 +56,9 @@ export default class App extends React.Component {
<Provider store={store}> <Provider store={store}>
<PersistGate persistor={persistor}> <PersistGate persistor={persistor}>
<ApolloProvider client={client}> <ApolloProvider client={client}>
<ScreenMainComponent /> <SafeAreaProvider>
<ScreenMainComponent />
</SafeAreaProvider>
</ApolloProvider> </ApolloProvider>
</PersistGate> </PersistGate>
</Provider> </Provider>

View File

@@ -80,6 +80,7 @@ export default function CameraControls({
onPressOut={onCaptureOut} onPressOut={onCaptureOut}
onLongPress={onLongCapture} onLongPress={onLongCapture}
onPress={onShortCapture} onPress={onShortCapture}
disabled={capturing}
> >
<View style={[styles.captureBtn, capturing && styles.captureBtnActive]}> <View style={[styles.captureBtn, capturing && styles.captureBtnActive]}>
{capturing && <View style={styles.captureBtnInternal} />} {capturing && <View style={styles.captureBtnInternal} />}

View File

@@ -0,0 +1,86 @@
import { useQuery } from "@apollo/client";
import { Picker } from "native-base";
import React from "react";
import { View } from "react-native";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { QUERY_ALL_ACTIVE_JOBS } from "../../graphql/jobs.queries";
import { setCameraJob, setCameraJobId } from "../../redux/app/app.actions";
import { selectCurrentCameraJobId } from "../../redux/app/app.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors";
import ErrorDisplay from "../error-display/error-display.component";
import LoadingDisplay from "../loading-display/loading-display.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
cameraJobId: selectCurrentCameraJobId,
});
const mapDispatchToProps = (dispatch) => ({
setCameraJobId: (id) => dispatch(setCameraJobId(id)),
setCameraJob: (job) => dispatch(setCameraJob(job)),
});
export function CameraSelectJob({
bodyshop,
cameraJobId,
setCameraJobId,
setCameraJob,
}) {
const { loading, error, data, refetch } = useQuery(QUERY_ALL_ACTIVE_JOBS, {
variables: {
statuses: bodyshop.md_ro_statuses.active_statuses || ["Open", "Open*"],
},
skip: !bodyshop,
});
const onRefresh = async () => {
return refetch();
};
if (loading) return <LoadingDisplay />;
if (error) return <ErrorDisplay errorMessage={error.message} />;
return (
<View
style={{
// display: "flex",
// width: "100%",
// alignSelf: "flex-start",
// alignItems: "center",
backgroundColor: "rgba(35,35,35, 0.4)",
paddingTop: 30,
//textShadow: "tomato 0px 0px 10px",
fontColor: "black",
fontSize: 20,
fontWeight: "bold",
}}
>
<Picker
note
selectedValue={cameraJobId}
onValueChange={(value, idx) => {
console.log(value, idx);
setCameraJobId(value);
setCameraJob(data.jobs[idx]);
}}
>
{data.jobs.map((j) => {
return (
<Picker.Item
label={`${j.ro_number ? `${j.ro_number} - ` : ``}${
j.ownr_fn || ""
} ${j.ownr_ln || ""} ${j.ownr_co_nm || ""} - ${
j.v_model_yr || ""
} ${j.v_make_desc || ""} ${j.v_model_desc || ""}`}
value={j.id}
key={j.id}
/>
);
})}
</Picker>
</View>
);
}
export default connect(mapStateToProps, mapDispatchToProps)(CameraSelectJob);

View File

@@ -1,7 +1,6 @@
import React from "react"; import React from "react";
import { View, Text } from "react-native"; import { View } from "react-native";
import { BarIndicator } from "react-native-indicators"; import { BarIndicator } from "react-native-indicators";
import { Container, Content } from "native-base";
export default function LoadingDisplay({ count = 5 }) { export default function LoadingDisplay({ count = 5 }) {
return ( return (

View File

@@ -1,10 +0,0 @@
import React from "react";
import { Text, View } from "react-native";
export default function ScreenCameraJobSearch() {
return (
<View>
<Text>This is the media cache screen.</Text>
</View>
);
}

View File

@@ -12,6 +12,7 @@ import {
} from "../../redux/app/app.selectors"; } from "../../redux/app/app.selectors";
import { addPhoto } from "../../redux/photos/photos.actions"; import { addPhoto } from "../../redux/photos/photos.actions";
import CameraControls from "../camera-controls/camera-controls.component"; import CameraControls from "../camera-controls/camera-controls.component";
import CameraSelectJob from "../camera-select-job/camera-select-job.component";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
cameraJobId: selectCurrentCameraJobId, cameraJobId: selectCurrentCameraJobId,
@@ -62,16 +63,14 @@ export function ScreenCamera({ cameraJobId, cameraJob, addPhoto }) {
const handleShortCapture = async () => { const handleShortCapture = async () => {
if (cameraRef.current) { if (cameraRef.current) {
const options = { const options = {
//quality: 0.5, quality: 0.8,
//base64: true, //base64: true,
//skipProcessing: true, skipProcessing: true,
}; };
console.log("Taking a picture!");
let photo = await cameraRef.current.takePictureAsync(options); let photo = await cameraRef.current.takePictureAsync(options);
console.log("ScreenCamera -> photo", photo);
const filename = photo.uri.substring(photo.uri.lastIndexOf("/") + 1); const filename = photo.uri.substring(photo.uri.lastIndexOf("/") + 1);
const newUri = FileSystem.documentDirectory + "photos/" + filename; const newUri = FileSystem.documentDirectory + "photos/" + filename;
await FileSystem.moveAsync({ await FileSystem.moveAsync({
@@ -79,7 +78,7 @@ export function ScreenCamera({ cameraJobId, cameraJob, addPhoto }) {
to: newUri, to: newUri,
}); });
setState({ ...state, capturing: false }); setState({ ...state, capturing: false });
console.log("Adding photo to cache...");
addPhoto({ addPhoto({
...photo, ...photo,
id: filename, id: filename,
@@ -119,51 +118,27 @@ export function ScreenCamera({ cameraJobId, cameraJob, addPhoto }) {
} }
if (hasPermission === false) { if (hasPermission === false) {
return <Text>No access to camera</Text>; return <Text>No access to camera. Please ensure that you allow it.</Text>;
} }
const { flashMode, cameraType, capturing } = state; const { flashMode, cameraType, capturing } = state;
return ( return (
<View style={{ display: "flex", flex: 1 }}> <SafeAreaView
style={{ display: "flex", flex: 1, backgroundColor: "tomato" }}
>
<Camera <Camera
style={{ flex: 1, display: "flex" }} style={{ flex: 1, display: "flex" }}
type={state.cameraType} type={state.cameraType}
ref={cameraRef} ref={cameraRef}
ratio={"16:9"}
> >
<SafeAreaView <View
style={{ style={{
flex: 1, flex: 1,
}} }}
> >
<TouchableOpacity <CameraSelectJob />
onPress={() => navigation.push("CameraJobSearch")}
style={{
display: "flex",
width: "100%",
alignSelf: "flex-start",
alignItems: "center",
backgroundColor: "rgba(112, 128, 144, 0.3)",
fontSize: 20,
fontWeight: "bold",
}}
>
<Text
style={{
fontSize: 20,
fontWeight: "bold",
}}
>
{cameraJob && cameraJob.ro_number}
</Text>
<Text>
{cameraJob &&
`${cameraJob && cameraJob.ownr_fn} ${
cameraJob && cameraJob.ownr_ln
}`}
</Text>
<Text>{cameraJobId}</Text>
</TouchableOpacity>
<TouchableOpacity <TouchableOpacity
onPress={() => { onPress={() => {
navigation.push("MediaCache"); navigation.push("MediaCache");
@@ -192,9 +167,9 @@ export function ScreenCamera({ cameraJobId, cameraJob, addPhoto }) {
onLongCapture={handleLongCapture} onLongCapture={handleLongCapture}
onShortCapture={handleShortCapture} onShortCapture={handleShortCapture}
/> />
</SafeAreaView> </View>
</Camera> </Camera>
</View> </SafeAreaView>
); );
} }
export default connect(mapStateToProps, mapDispatchToProps)(ScreenCamera); export default connect(mapStateToProps, mapDispatchToProps)(ScreenCamera);

View File

@@ -3,10 +3,12 @@ import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import { createDrawerNavigator } from "@react-navigation/drawer"; import { createDrawerNavigator } from "@react-navigation/drawer";
import { NavigationContainer } from "@react-navigation/native"; import { NavigationContainer } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack"; import { createStackNavigator } from "@react-navigation/stack";
import Dinero from "dinero.js";
import i18n from "i18next"; import i18n from "i18next";
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { StatusBar as rnStatusBar, StyleSheet } from "react-native"; import { StatusBar as rnStatusBar, StyleSheet } from "react-native";
import { SafeAreaProvider } from "react-native-safe-area-context";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
import { import {
@@ -18,8 +20,7 @@ import {
selectBodyshop, selectBodyshop,
selectCurrentUser, selectCurrentUser,
} from "../../redux/user/user.selectors"; } from "../../redux/user/user.selectors";
import ScreenCameraJobSearch from "../screen-camera-job-search/screen-camera-job-search.component"; import ScreenCamera from "../screen-camera/screen-camera";
import ScreenCamera from "../screen-camera/screen-camera.component";
import ScreenJobDetail from "../screen-job-detail/screen-job-detail.component"; import ScreenJobDetail from "../screen-job-detail/screen-job-detail.component";
import ScreenJobList from "../screen-job-list/screen-job-list.component"; import ScreenJobList from "../screen-job-list/screen-job-list.component";
import ScreenMediaCache from "../screen-media-cache/screen-media-cache.component"; import ScreenMediaCache from "../screen-media-cache/screen-media-cache.component";
@@ -28,7 +29,6 @@ import ScreenMessagingList from "../screen-messaging-list/screen-messaging-list.
import ScreenSettingsComponent from "../screen-settings/screen-settings.component"; import ScreenSettingsComponent from "../screen-settings/screen-settings.component";
import ScreenSignIn from "../screen-sign-in/screen-sign-in.component"; import ScreenSignIn from "../screen-sign-in/screen-sign-in.component";
import ScreenSplash from "../screen-splash/screen-splash.component"; import ScreenSplash from "../screen-splash/screen-splash.component";
import Dinero from "dinero.js";
const JobStack = createStackNavigator(); const JobStack = createStackNavigator();
const CameraStack = createStackNavigator(); const CameraStack = createStackNavigator();
@@ -91,19 +91,21 @@ const CameraStackNavigator = ({ navigation }) => (
options={{ headerShown: false }} options={{ headerShown: false }}
component={ScreenCamera} component={ScreenCamera}
/> />
<CameraStack.Screen {/* <CameraStack.Screen
name="CameraJobSearch" name="CameraJobSearch"
component={ScreenCameraJobSearch} component={ScreenCameraJobSearch}
/> /> */}
<CameraStack.Screen name="MediaCache" component={ScreenMediaCache} /> <CameraStack.Screen name="MediaCache" component={ScreenMediaCache} />
</CameraStack.Navigator> </CameraStack.Navigator>
); );
const MediaCacheStackNavigator = ({ navigation }) => ( const MediaCacheStackNavigator = ({ navigation }) => (
<CameraStack.Navigator initialRouteName="TabMediaCache"> <CameraStack.Navigator initialRouteName="TabMediaCache">
<CameraStack.Screen name="MediaCache" component={ScreenMediaCache} /> <CameraStack.Screen name="MediaCache" component={ScreenMediaCache} />
</CameraStack.Navigator> </CameraStack.Navigator>
); );
const MessagingStackNavigator = ({ navigation }) => ( const MessagingStackNavigator = ({ navigation }) => (
<MessagingStack.Navigator> <MessagingStack.Navigator>
<MessagingStack.Screen <MessagingStack.Screen

View File

@@ -4,6 +4,7 @@ import Logo from "../../assets/logo192.png";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { H1, Container, Content } from "native-base"; import { H1, Container, Content } from "native-base";
import styles from "../styles"; import styles from "../styles";
import { BarIndicator } from "react-native-indicators";
export default function ScreenSplash() { export default function ScreenSplash() {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -17,6 +18,7 @@ export default function ScreenSplash() {
> >
<Image style={localStyles.logo} source={Logo} /> <Image style={localStyles.logo} source={Logo} />
<H1>{t("app.title")}</H1> <H1>{t("app.title")}</H1>
<BarIndicator count={5} color="dodgerblue" />
</Content> </Content>
</Container> </Container>
); );

12336
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -45,7 +45,7 @@
"react-native-image-zoom-viewer": "^3.0.1", "react-native-image-zoom-viewer": "^3.0.1",
"react-native-indicators": "^0.17.0", "react-native-indicators": "^0.17.0",
"react-native-reanimated": "~1.13.0", "react-native-reanimated": "~1.13.0",
"react-native-safe-area-context": "3.1.9", "react-native-safe-area-context": "^3.1.9",
"react-native-screens": "~2.15.0", "react-native-screens": "~2.15.0",
"react-native-web": "~0.13.12", "react-native-web": "~0.13.12",
"react-redux": "^7.2.2", "react-redux": "^7.2.2",
@@ -58,8 +58,14 @@
"subscriptions-transport-ws": "^0.9.18" "subscriptions-transport-ws": "^0.9.18"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "~7.9.0", "@babel/core": "^7.12.13",
"babel-preset-expo": "8.3.0" "babel-preset-expo": "8.3.0",
"eslint": "^7.19.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.22.0",
"eslint-plugin-react-hooks": "^1.7.0"
}, },
"private": true "private": true
} }

View File

@@ -20,8 +20,6 @@ export const handleUpload = async (ev, context) => {
/\.[^/.]+$/, /\.[^/.]+$/,
"" ""
)}`; )}`;
console.log("Got here");
return uploadToCloudinary( return uploadToCloudinary(
key, key,
newFile.type, newFile.type,

7992
yarn.lock

File diff suppressed because it is too large Load Diff