Fix layout issues on Android

This commit is contained in:
John Lyon-Smith
2018-04-08 10:17:15 -07:00
parent dd2adf807f
commit 5634acb967
9 changed files with 119 additions and 85 deletions

21
.idea/workspace.xml generated
View File

@@ -2,20 +2,8 @@
<project version="4"> <project version="4">
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="6f884dce-583e-4e88-a1c3-0ae6c4d6d70b" name="Default" comment=""> <list default="true" id="6f884dce-583e-4e88-a1c3-0ae6c4d6d70b" name="Default" comment="">
<change beforePath="$PROJECT_DIR$/mobile/.babelrc" afterPath="$PROJECT_DIR$/mobile/.babelrc" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" afterPath="$PROJECT_DIR$/.idea/workspace.xml" />
<change beforePath="$PROJECT_DIR$/mobile/android/build.gradle" afterPath="$PROJECT_DIR$/mobile/android/build.gradle" /> <change beforePath="$PROJECT_DIR$/version.json5" afterPath="$PROJECT_DIR$/version.json5" />
<change beforePath="$PROJECT_DIR$/mobile/package-lock.json" afterPath="$PROJECT_DIR$/mobile/package-lock.json" />
<change beforePath="$PROJECT_DIR$/mobile/package.json" afterPath="$PROJECT_DIR$/mobile/package.json" />
<change beforePath="$PROJECT_DIR$/mobile/src/screens/Error.js" afterPath="$PROJECT_DIR$/mobile/src/screens/Error.js" />
<change beforePath="$PROJECT_DIR$/mobile/src/screens/Login.js" afterPath="$PROJECT_DIR$/mobile/src/screens/Login.js" />
<change beforePath="$PROJECT_DIR$/mobile/src/ui/BoundButton.js" afterPath="$PROJECT_DIR$/mobile/src/ui/BoundButton.js" />
<change beforePath="$PROJECT_DIR$/mobile/src/ui/BoundInput.js" afterPath="$PROJECT_DIR$/mobile/src/ui/BoundInput.js" />
<change beforePath="$PROJECT_DIR$/mobile/src/ui/BoundSwitch.js" afterPath="$PROJECT_DIR$/mobile/src/ui/BoundSwitch.js" />
<change beforePath="$PROJECT_DIR$/server/package-lock.json" afterPath="$PROJECT_DIR$/server/package-lock.json" />
<change beforePath="$PROJECT_DIR$/server/package.json" afterPath="$PROJECT_DIR$/server/package.json" />
<change beforePath="$PROJECT_DIR$/website/src/Teams/TeamList.js" afterPath="$PROJECT_DIR$/website/src/Teams/TeamList.js" />
<change beforePath="$PROJECT_DIR$/website/src/Teams/Teams.js" afterPath="$PROJECT_DIR$/website/src/Teams/Teams.js" />
<change beforePath="$PROJECT_DIR$/website/src/Users/Users.js" afterPath="$PROJECT_DIR$/website/src/Users/Users.js" />
</list> </list>
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" /> <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="TRACKING_ENABLED" value="true" /> <option name="TRACKING_ENABLED" value="true" />
@@ -53,11 +41,11 @@
<foldersAlwaysOnTop value="true" /> <foldersAlwaysOnTop value="true" />
</navigator> </navigator>
<panes> <panes>
<pane id="AndroidView" />
<pane id="Scope" />
<pane id="Scratches" /> <pane id="Scratches" />
<pane id="ProjectPane" /> <pane id="ProjectPane" />
<pane id="Scope" />
<pane id="PackagesPane" /> <pane id="PackagesPane" />
<pane id="AndroidView" />
</panes> </panes>
</component> </component>
<component name="PropertiesComponent"> <component name="PropertiesComponent">
@@ -162,7 +150,6 @@
</component> </component>
<component name="ToolWindowManager"> <component name="ToolWindowManager">
<frame x="-4316" y="117" width="1522" height="1014" extended-state="0" /> <frame x="-4316" y="117" width="1522" height="1014" extended-state="0" />
<editor active="true" />
<layout> <layout>
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" /> <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
<window_info id="Palette&#9;" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" /> <window_info id="Palette&#9;" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />

View File

@@ -61,7 +61,6 @@ class API extends EventEmitter {
this.emit("login") this.emit("login")
}) })
.catch((err) => { .catch((err) => {
console.error(err)
AsyncStorage.removeItem(authTokenName) AsyncStorage.removeItem(authTokenName)
this.token = null this.token = null
this.user = {} this.user = {}

View File

@@ -7,7 +7,7 @@ import {
Switch, Switch,
TextInput, TextInput,
View, View,
Button Button,
} from "react-native" } from "react-native"
import { MessageModal } from "../Modal" import { MessageModal } from "../Modal"
import logoImage from "./images/deighton.png" import logoImage from "./images/deighton.png"
@@ -15,27 +15,29 @@ import { FormBinder } from "react-form-binder"
import { api } from "../API" import { api } from "../API"
import { BoundSwitch, BoundInput, BoundButton } from "../ui" import { BoundSwitch, BoundInput, BoundButton } from "../ui"
import KeyboardSpacer from "react-native-keyboard-spacer" import KeyboardSpacer from "react-native-keyboard-spacer"
import { versionInfo } from "../version"
import autobind from "autobind-decorator" import autobind from "autobind-decorator"
import { isIphoneX } from "react-native-iphone-x-helper"
export class Login extends React.Component { export class Login extends React.Component {
static bindings = { static bindings = {
email: { email: {
alwaysGet: true, alwaysGet: true,
isValid: (r, v) => v !== "" isValid: (r, v) => v !== "",
}, },
password: { password: {
alwaysGet: true, alwaysGet: true,
isValid: (r, v) => v !== "" isValid: (r, v) => v !== "",
}, },
rememberMe: { rememberMe: {
alwaysGet: true, alwaysGet: true,
initValue: true, initValue: true,
isValid: true isValid: true,
}, },
login: { login: {
noValue: true, noValue: true,
isDisabled: r => !(r.anyModified && r.allValid) isDisabled: (r) => !(r.anyModified && r.allValid),
} },
} }
static styles = StyleSheet.create({ static styles = StyleSheet.create({
@@ -44,39 +46,39 @@ export class Login extends React.Component {
flex: 1, flex: 1,
backgroundColor: "#fff", backgroundColor: "#fff",
alignItems: "center", alignItems: "center",
justifyContent: "center" justifyContent: "center",
}, },
logo: { logo: {
width: "50%" width: "50%",
}, },
inputRow: { inputRow: {
paddingTop: 10, paddingTop: 10,
width: "60%", width: "60%",
flexDirection: "column", flexDirection: "column",
justifyContent: "flex-end", justifyContent: "flex-end",
alignItems: "flex-start" alignItems: "flex-start",
}, },
switchRow: { switchRow: {
paddingTop: 10, paddingTop: 10,
width: "60%", width: "60%",
flexDirection: "row", flexDirection: "row",
justifyContent: "flex-end", justifyContent: "flex-end",
alignItems: "center" alignItems: "center",
}, },
buttonRow: { buttonRow: {
paddingTop: 10, paddingTop: 10,
width: "60%", width: "60%",
flexDirection: "row", flexDirection: "row",
justifyContent: "flex-end", justifyContent: "flex-end",
alignItems: "center" alignItems: "center",
} },
}) })
constructor(props) { constructor(props) {
super(props) super(props)
this.state = { this.state = {
binder: new FormBinder({ email: "john@lyon-smith.org" }, Login.bindings), binder: new FormBinder({ email: "john@lyon-smith.org" }, Login.bindings),
messageModal: null messageModal: null,
} }
} }
@@ -88,16 +90,16 @@ export class Login extends React.Component {
if (obj) { if (obj) {
api api
.login(obj.email, obj.password, obj.rememberMe) .login(obj.email, obj.password, obj.rememberMe)
.then(user => { .then((user) => {
history.replace("/home") history.replace("/home")
}) })
.catch(error => { .catch((error) => {
this.setState({ this.setState({
messageModal: { messageModal: {
icon: "hand", icon: "hand",
message: "Unable to login", message: "Unable to login",
detail: error.message detail: error.message,
} },
}) })
}) })
} }
@@ -152,6 +154,17 @@ export class Login extends React.Component {
binder={this.state.binder} binder={this.state.binder}
/> />
</View> </View>
<View style={{ width: "60%", alignItems: "center" }}>
<Text
style={{
paddingTop: 15,
alignSelf: "flex-end",
color: "lightgray",
fontSize: 10,
}}>
{versionInfo.version}
</Text>
</View>
<MessageModal <MessageModal
open={!!messageModal} open={!!messageModal}
icon={messageModal ? messageModal.icon : ""} icon={messageModal ? messageModal.icon : ""}
@@ -159,7 +172,7 @@ export class Login extends React.Component {
detail={messageModal ? messageModal.detail : ""} detail={messageModal ? messageModal.detail : ""}
onDismiss={messageModal && this.handleMessageDismiss} onDismiss={messageModal && this.handleMessageDismiss}
/> />
<KeyboardSpacer /> {Platform.OS === "ios" && <KeyboardSpacer />}
</View> </View>
) )
} }

View File

@@ -186,7 +186,8 @@ export class Home extends React.Component {
style={{ marginLeft: 10, marginRight: 5, tintColor: "gray" }} style={{ marginLeft: 10, marginRight: 5, tintColor: "gray" }}
/> />
<TextInput <TextInput
style={{ flexGrow: 1, height: "100%" }} style={{ flexGrow: 1, flexBasis: 0, height: "100%" }}
underlineColorAndroid="#F4F4F4"
placeholder="Search" placeholder="Search"
/> />
<Icon <Icon

View File

@@ -60,7 +60,7 @@ export class WorkItem extends React.Component {
}, },
location: { location: {
isValid: true, isValid: true,
isDisabled: true, isReadOnly: true,
}, },
details: { details: {
isValid: (r, v) => v !== "", isValid: (r, v) => v !== "",
@@ -210,29 +210,37 @@ export class WorkItem extends React.Component {
/> />
</View> </View>
<View style={styles.panel}> <View style={styles.panel}>
<MapView <View style={{ flexDirection: "column", justifyContent: "center" }}>
style={{ <MapView
flexDirection: "column", style={{
justifyContent: "center", flexDirection: "column",
width: "100%", justifyContent: "center",
height: 400, width: "100%",
marginBottom: 10, height: 400,
}} marginBottom: 10,
zoomControlEnabled }}
initialRegion={{ showsBuildings={false}
latitude: 43.653908, showsTraffic={false}
longitude: -79.384293, showsIndoors={false}
latitudeDelta: 0.0922, zoomControlEnabled
longitudeDelta: 0.0421, initialRegion={{
}} latitude: 43.653908,
onRegionChange={this.handleRegionChange}> longitude: -79.384293,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
onRegionChange={this.handleRegionChange}
/>
<Icon <Icon
name="target" name="target"
size={24} size={24}
style={{ alignSelf: "center" }}
pointerEvents={false} pointerEvents={false}
style={{
position: "absolute",
alignSelf: "center",
}}
/> />
</MapView> </View>
<BoundInput <BoundInput
ref={(ref) => (this.latLngInput = ref)} ref={(ref) => (this.latLngInput = ref)}
binder={binder} binder={binder}
@@ -258,7 +266,7 @@ export class WorkItem extends React.Component {
detail={messageModal ? messageModal.detail : ""} detail={messageModal ? messageModal.detail : ""}
onDismiss={messageModal && this.handleMessageDismiss} onDismiss={messageModal && this.handleMessageDismiss}
/> />
<KeyboardSpacer /> {Platform.OS === "ios" && <KeyboardSpacer />}
</View> </View>
) )
} }

View File

@@ -1,6 +1,6 @@
import React from "react" import React from "react"
import PropTypes from "prop-types" import PropTypes from "prop-types"
import { TextInput, Text, View } from "react-native" import { TextInput, Text, View, Platform } from "react-native"
import autobind from "autobind-decorator" import autobind from "autobind-decorator"
export class BoundInput extends React.Component { export class BoundInput extends React.Component {
@@ -42,7 +42,7 @@ export class BoundInput extends React.Component {
render() { render() {
const { label, password, name, placeholder, message, lines } = this.props const { label, password, name, placeholder, message, lines } = this.props
const { visible, disabled, value, valid } = this.state const { visible, disabled, readOnly, value, valid } = this.state
if (!visible) { if (!visible) {
return null return null
@@ -62,11 +62,12 @@ export class BoundInput extends React.Component {
borderWidth: 1, borderWidth: 1,
fontSize: 16, fontSize: 16,
paddingTop: 7, paddingTop: 7,
paddingBottom: 7, paddingBottom: Platform.OS === "ios" ? 7 : 0,
textAlignVertical: "top",
}} }}
multiline={lines > 1} multiline={lines > 1}
numberOfLines={lines} numberOfLines={lines}
editable={!disabled} editable={!disabled && !readOnly}
autoCapitalize="none" autoCapitalize="none"
underlineColorAndroid="white" underlineColorAndroid="white"
value={value} value={value}

View File

@@ -1,10 +1,13 @@
import React, { Component } from 'react' import React, { Component } from "react"
import { View, TouchableOpacity, Text } from 'react-native' import { View, Platform, TouchableOpacity, Text } from "react-native"
import { Icon } from './Icon' import { Icon } from "./Icon"
import PropTypes from 'prop-types' import PropTypes from "prop-types"
import { ifIphoneX } from 'react-native-iphone-x-helper' import { ifIphoneX } from "react-native-iphone-x-helper"
const headerButtonShape = { icon: PropTypes.string.isRequired, onPress: PropTypes.func } const headerButtonShape = {
icon: PropTypes.string.isRequired,
onPress: PropTypes.func,
}
export class Header extends Component { export class Header extends Component {
static propTypes = { static propTypes = {
@@ -15,8 +18,8 @@ export class Header extends Component {
} }
static defaultProps = { static defaultProps = {
rightButton: { icon: 'none' }, rightButton: { icon: "none" },
leftButton: { icon: 'none' }, leftButton: { icon: "none" },
visible: true, visible: true,
} }
@@ -25,35 +28,49 @@ export class Header extends Component {
let right = null let right = null
if (!rightButton) { if (!rightButton) {
right = ( right = <Icon name="" size={24} style={{ marginRight: 15 }} />
<Icon name='' size={24} style={{ marginRight: 15 }} />
)
} else if (disabled) { } else if (disabled) {
right = ( right = (
<Icon name={rightButton.icon} size={24} style={{ marginRight: 15, tintColor: 'lightgrey' }} /> <Icon
name={rightButton.icon}
size={24}
style={{ marginRight: 15, tintColor: "lightgrey" }}
/>
) )
} else { } else {
right = ( right = (
<TouchableOpacity onPress={rightButton.onPress}> <TouchableOpacity onPress={rightButton.onPress}>
<Icon name={rightButton.icon} size={24} style={{ marginRight: 15, tintColor: 'grey' }} /> <Icon
name={rightButton.icon}
size={24}
style={{ marginRight: 15, tintColor: "grey" }}
/>
</TouchableOpacity> </TouchableOpacity>
) )
} }
return ( return (
<View style={{ <View
flexDirection: 'row', style={[
justifyContent: 'space-between', {
alignItems: 'center', flexDirection: "row",
width: '100%', justifyContent: "space-between",
height: 45, alignItems: "center",
backgroundColor: '#F4F4F4', width: "100%",
...ifIphoneX({ marginTop: 50 }, { marginTop: 20 }) height: 45,
}}> backgroundColor: "#F4F4F4",
},
Platform.OS === "ios" &&
ifIphoneX({ marginTop: 50 }, { marginTop: 20 }),
]}>
<TouchableOpacity onPress={leftButton.onPress}> <TouchableOpacity onPress={leftButton.onPress}>
<Icon name={leftButton.icon} size={24} style={{ marginLeft: 15, tintColor: 'gray' }} /> <Icon
name={leftButton.icon}
size={24}
style={{ marginLeft: 15, tintColor: "gray" }}
/>
</TouchableOpacity> </TouchableOpacity>
<Text style={{ color: 'gray', fontSize: 18, }}>{title}</Text> <Text style={{ color: "gray", fontSize: 18 }}>{title}</Text>
{right} {right}
</View> </View>
) )

7
mobile/src/version.js Normal file
View File

@@ -0,0 +1,7 @@
export const versionInfo = {
version: '1.0.0',
fullVersion: '1.0.0-20180407.3',
title: 'Deighton AR System',
copyright: '© 2018, Kingston Software Solutions.',
supportEmail: 'support@kss.us.com',
}

View File

@@ -3,6 +3,7 @@
"package.json", "package.json",
"website/.env", "website/.env",
"website/src/version.js", "website/src/version.js",
"mobile/src/version.js",
"mobile/ios/DeightonAR/info.plist", "mobile/ios/DeightonAR/info.plist",
"mobile/android/app/build.gradle", "mobile/android/app/build.gradle",
"mobile/android/app/src/main/AndroidManifest.xml", "mobile/android/app/src/main/AndroidManifest.xml",