Add better sizing for pictures
This commit is contained in:
@@ -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" />
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
BoundInput,
|
||||
BoundButton,
|
||||
BoundOptionStrip,
|
||||
BoundHeader,
|
||||
} from "../ui"
|
||||
import { MessageModal } from "../Modal"
|
||||
import autobind from "autobind-decorator"
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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"} />} />
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
74
mobile/src/ui/PhotoPanel.js
Normal file
74
mobile/src/ui/PhotoPanel.js
Normal 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>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user