From 3c3ec5566029376947da006b2407543c36f883c8 Mon Sep 17 00:00:00 2001 From: John Lyon-Smith Date: Sat, 21 Apr 2018 20:27:16 -0700 Subject: [PATCH] Add better sizing for pictures --- mobile/android/app/app.iml | 1 + mobile/src/Activity/Activity.js | 1 + mobile/src/App.js | 54 ++++++++------------ mobile/src/Auth/DefaultRoute.js | 2 +- mobile/src/Home/Home.js | 89 +++++++++++++++++++++++---------- mobile/src/WorkItem/WorkItem.js | 13 +---- mobile/src/config.js | 4 +- mobile/src/ui/PhotoButton.js | 31 ------------ mobile/src/ui/PhotoPanel.js | 74 +++++++++++++++++++++++++++ mobile/src/ui/index.js | 18 +++---- 10 files changed, 172 insertions(+), 115 deletions(-) create mode 100644 mobile/src/ui/PhotoPanel.js diff --git a/mobile/android/app/app.iml b/mobile/android/app/app.iml index 85b3055..d5b763e 100644 --- a/mobile/android/app/app.iml +++ b/mobile/android/app/app.iml @@ -76,6 +76,7 @@ + diff --git a/mobile/src/Activity/Activity.js b/mobile/src/Activity/Activity.js index ffbfd4f..515808d 100644 --- a/mobile/src/Activity/Activity.js +++ b/mobile/src/Activity/Activity.js @@ -19,6 +19,7 @@ import { BoundInput, BoundButton, BoundOptionStrip, + BoundHeader, } from "../ui" import { MessageModal } from "../Modal" import autobind from "autobind-decorator" diff --git a/mobile/src/App.js b/mobile/src/App.js index 00cfbe3..25f634d 100644 --- a/mobile/src/App.js +++ b/mobile/src/App.js @@ -20,54 +20,40 @@ console.ignoredYellowBox = [ "", ] -export const ensurePermission = ( - permission, - neverAskKeyName, +export const ensurePermissions = ( + permissions, rationale, onSuccess, onError ) => { if (Platform.OS === "ios") { if (onSuccess) { - onSuccess() + onSuccess( + permissions.reduce( + (dict, permission) => + (dict[permission] = PermissionsAndroid.RESULTS.GRANTED), + {} + ) + ) } return } - PermissionsAndroid.check(permission) - .then((flag) => { - if (flag) { - if (onSuccess) { - onSuccess() - } - return - } - return AsyncStorage.getItem(neverAskKeyName) - }) - .then((value) => { - if (value === "YES") { - return - } else { - return PermissionsAndroid.request(permission, rationale) - } - }) - .then((result) => { - if (result === PermissionsAndroid.RESULTS.GRANTED) { - if (onSuccess) { - onSuccess() - } - return + PermissionsAndroid.requestMultiple(permissions, rationale) + .then((results) => { + if ( + !Object.values(results).every( + (grant) => grant === PermissionsAndroid.RESULTS.GRANTED + ) + ) { + return Promise.reject() } - if (result === PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN) { - AsyncStorage.setItem(neverAskKeyName, "YES") - } - - if (onError) { - onError() + if (onSuccess) { + onSuccess(results) } }) - .catch((err) => { + .catch((error) => { if (onError) { onError() } diff --git a/mobile/src/Auth/DefaultRoute.js b/mobile/src/Auth/DefaultRoute.js index 43027b5..9e21135 100644 --- a/mobile/src/Auth/DefaultRoute.js +++ b/mobile/src/Auth/DefaultRoute.js @@ -3,5 +3,5 @@ import { Route, Redirect } from "react-router-native" export const DefaultRoute = () => { // NOTE: When working on the app, change this to the page you are working on - return } /> + return } /> } diff --git a/mobile/src/Home/Home.js b/mobile/src/Home/Home.js index 33ef908..1b44c6a 100644 --- a/mobile/src/Home/Home.js +++ b/mobile/src/Home/Home.js @@ -9,17 +9,19 @@ import { TouchableOpacity, TouchableHighlight, PermissionsAndroid, - AsyncStorage, + Platform, } from "react-native" import MapView, { Marker } from "react-native-maps" import { Icon, Header } from "../ui" +import { MessageModal } from "../Modal" import { api } from "../API" import autobind from "autobind-decorator" import { ifIphoneX } from "react-native-iphone-x-helper" import { workItemTypeText, pad, regionContainingPoints } from "../util" -import { ensurePermission } from "../App" +import { ensurePermissions } from "../App" import { versionInfo } from "../version" import { minGPSAccuracy } from "../config" +import KeyboardSpacer from "react-native-keyboard-spacer" import pinImage from "./images/pin.png" const neverAskForLocationPermissionKeyName = "NeverAskForLocationPermission" @@ -38,38 +40,50 @@ export class Home extends React.Component { longitudeDelta: 0.0922, }, positionInfo: null, - allowCameraAccess: false, + disableARViewer: true, } - ensurePermission( - PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION, - neverAskForLocationPermissionKeyName, + ensurePermissions( + [ + PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION, + PermissionsAndroid.PERMISSIONS.CAMERA, + ], { title: versionInfo.title, message: - "This app needs access to your location so that " + - "you can find and access the geo located items.", + "This app needs these permissions so that you can " + + "find, access and photograph geo located items.", }, - () => { - this.watchId = navigator.geolocation.watchPosition( - this.handlePositionChange, - null, - { distanceFilter: 10 } - ) - } - ) + (results) => { + if ( + results[PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION] === + PermissionsAndroid.RESULTS.GRANTED + ) { + this.watchId = navigator.geolocation.watchPosition( + this.handlePositionChange, + null, + { distanceFilter: 10 } + ) + } - ensurePermission( - PermissionsAndroid.PERMISSIONS.CAMERA, - neverAskForCameraKeyName, - { - title: versionInfo.title, - message: - "This app needs access to your camera so that " + - "you can view AR items.", + if ( + results[PermissionsAndroid.PERMISSIONS.CAMERA] === + PermissionsAndroid.RESULTS.GRANTED + ) { + this.setState({ disableARViewer: false }) + } }, () => { - this.setState({ allowCameraAccess: true }) + this.setState({ + messageModal: { + icon: "hand", + message: + "You have denied the app access to phone features it needs to function. " + + "Some parts of the app are disabled. To enable these features in future " + + "please go to Settings.", + detail: "", + }, + }) } ) @@ -96,6 +110,11 @@ export class Home extends React.Component { } } + @autobind + handleMessageDismiss() { + this.setState({ messageModal: null }) + } + @autobind handlePositionChange(positionInfo) { this.setState({ positionInfo }) @@ -150,7 +169,14 @@ export class Home extends React.Component { } render() { - const { sections, showWorkItems, region, positionInfo } = this.state + const { + sections, + showWorkItems, + region, + positionInfo, + messageModal, + disableARViewer, + } = this.state return ( + + {Platform.OS === "ios" && } ) } diff --git a/mobile/src/WorkItem/WorkItem.js b/mobile/src/WorkItem/WorkItem.js index c43f84f..bd1d1db 100644 --- a/mobile/src/WorkItem/WorkItem.js +++ b/mobile/src/WorkItem/WorkItem.js @@ -20,6 +20,7 @@ import { Header, PhotoButton, BoundOptionStrip, + PhotoPanel, } from "../ui" import { MessageModal } from "../Modal" import autobind from "autobind-decorator" @@ -46,10 +47,6 @@ const styles = StyleSheet.create({ shadowOpacity: 0.5, padding: 10, }, - label: { - fontSize: 14, - marginBottom: 4, - }, }) export class WorkItem extends React.Component { @@ -257,13 +254,7 @@ export class WorkItem extends React.Component { /> - Pictures: - - - - - + {isIphoneX ? : null} diff --git a/mobile/src/config.js b/mobile/src/config.js index 6c62150..e86a071 100644 --- a/mobile/src/config.js +++ b/mobile/src/config.js @@ -1,5 +1,5 @@ export const localIPAddr = "192.168.1.175" -//export const defaultUser = "john@lyon-smith.org" -export const defaultUser = "" +export const defaultUser = "john@lyon-smith.org" +// export const defaultUser = "" // export const minGPSAccuracy = 20 export const minGPSAccuracy = 100 diff --git a/mobile/src/ui/PhotoButton.js b/mobile/src/ui/PhotoButton.js index 46f87e4..e69de29 100644 --- a/mobile/src/ui/PhotoButton.js +++ b/mobile/src/ui/PhotoButton.js @@ -1,31 +0,0 @@ -import React from 'react' -import { - StyleSheet, - View, - Image, - TouchableOpacity -} from 'react-native' -import { Icon } from '.' -import autobind from 'autobind-decorator' - -// const styles = StyleSheet.create() - -export class PhotoButton extends React.Component { - render() { - return ( - - - - - - ) - } -} diff --git a/mobile/src/ui/PhotoPanel.js b/mobile/src/ui/PhotoPanel.js new file mode 100644 index 0000000..e06d41f --- /dev/null +++ b/mobile/src/ui/PhotoPanel.js @@ -0,0 +1,74 @@ +import React, { Component } from "react" +import { + StyleSheet, + Text, + View, + Image, + TouchableOpacity, + Dimensions, +} from "react-native" +import { Icon } from "." +import autobind from "autobind-decorator" + +const getScreenPortraitDimensions = () => { + const { width, height } = Dimensions.get("window") + + return { + screenWidth: Math.min(width, height), + screenHeight: Math.max(width, height), + } +} + +export class PhotoPanel extends Component { + render() { + const { screenWidth, screenHeight } = getScreenPortraitDimensions() + const photoWidth = screenHeight / 4 + const photoHeight = screenWidth / 4 + const numRows = 2 + const numCols = 2 + const rowPadding = 10 + + return ( + + + Pictures: + + {Array.from(new Array(numRows), (x, i) => ( + + {Array.from(new Array(numCols), (y, j) => ( + + + + ))} + + ))} + + ) + } +} diff --git a/mobile/src/ui/index.js b/mobile/src/ui/index.js index c65ea16..b2865c5 100644 --- a/mobile/src/ui/index.js +++ b/mobile/src/ui/index.js @@ -1,9 +1,9 @@ -export { Icon } from './Icon' -export { Header } from './Header' -export { PhotoButton } from './PhotoButton' -export { OptionStrip } from './OptionStrip' -export { BoundSwitch } from './BoundSwitch' -export { BoundInput } from './BoundInput' -export { BoundButton } from './BoundButton' -export { BoundOptionStrip } from './BoundOptionStrip' -export { BoundHeader } from './BoundHeader' +export { Icon } from "./Icon" +export { Header } from "./Header" +export { PhotoPanel } from "./PhotoPanel" +export { OptionStrip } from "./OptionStrip" +export { BoundSwitch } from "./BoundSwitch" +export { BoundInput } from "./BoundInput" +export { BoundButton } from "./BoundButton" +export { BoundOptionStrip } from "./BoundOptionStrip" +export { BoundHeader } from "./BoundHeader"