V1
This commit is contained in:
4
.expo-shared/assets.json
Normal file
4
.expo-shared/assets.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"f9155ac790fd02fadcdeca367b02581c04a353aa6d5aa84409a59f6804c87acd": true,
|
||||
"89ed26367cdb9b771858e026f2eb95bfdb90e5ae943e716575327ec325f39c44": true
|
||||
}
|
||||
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
node_modules/**/*
|
||||
.expo/*
|
||||
npm-debug.*
|
||||
*.jks
|
||||
*.p8
|
||||
*.p12
|
||||
*.key
|
||||
*.mobileprovision
|
||||
*.orig.*
|
||||
web-build/
|
||||
web-report/
|
||||
12
.idea/bird-bam.iml
generated
Normal file
12
.idea/bird-bam.iml
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
6
.idea/misc.xml
generated
Normal file
6
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JavaScriptSettings">
|
||||
<option name="languageLevel" value="JSX" />
|
||||
</component>
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/bird-bam.iml" filepath="$PROJECT_DIR$/.idea/bird-bam.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
299
.idea/workspace.xml
generated
Normal file
299
.idea/workspace.xml
generated
Normal file
@@ -0,0 +1,299 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="1582f386-ce79-4cb6-aea9-8e19c50fae98" name="Default Changelist" comment="">
|
||||
<change afterPath="$PROJECT_DIR$/../.idea/vcs.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/.idea/bird-bam.iml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/Button.js" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/TextInput.js" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/UserInterface.js" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/../.idea/beepboop.iml" beforeDir="false" afterPath="$PROJECT_DIR$/../.idea/beepboop.iml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/../.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/../.idea/workspace.xml" afterDir="false" />
|
||||
</list>
|
||||
<ignored path="$PROJECT_DIR$/.tmp/" />
|
||||
<ignored path="$PROJECT_DIR$/temp/" />
|
||||
<ignored path="$PROJECT_DIR$/tmp/" />
|
||||
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="FileEditorManager">
|
||||
<leaf>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/App.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="42">
|
||||
<caret line="2" column="20" selection-start-line="2" selection-start-column="20" selection-end-line="2" selection-end-column="20" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/package.json">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="315">
|
||||
<caret line="15" column="33" selection-start-line="15" selection-start-column="33" selection-end-line="15" selection-end-column="33" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/TextInput.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="357">
|
||||
<caret line="17" selection-start-line="17" selection-end-line="17" />
|
||||
<folding>
|
||||
<element signature="e#0#26#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/Button.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="105">
|
||||
<caret line="5" column="20" selection-start-line="5" selection-start-column="20" selection-end-line="6" selection-end-column="22" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/app.json">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="273">
|
||||
<caret line="13" column="26" selection-start-line="13" selection-start-column="26" selection-end-line="13" selection-end-column="26" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="true">
|
||||
<entry file="file://$PROJECT_DIR$/UserInterface.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="238">
|
||||
<caret line="214" column="44" selection-start-line="214" selection-start-column="44" selection-end-line="214" selection-end-column="44" />
|
||||
<folding>
|
||||
<element signature="e#20#46#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/assets/splash.png">
|
||||
<provider selected="true" editor-type-id="images" />
|
||||
</entry>
|
||||
</file>
|
||||
</leaf>
|
||||
</component>
|
||||
<component name="FileTemplateManagerImpl">
|
||||
<option name="RECENT_TEMPLATES">
|
||||
<list>
|
||||
<option value="JavaScript File" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." />
|
||||
</component>
|
||||
<component name="IdeDocumentHistory">
|
||||
<option name="CHANGED_PATHS">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/app.json" />
|
||||
<option value="$PROJECT_DIR$/Button.js" />
|
||||
<option value="$PROJECT_DIR$/TextInput.js" />
|
||||
<option value="$PROJECT_DIR$/package.json" />
|
||||
<option value="$PROJECT_DIR$/ui.js" />
|
||||
<option value="$PROJECT_DIR$/App.js" />
|
||||
<option value="$PROJECT_DIR$/UserInterface.js" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectConfigurationFiles">
|
||||
<option name="files">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/.idea/bird-bam.iml" />
|
||||
<option value="$PROJECT_DIR$/.idea/vcs.xml" />
|
||||
<option value="$PROJECT_DIR$/.idea/misc.xml" />
|
||||
<option value="$PROJECT_DIR$/.idea/modules.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectFrameBounds" extendedState="6">
|
||||
<option name="width" value="1280" />
|
||||
<option name="height" value="696" />
|
||||
</component>
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
|
||||
<component name="ProjectView">
|
||||
<navigator proportions="" version="1">
|
||||
<foldersAlwaysOnTop value="true" />
|
||||
</navigator>
|
||||
<panes>
|
||||
<pane id="Scope" />
|
||||
<pane id="ProjectPane">
|
||||
<subPane>
|
||||
<expand>
|
||||
<path>
|
||||
<item name="bird-bam" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="bird-bam" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="bird-bam" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="bird-bam" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="assets" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
</expand>
|
||||
<select />
|
||||
</subPane>
|
||||
</pane>
|
||||
</panes>
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
|
||||
<property name="node.js.detected.package.eslint" value="true" />
|
||||
<property name="node.js.detected.package.tslint" value="true" />
|
||||
<property name="node.js.path.for.package.eslint" value="project" />
|
||||
<property name="node.js.path.for.package.tslint" value="project" />
|
||||
<property name="node.js.selected.package.eslint" value="(autodetect)" />
|
||||
<property name="node.js.selected.package.tslint" value="(autodetect)" />
|
||||
<property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" />
|
||||
<property name="nodejs_npm_path_reset_for_default_project" value="true" />
|
||||
<property name="nodejs_package_manager_path" value="yarn" />
|
||||
<property name="settings.editor.selected.configurable" value="preferences.pluginManager" />
|
||||
</component>
|
||||
<component name="RecentsManager">
|
||||
<key name="MoveFile.RECENT_KEYS">
|
||||
<recent name="$PROJECT_DIR$/assets" />
|
||||
</key>
|
||||
</component>
|
||||
<component name="RunDashboard">
|
||||
<option name="ruleStates">
|
||||
<list>
|
||||
<RuleState>
|
||||
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
|
||||
</RuleState>
|
||||
<RuleState>
|
||||
<option name="name" value="StatusDashboardGroupingRule" />
|
||||
</RuleState>
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="RunManager">
|
||||
<configuration name="run" type="js.build_tools.npm" nameIsGenerated="true">
|
||||
<package-json value="$PROJECT_DIR$/package.json" />
|
||||
<command value="run" />
|
||||
<scripts>
|
||||
<script value="start" />
|
||||
</scripts>
|
||||
<node-interpreter value="project" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
<component name="SvnConfiguration">
|
||||
<configuration />
|
||||
</component>
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="1582f386-ce79-4cb6-aea9-8e19c50fae98" name="Default Changelist" comment="" />
|
||||
<created>1567277341123</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1567277341123</updated>
|
||||
<workItem from="1567277342489" duration="9493000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TimeTrackingManager">
|
||||
<option name="totallyTimeSpent" value="9493000" />
|
||||
</component>
|
||||
<component name="ToolWindowManager">
|
||||
<frame x="-1" y="-2" width="1922" height="1047" extended-state="6" />
|
||||
<editor active="true" />
|
||||
<layout>
|
||||
<window_info id="npm" side_tool="true" />
|
||||
<window_info id="Favorites" side_tool="true" />
|
||||
<window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.1651715" />
|
||||
<window_info id="Structure" order="1" side_tool="true" weight="0.25" />
|
||||
<window_info anchor="bottom" id="Docker" show_stripe_button="false" />
|
||||
<window_info anchor="bottom" id="Version Control" />
|
||||
<window_info anchor="bottom" id="Terminal" />
|
||||
<window_info anchor="bottom" id="Event Log" sideWeight="0.50026387" side_tool="true" visible="true" weight="0.19977678" />
|
||||
<window_info anchor="bottom" id="Message" order="0" />
|
||||
<window_info anchor="bottom" id="Find" order="1" />
|
||||
<window_info anchor="bottom" id="Run" order="2" sideWeight="0.49973616" visible="true" weight="0.19977678" />
|
||||
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
|
||||
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
|
||||
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
||||
<window_info anchor="bottom" id="TODO" order="6" />
|
||||
<window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
|
||||
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
|
||||
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
|
||||
</layout>
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="1" />
|
||||
</component>
|
||||
<component name="editorHistoryManager">
|
||||
<entry file="file://$PROJECT_DIR$/assets/logo.png">
|
||||
<provider selected="true" editor-type-id="images" />
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/assets/icon.png">
|
||||
<provider selected="true" editor-type-id="images" />
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/assets/splash.png">
|
||||
<provider selected="true" editor-type-id="images" />
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/Button.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="105">
|
||||
<caret line="5" column="20" selection-start-line="5" selection-start-column="20" selection-end-line="6" selection-end-column="22" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/TextInput.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="357">
|
||||
<caret line="17" selection-start-line="17" selection-end-line="17" />
|
||||
<folding>
|
||||
<element signature="e#0#26#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/package.json">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="315">
|
||||
<caret line="15" column="33" selection-start-line="15" selection-start-column="33" selection-end-line="15" selection-end-column="33" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/app.json">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="273">
|
||||
<caret line="13" column="26" selection-start-line="13" selection-start-column="26" selection-end-line="13" selection-end-column="26" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/App.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="42">
|
||||
<caret line="2" column="20" selection-start-line="2" selection-start-column="20" selection-end-line="2" selection-end-column="20" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/UserInterface.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="238">
|
||||
<caret line="214" column="44" selection-start-line="214" selection-start-column="44" selection-end-line="214" selection-end-column="44" />
|
||||
<folding>
|
||||
<element signature="e#20#46#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</component>
|
||||
</project>
|
||||
1
.watchmanconfig
Normal file
1
.watchmanconfig
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
20
App.js
Normal file
20
App.js
Normal file
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import UserInterface from './UserInterface';
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<UserInterface />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#fff',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}
|
||||
});
|
||||
108
Button.js
Normal file
108
Button.js
Normal file
@@ -0,0 +1,108 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
View,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
} from 'react-native';
|
||||
|
||||
|
||||
|
||||
export default class Button extends React.Component {
|
||||
|
||||
|
||||
render() {
|
||||
|
||||
if (!this.props.visible) {
|
||||
return false;
|
||||
}
|
||||
if (!this.props.label) {
|
||||
return false;
|
||||
}
|
||||
if (!this.props.onClick) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.component}>
|
||||
<View style={styles.layouts}>
|
||||
<View style={styles.layout}>
|
||||
<View style={styles.itemcontainer}>
|
||||
<View style={styles.itemcontainerInner}>
|
||||
<TouchableOpacity
|
||||
style={styles.chocolate}
|
||||
onPress={this.props.onClick}
|
||||
>
|
||||
<Text style={styles.item1TouchableOpacity}>
|
||||
{this.props.label}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
|
||||
component: {
|
||||
width: '100%',
|
||||
flexDirection: 'row',
|
||||
paddingLeft: 7.5,
|
||||
paddingRight: 7.5,
|
||||
paddingTop: 7.5,
|
||||
paddingBottom: 7.5,
|
||||
},
|
||||
|
||||
layouts: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
},
|
||||
|
||||
layout: {
|
||||
width: '100%',
|
||||
height: 90,
|
||||
},
|
||||
|
||||
itemcontainer: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
paddingTop: 7.5,
|
||||
paddingBottom: 7.5,
|
||||
paddingLeft: 7.5,
|
||||
paddingRight: 7.5,
|
||||
},
|
||||
|
||||
itemcontainerInner: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
position: 'relative',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
|
||||
chocolate: {
|
||||
backgroundColor: '#1194f6',
|
||||
borderWidth: 0,
|
||||
borderColor: '#eee',
|
||||
borderStyle: 'solid',
|
||||
borderRadius: 4,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
overflow: 'hidden',
|
||||
padding: 10,
|
||||
},
|
||||
|
||||
buttonText: {
|
||||
color: '#fff',
|
||||
fontSize: 14,
|
||||
textAlign: 'center',
|
||||
width: '100%',
|
||||
},
|
||||
|
||||
});
|
||||
116
TextInput.js
Normal file
116
TextInput.js
Normal file
@@ -0,0 +1,116 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
View,
|
||||
KeyboardAvoidingView,
|
||||
TextInput,
|
||||
} from 'react-native';
|
||||
|
||||
export default class PTextInput extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
data: ""
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
if (!this.props.visible) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.props.placeholder){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!this.props.textChange){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<KeyboardAvoidingView
|
||||
style={styles.component}
|
||||
behavior={'padding'}
|
||||
>
|
||||
<View style={styles.layouts}>
|
||||
<View style={styles.layout}>
|
||||
<View style={styles.itemcontainer}>
|
||||
<View style={styles.itemcontainerInner}>
|
||||
<View style={styles.chocolate}>
|
||||
<TextInput
|
||||
style={styles.TextInput}
|
||||
placeholder={this.props.placeholder}
|
||||
underlineColorAndroid={"transparent"}
|
||||
placeholderTextColor={"#AFAFAF"}
|
||||
onChangeText={(val) => {
|
||||
this.setState({ data: val });
|
||||
this.props.textChange(val);
|
||||
}}
|
||||
value={this.state.data}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</KeyboardAvoidingView>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
|
||||
component: {
|
||||
width: '100%',
|
||||
flexDirection: 'row',
|
||||
paddingLeft: 7.5,
|
||||
paddingRight: 7.5,
|
||||
paddingTop: 7.5,
|
||||
paddingBottom: 7.5,
|
||||
},
|
||||
|
||||
layouts: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
},
|
||||
|
||||
layout: {
|
||||
width: '100%',
|
||||
height: 90,
|
||||
},
|
||||
|
||||
itemcontainer: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
paddingTop: 7.5,
|
||||
paddingBottom: 7.5,
|
||||
paddingLeft: 7.5,
|
||||
paddingRight: 7.5,
|
||||
},
|
||||
|
||||
itemcontainerInner: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
position: 'relative',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
|
||||
chocolate: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
justifyContent: 'center',
|
||||
padding: 10,
|
||||
overflow: 'hidden',
|
||||
},
|
||||
|
||||
TextInput: {
|
||||
color: '#181818',
|
||||
fontSize: 14,
|
||||
textAlign: 'left',
|
||||
width: '100%',
|
||||
},
|
||||
|
||||
});
|
||||
381
UserInterface.js
Normal file
381
UserInterface.js
Normal file
@@ -0,0 +1,381 @@
|
||||
// Secrets
|
||||
/*
|
||||
Secrets
|
||||
Inputs:
|
||||
trackme - hit set token to set fixed location to dynamic
|
||||
setrad:<feet> - hit scan button to set scan radius
|
||||
*/
|
||||
|
||||
|
||||
import React from 'react';
|
||||
import { Alert, StyleSheet, AsyncStorage, Image, Text, View } from 'react-native';
|
||||
import Button from './Button';
|
||||
import PTextInput from './TextInput';
|
||||
import Hero from 'react-native-hero';
|
||||
|
||||
|
||||
export default class UserInterface extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
text: "",
|
||||
status: "Not logged in",
|
||||
token: undefined,
|
||||
radius: "10000.0",
|
||||
location: {
|
||||
"timestamp": 1533729980953.91,
|
||||
"coords": {
|
||||
"accuracy": 5,
|
||||
"altitude": 0,
|
||||
"altitudeAccuracy": -1,
|
||||
"heading": -1,
|
||||
"latitude": 39.03467555,
|
||||
"longitude": -94.5804479,
|
||||
"speed": -1
|
||||
}
|
||||
},
|
||||
birdsobj: undefined
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Feet calculation
|
||||
distance(lat1, lon1, lat2, lon2) {
|
||||
if ((lat1 == lat2) && (lon1 == lon2)) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
var radlat1 = Math.PI * lat1/180;
|
||||
var radlat2 = Math.PI * lat2/180;
|
||||
var theta = lon1-lon2;
|
||||
var radtheta = Math.PI * theta/180;
|
||||
var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
|
||||
if (dist > 1) {
|
||||
dist = 1;
|
||||
}
|
||||
dist = Math.acos(dist);
|
||||
dist = dist * 180/Math.PI;
|
||||
dist = dist * 60 * 1.1515;
|
||||
dist = dist * 5280;
|
||||
return dist;
|
||||
}
|
||||
}
|
||||
|
||||
// Generate headers to send to bird
|
||||
genHeaders(token){
|
||||
if(token === 'registration'){
|
||||
return {
|
||||
'app-version': '4.46.1.9',
|
||||
'os-version': '6.0',
|
||||
'user-agent': 'Android - 6.0',
|
||||
'connection-type': '4G',
|
||||
'device-model': 'Android SDK built for x86_64',
|
||||
'battery-level': '0',
|
||||
'device-name': 'generic_x86_64',
|
||||
'carrier-name': 'Android',
|
||||
'device-id': '5aeb9526b4a9b0ef',
|
||||
'platform': 'android',
|
||||
'location': '{"accuracy":11.0,"altitude":130.0,"heading":null,"latitude":39.03467555,"longitude":-94.5804479,"mocked":false,"speed":10.728463172912598}',
|
||||
'bluetooth-state': 'disabled',
|
||||
'app-name': 'bird',
|
||||
'accept-language': 'en-US'
|
||||
};
|
||||
}
|
||||
return {
|
||||
'app-version': '4.46.1.9',
|
||||
'os-version': '6.0',
|
||||
'user-agent': 'Android - 6.0',
|
||||
'connection-type': '4G',
|
||||
'device-model': 'Android SDK built for x86_64',
|
||||
'battery-level': '0',
|
||||
'device-name': 'generic_x86_64',
|
||||
'carrier-name': 'Android',
|
||||
'device-id': '5aeb9526b4a9b0ef',
|
||||
'platform': 'android',
|
||||
'location': '{"accuracy":11.0,"altitude":130.0,"heading":null,"latitude":39.03467555,"longitude":-94.5804479,"mocked":false,"speed":10.728463172912598}',
|
||||
'bluetooth-state': 'disabled',
|
||||
'app-name': 'bird',
|
||||
'authorization': 'Bird '+token,
|
||||
'accept-language': 'en-US'
|
||||
};
|
||||
}
|
||||
|
||||
// Takes an email token and converts it to a usable session
|
||||
register(){
|
||||
// Secret tracking keyword
|
||||
if(this.state.text.toLowerCase() === 'trackme'){
|
||||
this.getLocation();
|
||||
} else{
|
||||
// Real function
|
||||
if(this.state.text.length >24 && this.state.text.length <20){
|
||||
Alert.alert('This is not a valid registration token');
|
||||
} else{
|
||||
// https://enyam4wrrj28.x.pipedream.net/request/accept
|
||||
// https://api.birdapp.com/request/accept
|
||||
fetch('https://api.birdapp.com/request/accept',{method: 'PUT', headers: {...this.genHeaders('registration'), 'content-type': 'application/json; charset=UTF-8'}, body: JSON.stringify({token: this.state.text})})
|
||||
.then((response) => response.json())
|
||||
.then( (output) => {
|
||||
console.log(output);
|
||||
if(typeof output.code === 'number'){
|
||||
this.setState({
|
||||
status: "token invalid"
|
||||
});
|
||||
} else{
|
||||
AsyncStorage.setItem('token', output.token);
|
||||
this.setState({
|
||||
status: "Logged in! Tap to scan",
|
||||
token: output.token
|
||||
});
|
||||
}
|
||||
}).catch(function (error) {
|
||||
console.log(error);
|
||||
});
|
||||
//
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Scanner to seek out the birds
|
||||
scan(){
|
||||
if(this.state.text.toLowerCase().includes('setrad:')){
|
||||
const rad = this.state.text.toLowerCase().split(':')[1];
|
||||
this.setState({
|
||||
status: `Radius set to ${rad}`,
|
||||
radius: rad,
|
||||
text: ""
|
||||
});
|
||||
} else{
|
||||
if(typeof this.state.token === 'undefined'){
|
||||
Alert.alert('No valid token is available');
|
||||
} else{
|
||||
//console.log(`https://api.birdapp.com/bird/nearby?latitude=${this.state.location.coords.latitude.toString()}&longitude=${this.state.location.coords.longitude.toString()}&radius=${this.state.radius}`);
|
||||
fetch(`https://api.birdapp.com/bird/nearby?latitude=${this.state.location.coords.latitude.toString()}&longitude=${this.state.location.coords.longitude.toString()}&radius=10000.0`
|
||||
,{method:'GET', headers: this.genHeaders(this.state.token)})
|
||||
.then((response) => response.json())
|
||||
.then( (output) => {
|
||||
//console.log(output);
|
||||
if(typeof output.birds !== 'object'){
|
||||
this.setState({
|
||||
status: "token invalid",
|
||||
token: undefined
|
||||
});
|
||||
} else{
|
||||
if(this.state.radius !== '10000.0'){
|
||||
let newobj = [];
|
||||
let total = output.birds.length;
|
||||
let inc = 0;
|
||||
output.birds.forEach((bird)=>{
|
||||
inc++;
|
||||
const reach = this.distance(this.state.location.coords.latitude, this.state.location.coords.longitude, bird.location.latitude, bird.location.longitude);
|
||||
if(reach < parseInt(this.state.radius)){
|
||||
newobj.push(bird);
|
||||
}
|
||||
if(inc === total){
|
||||
// Done
|
||||
total = newobj.length.toString();
|
||||
this.setState({
|
||||
status: `Scanned! Total birds in scope: ${total}`,
|
||||
birdsobj: newobj
|
||||
});
|
||||
}
|
||||
});
|
||||
} else{
|
||||
// No distance changing
|
||||
const total = output.birds.length.toString();
|
||||
this.setState({
|
||||
status: `Scanned! Total birds in scope: ${total}`,
|
||||
birdsobj: output.birds
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}).catch(function (error) {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// The beep
|
||||
beep(){
|
||||
if(typeof this.state.birdsobj === 'undefined'){
|
||||
Alert.alert('No birds in sight');
|
||||
} else{
|
||||
this.state.birdsobj.forEach((bird)=>{
|
||||
fetch('https://api.birdapp.com/bird/chirp',
|
||||
{method:'PUT', headers:{...this.genHeaders(this.state.token), 'content-type': 'application/json; charset=UTF-8'}, body: JSON.stringify({
|
||||
"bird_id": bird.id,
|
||||
"alarm": false
|
||||
})})
|
||||
.then((response) => response.json())
|
||||
.then( (output) => {
|
||||
console.log(output);
|
||||
}).catch(function (error) {
|
||||
console.log(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// The bad one
|
||||
alarm(){
|
||||
Alert.alert(
|
||||
'WARNING',
|
||||
'This will cause all birds to emit a long, and loud alert sound. Please confirm you are absolutely sure about doing this.',
|
||||
[
|
||||
{text: 'NO', onPress: () => console.warn('cancelled'), style: 'cancel'},
|
||||
{text: 'YES', onPress: () => {
|
||||
//
|
||||
if(typeof this.state.birdsobj === 'undefined'){
|
||||
Alert.alert('No birds in sight');
|
||||
} else{
|
||||
this.state.birdsobj.forEach((bird)=>{
|
||||
fetch('https://api.birdapp.com/bird/chirp',
|
||||
{method:'PUT', headers:{...this.genHeaders(this.state.token), 'content-type': 'application/json; charset=UTF-8'}, body: JSON.stringify({
|
||||
"bird_id": bird.id,
|
||||
"alarm": true
|
||||
})});
|
||||
});
|
||||
}
|
||||
}},
|
||||
]
|
||||
);
|
||||
};
|
||||
|
||||
// Check if the token exists, and if so try signing in
|
||||
async checkUserSignedIn(){
|
||||
let context = this;
|
||||
try {
|
||||
let value = await AsyncStorage.getItem('token');
|
||||
if (value != null){
|
||||
// Check if token is a valid one
|
||||
fetch(`https://api.birdapp.com/user`, {
|
||||
method: 'GET',
|
||||
headers: this.genHeaders(value)
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then( (output) => {
|
||||
if(typeof output.government === 'undefined'){
|
||||
this.setState({
|
||||
status: "Old token invalid"
|
||||
});
|
||||
} else{
|
||||
this.setState({
|
||||
status: "Logged in! Tap to scan",
|
||||
token: value
|
||||
});
|
||||
}
|
||||
}).catch(function (error) {
|
||||
console.log(error);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
// do something else
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
// Error retrieving data
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the location to localize your actions
|
||||
getLocation(){
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
position => {
|
||||
const location = JSON.stringify(position);
|
||||
|
||||
this.setState({ position });
|
||||
Alert.alert('Position acquired!',
|
||||
'Lat: '+position.coords.latitude.toString() + '\nLon: '+position.coords.longitude.toString());
|
||||
},
|
||||
error => Alert.alert(error.message),
|
||||
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 }
|
||||
);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
this.checkUserSignedIn();
|
||||
// this.checkUserSignedIn().then((result)=>{
|
||||
// if(result){
|
||||
// this.props.navigation.navigate('Menu', {})
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View
|
||||
onPress={()=>{this.getLocation()}}
|
||||
>
|
||||
<Image
|
||||
style={styles.stretch}
|
||||
source={require('./assets/logo.png')}
|
||||
/>
|
||||
</View>
|
||||
<PTextInput
|
||||
visible={ true }
|
||||
placeholder = {"Insert login token OR set range"}
|
||||
textChange={(val) => this.setState({ text: val })}
|
||||
/>
|
||||
<Button
|
||||
visible={ true }
|
||||
label={"Update auth token"}
|
||||
onClick={()=>{this.register()}}
|
||||
/>
|
||||
<Hero
|
||||
key={0}
|
||||
source={require('./assets/birds.jpg')}
|
||||
renderOverlay={() => (
|
||||
<View
|
||||
style={{ padding: 40 }}
|
||||
onPress={()=>{this.scan()}}
|
||||
>
|
||||
<Text
|
||||
style={styles.input}
|
||||
onPress={()=>{this.scan()}}
|
||||
>{this.state.status}</Text>
|
||||
</View>
|
||||
)}
|
||||
/>
|
||||
<Button
|
||||
visible={ true }
|
||||
label={"Beep"}
|
||||
onClick={()=>{this.beep()}}
|
||||
/>
|
||||
<Button
|
||||
visible={ true }
|
||||
label={"Alarm"}
|
||||
onClick={()=>{this.alarm()}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#fff',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
stretch: {
|
||||
width: 75,
|
||||
height: 75,
|
||||
resizeMode: 'stretch'
|
||||
},
|
||||
input: {
|
||||
fontSize: 25,
|
||||
color: '#fff',
|
||||
fontWeight: '600',
|
||||
textAlign: 'center'
|
||||
}
|
||||
});
|
||||
30
app.json
Normal file
30
app.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"expo": {
|
||||
"name": "Bird Ringer",
|
||||
"slug": "bird-bam",
|
||||
"privacy": "public",
|
||||
"sdkVersion": "34.0.0",
|
||||
"platforms": [
|
||||
"ios",
|
||||
"android",
|
||||
"web"
|
||||
],
|
||||
"version": "1.0.0",
|
||||
"orientation": "portrait",
|
||||
"icon": "./assets/logo.png",
|
||||
"splash": {
|
||||
"image": "./assets/splash.png",
|
||||
"resizeMode": "contain",
|
||||
"backgroundColor": "#ffffff"
|
||||
},
|
||||
"updates": {
|
||||
"fallbackToCacheTimeout": 0
|
||||
},
|
||||
"assetBundlePatterns": [
|
||||
"**/*"
|
||||
],
|
||||
"ios": {
|
||||
"supportsTablet": true
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
assets/birds.jpg
Normal file
BIN
assets/birds.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 147 KiB |
BIN
assets/icon.png
Normal file
BIN
assets/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
assets/logo.png
Normal file
BIN
assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 33 KiB |
BIN
assets/splash.png
Normal file
BIN
assets/splash.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 185 KiB |
6
babel.config.js
Normal file
6
babel.config.js
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = function(api) {
|
||||
api.cache(true);
|
||||
return {
|
||||
presets: ['babel-preset-expo'],
|
||||
};
|
||||
};
|
||||
22
package.json
Normal file
22
package.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"main": "node_modules/expo/AppEntry.js",
|
||||
"scripts": {
|
||||
"start": "expo start",
|
||||
"android": "expo start --android",
|
||||
"ios": "expo start --ios",
|
||||
"web": "expo start --web",
|
||||
"eject": "expo eject"
|
||||
},
|
||||
"dependencies": {
|
||||
"expo": "^34.0.1",
|
||||
"react": "16.8.3",
|
||||
"react-dom": "^16.8.6",
|
||||
"react-native": "https://github.com/expo/react-native/archive/sdk-34.0.0.tar.gz",
|
||||
"react-native-web": "^0.11.4",
|
||||
"react-native-hero": "^0.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-preset-expo": "^6.0.0"
|
||||
},
|
||||
"private": true
|
||||
}
|
||||
Reference in New Issue
Block a user