Skip to content

Commit

Permalink
components: AndroidNfcModal
Browse files Browse the repository at this point in the history
  • Loading branch information
kaloudis committed Apr 13, 2023
1 parent a1e2eb2 commit 1e06488
Show file tree
Hide file tree
Showing 9 changed files with 257 additions and 88 deletions.
2 changes: 2 additions & 0 deletions App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Stores from './stores/Stores';
import Navigation from './Navigation';
import { AppContainer } from './components/layout/AppContainer';
import ExternalLinkModal from './components/Modals/ExternalLinkModal';
import AndroidNfcModal from './components/Modals/AndroidNfcModal';

export default class App extends React.PureComponent {
render() {
Expand All @@ -29,6 +30,7 @@ export default class App extends React.PureComponent {
<AppContainer>
<Navigation />
<ExternalLinkModal />
<AndroidNfcModal />
</AppContainer>
</Provider>
);
Expand Down
5 changes: 5 additions & 0 deletions assets/images/SVG/NFC.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
110 changes: 110 additions & 0 deletions components/Modals/AndroidNfcModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import React from 'react';
import { View, StyleSheet, Text } from 'react-native';
import { inject, observer } from 'mobx-react';

import Button from '../Button';
import ModalBox from '../ModalBox';

import ModalStore from '../../stores/ModalStore';

import { localeString } from '../../utils/LocaleUtils';

import NFC from '../../assets/images/SVG/NFC.svg';

interface AndroidNfcModalProps {
ModalStore: ModalStore;
}

@inject('ModalStore')
@observer
export default class AndroidNfcModal extends React.Component<
AndroidNfcModalProps,
{}
> {
render() {
const { ModalStore } = this.props;
const { showAndroidNfcModal, toggleAndroidNfcModal } = ModalStore;

return (
<ModalBox
isOpen={showAndroidNfcModal}
style={{
backgroundColor: 'transparent',
paddingLeft: 24,
paddingRight: 24,
height: 380
}}
swipeToClose={false}
backButtonClose={false}
backdropPressToClose={false}
position="bottom"
ref="modal"
>
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
marginTop: 22
}}
>
<View
style={{
backgroundColor: 'white',
borderRadius: 30,
padding: 35,
alignItems: 'center',
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2
}
}}
>
<Text
style={{
fontSize: 30,
fontWeight: 'bold',
color: 'darkgrey',
marginBottom: 30
}}
>
{localeString('components.AndroidNfcModal.ready')}
</Text>
<NFC />
<Text
style={{
fontSize: 18,
color: 'black',
marginTop: 30,
marginBottom: 30,
textAlign: 'center'
}}
>
{localeString('components.AndroidNfcModal.hold')}
</Text>
<View style={styles.buttons}>
<View style={styles.button}>
<Button
title={localeString('general.cancel')}
onPress={() => toggleAndroidNfcModal(false)}
quaternary
></Button>
</View>
</View>
</View>
</View>
</ModalBox>
);
}
}

