From e65ade8ffeb53316918801d81ee7d1e771311feb Mon Sep 17 00:00:00 2001 From: Ksenia Lebedeva Date: Wed, 11 Sep 2024 19:07:54 +0200 Subject: [PATCH] initial import --- App.tsx | 119 +---------------------- android/app/src/main/AndroidManifest.xml | 5 + android/build.gradle | 32 ++++++ package-lock.json | 39 ++++++-- package.json | 8 +- src/Main.tsx | 60 ++++++++++++ src/NFCModal.tsx | 47 +++++++++ src/components/Button.tsx | 42 ++++++++ src/components/StartScreen.tsx | 34 +++++++ tsconfig.json | 3 +- 10 files changed, 264 insertions(+), 125 deletions(-) create mode 100644 src/Main.tsx create mode 100644 src/NFCModal.tsx create mode 100644 src/components/Button.tsx create mode 100644 src/components/StartScreen.tsx diff --git a/App.tsx b/App.tsx index 125fe1b..826fb6b 100644 --- a/App.tsx +++ b/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 ( - - - {title} - - - {children} - - +
); -} +}; -function App(): React.JSX.Element { - const isDarkMode = useColorScheme() === 'dark'; - - const backgroundStyle = { - backgroundColor: isDarkMode ? Colors.darker : Colors.lighter, - }; - - return ( - - - -
- -
- Edit App.tsx to change this - screen and then come back to see your edits. -
-
- -
-
- -
-
- Read the docs to discover what to do next: -
- -
- - - ); -} - -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; +export default App; \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index e189252..16ffca3 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,6 +1,11 @@ + + + =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", diff --git a/package.json b/package.json index c70f9da..b2b4b66 100644 --- a/package.json +++ b/package.json @@ -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", @@ -33,4 +35,4 @@ "engines": { "node": ">=18" } -} \ No newline at end of file +} diff --git a/src/Main.tsx b/src/Main.tsx new file mode 100644 index 0000000..4b6b599 --- /dev/null +++ b/src/Main.tsx @@ -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(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 ( + + + + ); +} + +const styles = StyleSheet.create({ + container: { + paddingTop: '30%', + height: '100%', + paddingLeft: '6%', + paddingRight: '6%' + }, +}); + +export default Main; + diff --git a/src/NFCModal.tsx b/src/NFCModal.tsx new file mode 100644 index 0000000..0c8bbe5 --- /dev/null +++ b/src/NFCModal.tsx @@ -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 = props => { + const {isVisible, onChangeFunc} = props; + + return ( + onChangeFunc(!isVisible)} swipeDirection={['up', 'left', 'right', 'down']} style={modalStyle.modalContainer}> + + Ready to Scan + Tap your Keycard + + + )}; + +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; \ No newline at end of file diff --git a/src/components/Button.tsx b/src/components/Button.tsx new file mode 100644 index 0000000..a75518d --- /dev/null +++ b/src/components/Button.tsx @@ -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 = props => { + const {label, disabled, btnColor, btnWidth, btnJustifyContent, onChangeFunc} = props; + + return ( + + + {label} + + + )}; + +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; \ No newline at end of file diff --git a/src/components/StartScreen.tsx b/src/components/StartScreen.tsx new file mode 100644 index 0000000..9fa6d1f --- /dev/null +++ b/src/components/StartScreen.tsx @@ -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 = props => { + const {onExitBtnFunc, isModalVisible, modalVisibilityFunc} = props; + + return ( + + + We are recruiting Operators to be the founders of a new, self-sovereign world in cyberspace + + + + + + + )}; + +const styles = StyleSheet.create({ + heading: { + textAlign: 'center', + fontSize: 16 + } +}); + +export default StartScreen; \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 304ab4e..a4f118d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,3 +1,4 @@ { - "extends": "@react-native/typescript-config/tsconfig.json" + "extends": "@react-native/typescript-config/tsconfig.json", + "noImplicitAny": false }