mirror of
https://github.com/selfxyz/self.git
synced 2026-04-27 03:01:15 -04:00
improve NFC reading UX on android #130
This commit is contained in:
@@ -114,6 +114,15 @@ import com.facebook.react.modules.core.DeviceEventManagerModule
|
||||
import com.facebook.react.bridge.LifecycleEventListener
|
||||
import com.facebook.react.bridge.Callback
|
||||
|
||||
object Messages {
|
||||
const val SCANNING = "Scanning....."
|
||||
const val STOP_MOVING = "Stop moving....."
|
||||
const val AUTH = "Auth....."
|
||||
const val COMPARING = "Comparing....."
|
||||
const val COMPLETED = "Scanning completed"
|
||||
const val RESET = ""
|
||||
}
|
||||
|
||||
class Response(json: String) : JSONObject(json) {
|
||||
val type: String? = this.optString("type")
|
||||
val data = this.optJSONArray("data")
|
||||
@@ -171,6 +180,7 @@ class RNPassportReaderModule(private val reactContext: ReactApplicationContext)
|
||||
|
||||
@ReactMethod
|
||||
fun scan(opts: ReadableMap, promise: Promise) {
|
||||
eventMessageEmitter(Messages.SCANNING)
|
||||
val mNfcAdapter = NfcAdapter.getDefaultAdapter(reactApplicationContext)
|
||||
// val mNfcAdapter = NfcAdapter.getDefaultAdapter(this.reactContext)
|
||||
if (mNfcAdapter == null) {
|
||||
@@ -261,6 +271,7 @@ class RNPassportReaderModule(private val reactContext: ReactApplicationContext)
|
||||
|
||||
override fun doInBackground(vararg params: Void?): Exception? {
|
||||
try {
|
||||
eventMessageEmitter(Messages.STOP_MOVING)
|
||||
isoDep.timeout = 10000
|
||||
Log.e("MY_LOGS", "This should obvsly log")
|
||||
val cardService = CardService.getInstance(isoDep)
|
||||
@@ -349,7 +360,7 @@ class RNPassportReaderModule(private val reactContext: ReactApplicationContext)
|
||||
// e.printStackTrace()
|
||||
// }
|
||||
// Log.d(TAG, "============LET'S VERIFY THE SIGNATURE=============")
|
||||
|
||||
eventMessageEmitter(Messages.AUTH)
|
||||
doChipAuth(service)
|
||||
doPassiveAuth()
|
||||
|
||||
@@ -372,6 +383,7 @@ class RNPassportReaderModule(private val reactContext: ReactApplicationContext)
|
||||
imageBase64 = Base64.encodeToString(buffer, Base64.DEFAULT)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
eventMessageEmitter(Messages.RESET)
|
||||
return e
|
||||
}
|
||||
return null
|
||||
@@ -409,8 +421,11 @@ class RNPassportReaderModule(private val reactContext: ReactApplicationContext)
|
||||
|
||||
val dataHashes = sodFile.dataGroupHashes
|
||||
|
||||
eventMessageEmitter("Reading DG14.....")
|
||||
val dg14Hash = if (chipAuthSucceeded) digest.digest(dg14Encoded) else ByteArray(0)
|
||||
eventMessageEmitter("Reading DG1.....")
|
||||
val dg1Hash = digest.digest(dg1File.encoded)
|
||||
eventMessageEmitter("Reading DG2.....")
|
||||
val dg2Hash = digest.digest(dg2File.encoded)
|
||||
|
||||
// val gson = Gson()
|
||||
@@ -432,7 +447,7 @@ class RNPassportReaderModule(private val reactContext: ReactApplicationContext)
|
||||
// Log.d(TAG, "dg2HashjoinToString " + gson.toJson(dg2Hash.joinToString("") { "%02x".format(it) }))
|
||||
|
||||
Log.d(TAG, "Comparing data group hashes...")
|
||||
|
||||
eventMessageEmitter(Messages.COMPARING)
|
||||
if (Arrays.equals(dg1Hash, dataHashes[1]) && Arrays.equals(dg2Hash, dataHashes[2])
|
||||
&& (!chipAuthSucceeded || Arrays.equals(dg14Hash, dataHashes[14]))) {
|
||||
|
||||
@@ -498,6 +513,7 @@ class RNPassportReaderModule(private val reactContext: ReactApplicationContext)
|
||||
Log.d(TAG, "Passive authentication success: $passiveAuthSuccess")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
eventMessageEmitter(Messages.RESET)
|
||||
Log.w(TAG, "Exception in passive authentication", e)
|
||||
}
|
||||
}
|
||||
@@ -538,6 +554,7 @@ class RNPassportReaderModule(private val reactContext: ReactApplicationContext)
|
||||
val certificateBytes = certificate.encoded
|
||||
val certificateBase64 = Base64.encodeToString(certificateBytes, Base64.DEFAULT)
|
||||
Log.d(TAG, "certificateBase64: ${certificateBase64}")
|
||||
|
||||
|
||||
passport.putString("documentSigningCertificate", certificateBase64)
|
||||
|
||||
@@ -609,7 +626,9 @@ class RNPassportReaderModule(private val reactContext: ReactApplicationContext)
|
||||
passport.putMap("photo", photo)
|
||||
// passport.putString("dg2File", gson.toJson(dg2File))
|
||||
|
||||
eventMessageEmitter(Messages.COMPLETED)
|
||||
scanPromise?.resolve(passport)
|
||||
eventMessageEmitter(Messages.RESET)
|
||||
resetState()
|
||||
}
|
||||
}
|
||||
@@ -626,6 +645,16 @@ class RNPassportReaderModule(private val reactContext: ReactApplicationContext)
|
||||
}
|
||||
}
|
||||
|
||||
private fun eventMessageEmitter(message: String) {
|
||||
if (reactContext.hasActiveCatalystInstance()) {
|
||||
reactContext
|
||||
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
||||
.emit("NativeEvent", message)
|
||||
} else {
|
||||
Log.d(TAG, "Error")
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = RNPassportReaderModule::class.java.simpleName
|
||||
private const val PARAM_DOC_NUM = "documentNumber";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { YStack, XStack, Text, Button, Tabs, Sheet, Label, Fieldset, Input, Switch, H2, Image, useWindowDimensions, H4, H3 } from 'tamagui'
|
||||
import { YStack, XStack, Text, Button, Tabs, Sheet, Label, Fieldset, Input, Switch, H2, Image, useWindowDimensions, H4, H3, View } from 'tamagui'
|
||||
import { HelpCircle, IterationCw, VenetianMask, Cog, CheckCircle2, ChevronLeft, Share, Eraser } from '@tamagui/lucide-icons';
|
||||
import X from '../images/x.png'
|
||||
import Telegram from '../images/telegram.png'
|
||||
@@ -8,7 +8,7 @@ import Internet from "../images/internet.png"
|
||||
import ProveScreen from './ProveScreen';
|
||||
import { Steps } from '../utils/utils';
|
||||
import AppScreen from './AppScreen';
|
||||
import { Linking, Modal, Platform, Pressable } from 'react-native';
|
||||
import { NativeEventEmitter, NativeModules, Linking, Modal, Platform, Pressable } from 'react-native';
|
||||
import NFC_IMAGE from '../images/nfc.png'
|
||||
import { bgColor, blueColorLight, borderColor, componentBgColor, textColor1, textColor2 } from '../utils/colors';
|
||||
import SendProofScreen from './SendProofScreen';
|
||||
@@ -26,9 +26,12 @@ import Dialog from "react-native-dialog";
|
||||
import { contribute } from '../utils/contribute';
|
||||
import RegisterScreen from './RegisterScreen';
|
||||
|
||||
const { nativeModule } = NativeModules;
|
||||
const emitter = new NativeEventEmitter(nativeModule);
|
||||
|
||||
const MainScreen: React.FC = () => {
|
||||
const [NFCScanIsOpen, setNFCScanIsOpen] = useState(false);
|
||||
const [scanningMessage, setScanningMessage] = useState('');
|
||||
const [displayOtherOptions, setDisplayOtherOptions] = useState(false);
|
||||
const [SettingsIsOpen, setSettingsIsOpen] = useState(false);
|
||||
const [DialogContributeIsOpen, setDialogContributeIsOpen] = useState(false);
|
||||
@@ -123,6 +126,18 @@ const MainScreen: React.FC = () => {
|
||||
setDialogDeleteSecretIsOpen(false);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const handleNativeEvent = (event: string) => {
|
||||
setScanningMessage(event);
|
||||
};
|
||||
|
||||
const subscription = emitter.addListener('NativeEvent', handleNativeEvent);
|
||||
|
||||
return () => {
|
||||
subscription.remove();
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (passportNumber?.length === 9 && (dateOfBirth?.length === 6 && dateOfExpiry?.length === 6)) {
|
||||
setStep(Steps.MRZ_SCAN_COMPLETED);
|
||||
@@ -207,8 +222,13 @@ const MainScreen: React.FC = () => {
|
||||
<Sheet open={NFCScanIsOpen} onOpenChange={setNFCScanIsOpen} dismissOnSnapToBottom modal dismissOnOverlayPress={false} disableDrag animation="medium" snapPoints={[35]}>
|
||||
<Sheet.Overlay />
|
||||
<Sheet.Frame>
|
||||
|
||||
<YStack gap="$5" f={1} pt="$3">
|
||||
<H2 textAlign='center'>Ready to scan</H2>
|
||||
<View>
|
||||
<H2 textAlign='center'>Ready to scan</H2>
|
||||
<Text textAlign='center'>{scanningMessage}</Text>
|
||||
</View>
|
||||
|
||||
{step >= Steps.NEXT_SCREEN ?
|
||||
<CheckCircle2
|
||||
size="$8"
|
||||
|
||||
@@ -213,7 +213,7 @@ const handleResponseAndroid = async (
|
||||
encapContent,
|
||||
documentSigningCertificate
|
||||
} = response;
|
||||
|
||||
|
||||
amplitude.track('Sig alg before conversion: ' + signatureAlgorithm);
|
||||
|
||||
const pem = "-----BEGIN CERTIFICATE-----" + documentSigningCertificate + "-----END CERTIFICATE-----"
|
||||
|
||||
Reference in New Issue
Block a user