const styles = StyleSheet.create({
buttons: {
width: '100%'
},
button: {
marginBottom: 20,
width: 350
}
});
16 changes: 12 additions & 4 deletions components/Modals/ExternalLinkModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ export default class ExternalLinkModal extends React.Component<
color: 'black'
}}
>
{localeString('components.Modal.externalLink')}
{localeString(
'components.ExternalLinkModal.externalLink'
)}
</Text>
<Text
style={{
Expand All @@ -87,7 +89,9 @@ export default class ExternalLinkModal extends React.Component<
textAlign: 'center'
}}
>
{localeString('components.Modal.proceed')}
{localeString(
'components.ExternalLinkModal.proceed'
)}
</Text>
<TouchableOpacity
style={{
Expand All @@ -109,7 +113,9 @@ export default class ExternalLinkModal extends React.Component<
color: themeColor('text')
}}
>
{localeString('components.Modal.copyLink')}
{localeString(
'components.ExternalLinkModal.copyLink'
)}
</Text>
<Text
style={{
Expand Down Expand Up @@ -145,7 +151,9 @@ export default class ExternalLinkModal extends React.Component<
<View style={styles.button}>
<Button
title={localeString('general.cancel')}
onPress={toggleExternalLinkModal(false)}
onPress={() =>
toggleExternalLinkModal(false)
}
></Button>
</View>
</View>
Expand Down
8 changes: 5 additions & 3 deletions locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,11 @@
"components.QRCodeScanner.cameraPermissionTitle": "Permission to use camera",
"components.QRCodeScanner.cameraPermission": "We need your permission to use your camera",
"components.QRCodeScanner.noCameraAccess": "No access to camera",
"components.Modal.externalLink": "You're about to leave Zeus",
"components.Modal.proceed": "Proceed to the following URL?",
"components.Modal.copyLink": "Copy Link",
"components.ExternalLinkModal.externalLink": "You're about to leave Zeus",
"components.ExternalLinkModal.proceed": "Proceed to the following URL?",
"components.ExternalLinkModal.copyLink": "Copy Link",
"components.AndroidNfcModal.ready": "Ready to scan",
"components.AndroidNfcModal.hold": "Hold your Android phone near an NFC tag to read it",
"models.Channel.unknownId": "Unknown Channel ID",
"models.Invoice.noMemo": "No memo",
"models.Invoice.seconds": "seconds",
Expand Down
2 changes: 1 addition & 1 deletion utils/UrlUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const goToBlockExplorerBlockHash = (hash: string, testnet: boolean) =>
const goToUrl = (url: string) => {
stores.modalStore.setUrl(url);
stores.modalStore.setClipboardValue(url);
stores.modalStore.toggleModal(true);
stores.modalStore.toggleExternalLinkModal(true);
stores.modalStore.setAction(() => leaveZeus(url));
};

Expand Down
79 changes: 50 additions & 29 deletions views/OpenChannel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
} from 'react-native';
import Clipboard from '@react-native-clipboard/clipboard';
import { inject, observer } from 'mobx-react';
import NfcManager, { NfcEvents } from 'react-native-nfc-manager';
import NfcManager, { NfcEvents, TagEvent } from 'react-native-nfc-manager';

import Amount from './../components/Amount';
import AmountInput from './../components/AmountInput';
Expand All @@ -35,6 +35,7 @@ import { themeColor } from '../utils/ThemeUtils';

import BalanceStore from './../stores/BalanceStore';
import ChannelsStore from './../stores/ChannelsStore';
import ModalStore from './../stores/ModalStore';
import SettingsStore from './../stores/SettingsStore';
import UTXOsStore from './../stores/UTXOsStore';

Expand All @@ -43,8 +44,9 @@ import Scan from '../assets/images/SVG/Scan.svg';
interface OpenChannelProps {
exitSetup: any;
navigation: any;
ChannelsStore: ChannelsStore;
BalanceStore: BalanceStore;
ChannelsStore: ChannelsStore;
ModalStore: ModalStore;
SettingsStore: SettingsStore;
UTXOsStore: UTXOsStore;
}
Expand All @@ -64,7 +66,13 @@ interface OpenChannelState {
utxoBalance: number;
}

@inject('ChannelsStore', 'SettingsStore', 'BalanceStore', 'UTXOsStore')
@inject(
'BalanceStore',
'ChannelsStore',
'ModalStore',
'SettingsStore',
'UTXOsStore'
)
@observer
export default class OpenChannel extends React.Component<
OpenChannelProps,
Expand Down Expand Up @@ -107,10 +115,6 @@ export default class OpenChannel extends React.Component<

async componentDidMount() {
this.initFromProps(this.props);

if (Platform.OS === 'android') {
await this.enableNfc();
}
}

disableNfc = () => {
Expand All @@ -119,21 +123,40 @@ export default class OpenChannel extends React.Component<
};

enableNfc = async () => {
const { ModalStore } = this.props;
this.disableNfc();
await NfcManager.start();

return new Promise((resolve: any) => {
let tagFound = null;

NfcManager.setEventListener(NfcEvents.DiscoverTag, (tag: any) => {
tagFound = tag;
const bytes = new Uint8Array(tagFound.ndefMessage[0].payload);
const str = NFCUtils.nfcUtf8ArrayToStr(bytes);
resolve(this.validateNodeUri(str));
NfcManager.unregisterTagEvent().catch(() => 0);
});
let tagFound: TagEvent | null = null;

// enable NFC
if (Platform.OS === 'android')
ModalStore.toggleAndroidNfcModal(true);

NfcManager.setEventListener(
NfcEvents.DiscoverTag,
(tag: TagEvent) => {
tagFound = tag;
const bytes = new Uint8Array(
tagFound.ndefMessage[0].payload
);
const str = NFCUtils.nfcUtf8ArrayToStr(bytes) || '';

// close NFC
if (Platform.OS === 'android')
ModalStore.toggleAndroidNfcModal(false);

resolve(this.validateNodeUri(str));
NfcManager.unregisterTagEvent().catch(() => 0);
}
);

NfcManager.setEventListener(NfcEvents.SessionClosed, () => {
// close NFC
if (Platform.OS === 'android')
ModalStore.toggleAndroidNfcModal(false);

if (!tagFound) {
resolve();
}
Expand Down Expand Up @@ -541,19 +564,17 @@ export default class OpenChannel extends React.Component<
/>
</View>

{Platform.OS === 'ios' && (
<View style={styles.button}>
<Button
title={localeString('general.enableNfc')}
icon={{
name: 'nfc',
size: 25
}}
onPress={() => this.enableNfc()}
secondary
/>
</View>
)}
<View style={styles.button}>
<Button
title={localeString('general.enableNfc')}
icon={{
name: 'nfc',
size: 25
}}
onPress={() => this.enableNfc()}
secondary
/>
</View>
</View>
</ScrollView>
</Screen>
Expand Down
Loading

0 comments on commit 1e06488

Please sign in to comment.