initial import
This commit is contained in:
parent
fa1f694e72
commit
e65ade8ffe
117
App.tsx
117
App.tsx
|
@ -1,118 +1,9 @@
|
|||
/**
|
||||
* Sample React Native App
|
||||
* https://github.com/facebook/react-native
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
import Main from './src//Main';
|
||||
|
||||
import React from 'react';
|
||||
import type {PropsWithChildren} from 'react';
|
||||
import {
|
||||
SafeAreaView,
|
||||
ScrollView,
|
||||
StatusBar,
|
||||
StyleSheet,
|
||||
Text,
|
||||
useColorScheme,
|
||||
View,
|
||||
} from 'react-native';
|
||||
|
||||
import {
|
||||
Colors,
|
||||
DebugInstructions,
|
||||
Header,
|
||||
LearnMoreLinks,
|
||||
ReloadInstructions,
|
||||
} from 'react-native/Libraries/NewAppScreen';
|
||||
|
||||
type SectionProps = PropsWithChildren<{
|
||||
title: string;
|
||||
}>;
|
||||
|
||||
function Section({children, title}: SectionProps): React.JSX.Element {
|
||||
const isDarkMode = useColorScheme() === 'dark';
|
||||
const App = () => {
|
||||
return (
|
||||
<View style={styles.sectionContainer}>
|
||||
<Text
|
||||
style={[
|
||||
styles.sectionTitle,
|
||||
{
|
||||
color: isDarkMode ? Colors.white : Colors.black,
|
||||
},
|
||||
]}>
|
||||
{title}
|
||||
</Text>
|
||||
<Text
|
||||
style={[
|
||||
styles.sectionDescription,
|
||||
{
|
||||
color: isDarkMode ? Colors.light : Colors.dark,
|
||||
},
|
||||
]}>
|
||||
{children}
|
||||
</Text>
|
||||
</View>
|
||||
<Main></Main>
|
||||
);
|
||||
}
|
||||
|
||||
function App(): React.JSX.Element {
|
||||
const isDarkMode = useColorScheme() === 'dark';
|
||||
|
||||
const backgroundStyle = {
|
||||
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
|
||||
};
|
||||
|
||||
return (
|
||||
<SafeAreaView style={backgroundStyle}>
|
||||
<StatusBar
|
||||
barStyle={isDarkMode ? 'light-content' : 'dark-content'}
|
||||
backgroundColor={backgroundStyle.backgroundColor}
|
||||
/>
|
||||
<ScrollView
|
||||
contentInsetAdjustmentBehavior="automatic"
|
||||
style={backgroundStyle}>
|
||||
<Header />
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: isDarkMode ? Colors.black : Colors.white,
|
||||
}}>
|
||||
<Section title="Step One">
|
||||
Edit <Text style={styles.highlight}>App.tsx</Text> to change this
|
||||
screen and then come back to see your edits.
|
||||
</Section>
|
||||
<Section title="See Your Changes">
|
||||
<ReloadInstructions />
|
||||
</Section>
|
||||
<Section title="Debug">
|
||||
<DebugInstructions />
|
||||
</Section>
|
||||
<Section title="Learn More">
|
||||
Read the docs to discover what to do next:
|
||||
</Section>
|
||||
<LearnMoreLinks />
|
||||
</View>
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
sectionContainer: {
|
||||
marginTop: 32,
|
||||
paddingHorizontal: 24,
|
||||
},
|
||||
sectionTitle: {
|
||||
fontSize: 24,
|
||||
fontWeight: '600',
|
||||
},
|
||||
sectionDescription: {
|
||||
marginTop: 8,
|
||||
fontSize: 18,
|
||||
fontWeight: '400',
|
||||
},
|
||||
highlight: {
|
||||
fontWeight: '700',
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export default App;
|
|
@ -1,6 +1,11 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.NFC"/>
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.nfc.hce"
|
||||
android:required="true" />
|
||||
|
||||
<application
|
||||
android:name=".MainApplication"
|
||||
|
|
|
@ -18,4 +18,36 @@ buildscript {
|
|||
}
|
||||
}
|
||||
|
||||
subprojects {
|
||||
afterEvaluate {
|
||||
if (project.hasProperty("android")) {
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
buildToolsVersion rootProject.ext.buildToolsVersion
|
||||
|
||||
defaultConfig {
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
}
|
||||
|
||||
// Speed up Tests Stage
|
||||
tasks.withType(Test).configureEach {
|
||||
// https://docs.gradle.org/current/userguide/performance.html#execute_tests_in_parallel
|
||||
maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1
|
||||
// https://docs.gradle.org/current/userguide/performance.html#fork_tests_into_multiple_processes
|
||||
forkEvery = 100
|
||||
// https://docs.gradle.org/current/userguide/performance.html#disable_reports
|
||||
reports.html.required = false
|
||||
reports.junitXml.required = false
|
||||
}
|
||||
// Speed up Java Compile Stage
|
||||
// https://docs.gradle.org/current/userguide/performance.html#run_the_compiler_as_a_separate_process
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
options.fork = true
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: "com.facebook.react.rootproject"
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
{
|
||||
"name": "keycardExit",
|
||||
"name": "KeycardExit",
|
||||
"version": "0.0.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "keycardExit",
|
||||
"name": "KeycardExit",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"react": "18.3.1",
|
||||
"react-native": "0.75.2"
|
||||
"react-native": "0.75.2",
|
||||
"react-native-modal": "^13.0.1",
|
||||
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#refs/tags/v2.5.39"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.0",
|
||||
|
@ -11344,7 +11346,6 @@
|
|||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
|
@ -11851,7 +11852,6 @@
|
|||
"version": "15.8.1",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.4.0",
|
||||
"object-assign": "^4.1.1",
|
||||
|
@ -11861,8 +11861,7 @@
|
|||
"node_modules/prop-types/node_modules/react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
},
|
||||
"node_modules/punycode": {
|
||||
"version": "2.3.1",
|
||||
|
@ -12018,6 +12017,32 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-animatable": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/react-native-animatable/-/react-native-animatable-1.3.3.tgz",
|
||||
"integrity": "sha512-2ckIxZQAsvWn25Ho+DK3d1mXIgj7tITkrS4pYDvx96WyOttSvzzFeQnM2od0+FUMzILbdHDsDEqZvnz1DYNQ1w==",
|
||||
"dependencies": {
|
||||
"prop-types": "^15.7.2"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-modal": {
|
||||
"version": "13.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-modal/-/react-native-modal-13.0.1.tgz",
|
||||
"integrity": "sha512-UB+mjmUtf+miaG/sDhOikRfBOv0gJdBU2ZE1HtFWp6UixW9jCk/bhGdHUgmZljbPpp0RaO/6YiMmQSSK3kkMaw==",
|
||||
"dependencies": {
|
||||
"prop-types": "^15.6.2",
|
||||
"react-native-animatable": "1.3.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-native": ">=0.65.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-status-keycard": {
|
||||
"version": "2.5.39",
|
||||
"resolved": "git+ssh://git@github.com/status-im/react-native-status-keycard.git#93dd64754e676172310e6ea7187cc49f2dc013c6",
|
||||
"license": "MPL 2.0"
|
||||
},
|
||||
"node_modules/react-native/node_modules/@jest/types": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "keycardExit",
|
||||
"name": "KeycardExit",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
@ -11,7 +11,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"react": "18.3.1",
|
||||
"react-native": "0.75.2"
|
||||
"react-native": "0.75.2",
|
||||
"react-native-modal": "^13.0.1",
|
||||
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#refs/tags/v2.5.39"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.0",
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { Platform, SafeAreaView, StyleSheet, useColorScheme, DeviceEventEmitter } from 'react-native';
|
||||
import { Colors } from 'react-native/Libraries/NewAppScreen';
|
||||
import StartScreen from './components/StartScreen';
|
||||
|
||||
//@ts-ignore
|
||||
import Keycard from "react-native-status-keycard";
|
||||
|
||||
const Main = () => {
|
||||
const isDarkMode = useColorScheme() === 'dark';
|
||||
const [isModalVisible, setIsModalVisible] = useState<boolean>(false);
|
||||
const didMount = useRef(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (!didMount.current) {
|
||||
didMount.current = true;
|
||||
DeviceEventEmitter.addListener("keyCardOnConnected", async () => {
|
||||
console.log(await Keycard.getApplicationInfo());
|
||||
setIsModalVisible(false);
|
||||
});
|
||||
DeviceEventEmitter.addListener("keyCardOnDisconnected", () => console.log("keycard disconnected"));
|
||||
DeviceEventEmitter.addListener("keyCardOnNFCEnabled", () => console.log("nfc enabled"));
|
||||
DeviceEventEmitter.addListener("keyCardOnNFCDisabled", () => console.log("nfc disabled"));
|
||||
}
|
||||
});
|
||||
|
||||
const backgroundStyle = {
|
||||
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
|
||||
};
|
||||
|
||||
const exitFunc = async () => {
|
||||
if (await Keycard.nfcIsSupported() && !await Keycard.nfcIsEnabled()) {
|
||||
await Keycard.openNfcSettings();
|
||||
}
|
||||
|
||||
await Keycard.startNFC("Tap your Keycard");
|
||||
|
||||
if (Platform.OS === 'android') {
|
||||
setIsModalVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<SafeAreaView style={[backgroundStyle, styles.container]}>
|
||||
<StartScreen onExitBtnFunc={exitFunc} isModalVisible={isModalVisible} modalVisibilityFunc={setIsModalVisible}></StartScreen>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
paddingTop: '30%',
|
||||
height: '100%',
|
||||
paddingLeft: '6%',
|
||||
paddingRight: '6%'
|
||||
},
|
||||
});
|
||||
|
||||
export default Main;
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
import React, {FC, useEffect, useState } from "react";
|
||||
import {StyleSheet, Text, View } from "react-native";
|
||||
import Modal from "react-native-modal/dist/modal";
|
||||
|
||||
type NFCModalProps = {
|
||||
isVisible: boolean;
|
||||
onChangeFunc: (val: boolean) => void;
|
||||
};
|
||||
|
||||
const NFCModal: FC<NFCModalProps> = props => {
|
||||
const {isVisible, onChangeFunc} = props;
|
||||
|
||||
return (
|
||||
<Modal isVisible={isVisible} onSwipeComplete={() => onChangeFunc(!isVisible)} swipeDirection={['up', 'left', 'right', 'down']} style={modalStyle.modalContainer}>
|
||||
<View style={modalStyle.container}>
|
||||
<Text style={modalStyle.header}>Ready to Scan</Text>
|
||||
<Text style={modalStyle.prompt}>Tap your Keycard</Text>
|
||||
</View>
|
||||
</Modal>
|
||||
)};
|
||||
|
||||
const modalStyle = StyleSheet.create({
|
||||
modalContainer: {
|
||||
justifyContent: 'flex-end',
|
||||
margin: 0
|
||||
},
|
||||
container: {
|
||||
backgroundColor: '#4A646C',
|
||||
height: 250,
|
||||
paddingBottom: 20,
|
||||
alignItems: 'center',
|
||||
borderTopLeftRadius: 10,
|
||||
borderTopRightRadius: 10,
|
||||
borderColor: 'rgba(0, 0, 0, 0.1)',
|
||||
},
|
||||
header: {
|
||||
paddingTop: '5%',
|
||||
fontSize: 24
|
||||
},
|
||||
prompt: {
|
||||
paddingTop: '10%',
|
||||
paddingBottom: '10%',
|
||||
fontSize: 15
|
||||
}
|
||||
});
|
||||
|
||||
export default NFCModal;
|
|
@ -0,0 +1,42 @@
|
|||
import {FC } from "react";
|
||||
import { DimensionValue, StyleSheet, Text, TouchableOpacity, View } from "react-native";
|
||||
|
||||
type ButtonProps = {
|
||||
label: string;
|
||||
disabled: boolean;
|
||||
btnColor: string;
|
||||
btnWidth: string;
|
||||
btnJustifyContent: string;
|
||||
onChangeFunc: () => void;
|
||||
};
|
||||
|
||||
const Button: FC<ButtonProps> = props => {
|
||||
const {label, disabled, btnColor, btnWidth, btnJustifyContent, onChangeFunc} = props;
|
||||
|
||||
return (
|
||||
<View style={[buttonStyle.textBtnContainer, {width: btnWidth as DimensionValue, justifyContent: btnJustifyContent as any}]}>
|
||||
<TouchableOpacity key={label} disabled={disabled} style={buttonStyle.button} onPress={onChangeFunc}>
|
||||
<Text style={[buttonStyle.title, {color: btnColor}]}>{label}</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
)};
|
||||
|
||||
const buttonStyle = StyleSheet.create({
|
||||
textBtnContainer: {
|
||||
flexDirection: 'row',
|
||||
textAlign: 'center',
|
||||
paddingTop: 25,
|
||||
paddingBottom: 15,
|
||||
justifyContent: 'flex-start'
|
||||
},
|
||||
button: {
|
||||
|
||||
},
|
||||
title: {
|
||||
fontSize: 15,
|
||||
textTransform: 'uppercase',
|
||||
|
||||
},
|
||||
});
|
||||
|
||||
export default Button;
|
|
@ -0,0 +1,34 @@
|
|||
import {FC } from "react";
|
||||
import { StyleSheet, Text, View } from "react-native";
|
||||
import NFCModal from "../NFCModal";
|
||||
import Button from "./Button";
|
||||
|
||||
type StartScreenProps = {
|
||||
onExitBtnFunc: () => void;
|
||||
isModalVisible: boolean;
|
||||
modalVisibilityFunc: (val: boolean) => void;
|
||||
};
|
||||
|
||||
const StartScreen: FC<StartScreenProps> = props => {
|
||||
const {onExitBtnFunc, isModalVisible, modalVisibilityFunc} = props;
|
||||
|
||||
return (
|
||||
<View>
|
||||
<View>
|
||||
<Text style={styles.heading}> We are recruiting Operators to be the founders of a new, self-sovereign world in cyberspace</Text>
|
||||
<Button label="Exit" disabled={false} btnColor="#4A646C" btnWidth="100%" onChangeFunc={onExitBtnFunc} btnJustifyContent='center'></Button>
|
||||
</View>
|
||||
<View>
|
||||
<NFCModal isVisible={isModalVisible} onChangeFunc={modalVisibilityFunc}></NFCModal>
|
||||
</View>
|
||||
</View>
|
||||
)};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
heading: {
|
||||
textAlign: 'center',
|
||||
fontSize: 16
|
||||
}
|
||||
});
|
||||
|
||||
export default StartScreen;
|
|
@ -1,3 +1,4 @@
|
|||
{
|
||||
"extends": "@react-native/typescript-config/tsconfig.json"
|
||||
"extends": "@react-native/typescript-config/tsconfig.json",
|
||||
"noImplicitAny": false
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue