Add better sizing for pictures

This commit is contained in:
John Lyon-Smith
2018-04-21 20:27:16 -07:00
parent f9cee95614
commit 3c3ec55660
10 changed files with 172 additions and 115 deletions

View File

@@ -76,6 +76,7 @@
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/.DS_Store" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />

View File

@@ -19,6 +19,7 @@ import {
BoundInput,
BoundButton,
BoundOptionStrip,
BoundHeader,
} from "../ui"
import { MessageModal } from "../Modal"
import autobind from "autobind-decorator"

View File

@@ -20,54 +20,40 @@ console.ignoredYellowBox = [
"<ViroSurface>",
]
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()
}

View File

@@ -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 <Route render={() => <Redirect to={"/home"} />} />
return <Route render={() => <Redirect to={"/workitem"} />} />
}

View File

@@ -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 (
<View
@@ -164,7 +190,8 @@ export class Home extends React.Component {
leftButton={{ icon: "logout", onPress: this.handleLogoutPress }}
rightButton={{ icon: "glasses", onPress: this.handleGlassesPress }}
disabled={
!(positionInfo && positionInfo.coords.accuracy <= minGPSAccuracy)
!(positionInfo && positionInfo.coords.accuracy <= minGPSAccuracy) ||
disableARViewer
}
/>
<MapView
@@ -347,6 +374,14 @@ export class Home extends React.Component {
/>
</TouchableOpacity>
</View>
<MessageModal
open={!!messageModal}
icon={messageModal ? messageModal.icon : ""}
message={messageModal ? messageModal.message : ""}
detail={messageModal ? messageModal.detail : ""}
onDismiss={messageModal && this.handleMessageDismiss}
/>
{Platform.OS === "ios" && <KeyboardSpacer />}
</View>
)
}

View File

@@ -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 {
/>
</View>
<View style={styles.panel}>
<Text style={styles.label}>Pictures:</Text>
<View
style={{ flexDirection: "row", justifyContent: "space-between" }}>
<PhotoButton />
<PhotoButton />
<PhotoButton />
</View>
<PhotoPanel />
</View>
{isIphoneX ? <View style={{ height: 30, width: "100%" }} /> : null}
</ScrollView>

View File

@@ -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

View File

@@ -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 (
<TouchableOpacity>
<View style={{
flexDirection: 'row',
width: 100,
height: 60,
borderWidth: 2,
borderColor: 'gray',
borderRadius: 4,
justifyContent: 'center',
}}>
<Icon name='add' size={24} style={{ alignSelf: 'center' }} />
</View>
</TouchableOpacity>
)
}
}

View File

@@ -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 (
<View
style={{
flexDirection: "column",
justifyContent: "space-between",
}}>
<Text
style={{
fontSize: 14,
marginBottom: 4,
}}>
Pictures:
</Text>
{Array.from(new Array(numRows), (x, i) => (
<View
key={"r" + i.toString()}
style={{
flexDirection: "row",
justifyContent: "space-between",
width: "100%",
height: photoHeight + rowPadding,
paddingTop: rowPadding / 2,
paddingBottom: rowPadding / 2,
}}>
{Array.from(new Array(numCols), (y, j) => (
<TouchableOpacity
key={"r" + i.toString() + "c" + j.toString()}
style={{
width: photoWidth,
height: photoHeight,
borderWidth: 2,
borderColor: "gray",
borderRadius: 4,
justifyContent: "center",
}}>
<Icon name="add" size={24} style={{ alignSelf: "center" }} />
</TouchableOpacity>
))}
</View>
))}
</View>
)
}
}

View File

@@ -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"