mirror of
https://github.com/selfxyz/self.git
synced 2026-01-10 23:27:56 -05:00
SEL-553: Show NFC Progress (#764)
* feat: add haptics * fix: BAC FAILED error event * update lock file --------- Co-authored-by: Justin Hernandez <transphorm@gmail.com>
This commit is contained in:
@@ -123,6 +123,21 @@ object Messages {
|
||||
const val COMPARING = "Comparing....."
|
||||
const val COMPLETED = "Scanning completed"
|
||||
const val RESET = ""
|
||||
const val PACE_STARTED = "PACE started"
|
||||
const val PACE_SUCCEEDED = "PACE succeeded"
|
||||
const val PACE_FAILED = "PACE failed"
|
||||
const val BAC_STARTED = "BAC started"
|
||||
const val BAC_SUCCEEDED = "BAC succeeded"
|
||||
const val BAC_FAILED = "BAC failed"
|
||||
const val READING_COM = "Reading COM....."
|
||||
const val READING_DG1 = "Reading DG1....."
|
||||
const val READING_DG1_SUCCEEDED = "Reading DG1 succeeded"
|
||||
const val READING_DG2 = "Reading DG2....."
|
||||
const val READING_DG2_SUCCEEDED = "Reading DG2 succeeded"
|
||||
const val READING_SOD = "Reading SOD....."
|
||||
const val READING_SOD_SUCCEEDED = "Reading SOD succeeded"
|
||||
const val READING_DG14 = "Reading DG14....."
|
||||
const val CHIP_AUTH_SUCCEEDED = "Chip authentication succeeded"
|
||||
}
|
||||
|
||||
class Response(json: String) : JSONObject(json) {
|
||||
@@ -323,6 +338,7 @@ class RNPassportReaderModule(private val reactContext: ReactApplicationContext)
|
||||
for (securityInfo: SecurityInfo in securityInfoCollection) {
|
||||
if (securityInfo is PACEInfo) {
|
||||
Log.e("MY_LOGS", "trying PACE...")
|
||||
eventMessageEmitter(Messages.PACE_STARTED)
|
||||
service.doPACE(
|
||||
authKey,
|
||||
securityInfo.objectIdentifier,
|
||||
@@ -331,10 +347,12 @@ class RNPassportReaderModule(private val reactContext: ReactApplicationContext)
|
||||
)
|
||||
Log.e("MY_LOGS", "PACE succeeded")
|
||||
paceSucceeded = true
|
||||
eventMessageEmitter(Messages.PACE_SUCCEEDED)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.w("MY_LOGS", e)
|
||||
eventMessageEmitter(Messages.PACE_FAILED)
|
||||
}
|
||||
Log.e("MY_LOGS", "Sending select applet command with paceSucceeded: ${paceSucceeded}") // this is false so PACE doesn't succeed
|
||||
service.sendSelectApplet(paceSucceeded)
|
||||
@@ -343,6 +361,8 @@ class RNPassportReaderModule(private val reactContext: ReactApplicationContext)
|
||||
var bacSucceeded = false
|
||||
var attempts = 0
|
||||
val maxAttempts = 3
|
||||
|
||||
eventMessageEmitter(Messages.BAC_STARTED)
|
||||
|
||||
while (!bacSucceeded && attempts < maxAttempts) {
|
||||
try {
|
||||
@@ -356,6 +376,7 @@ class RNPassportReaderModule(private val reactContext: ReactApplicationContext)
|
||||
|
||||
// Try to read EF_COM first
|
||||
try {
|
||||
eventMessageEmitter(Messages.READING_COM)
|
||||
service.getInputStream(PassportService.EF_COM).read()
|
||||
} catch (e: Exception) {
|
||||
// EF_COM failed, do BAC
|
||||
@@ -364,26 +385,28 @@ class RNPassportReaderModule(private val reactContext: ReactApplicationContext)
|
||||
|
||||
bacSucceeded = true
|
||||
Log.e("MY_LOGS", "BAC succeeded on attempt $attempts")
|
||||
|
||||
eventMessageEmitter(Messages.BAC_SUCCEEDED)
|
||||
} catch (e: Exception) {
|
||||
Log.e("MY_LOGS", "BAC attempt $attempts failed: ${e.message}")
|
||||
if (attempts == maxAttempts) {
|
||||
eventMessageEmitter(Messages.BAC_FAILED)
|
||||
throw e // Re-throw on final attempt
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eventMessageEmitter("Reading DG1.....")
|
||||
eventMessageEmitter(Messages.READING_DG1)
|
||||
val dg1In = service.getInputStream(PassportService.EF_DG1)
|
||||
dg1File = DG1File(dg1In)
|
||||
eventMessageEmitter(Messages.READING_DG1_SUCCEEDED)
|
||||
// eventMessageEmitter("Reading DG2.....")
|
||||
// val dg2In = service.getInputStream(PassportService.EF_DG2)
|
||||
// dg2File = DG2File(dg2In)
|
||||
eventMessageEmitter("Reading SOD.....")
|
||||
eventMessageEmitter(Messages.READING_SOD)
|
||||
val sodIn = service.getInputStream(PassportService.EF_SOD)
|
||||
sodFile = SODFile(sodIn)
|
||||
|
||||
eventMessageEmitter(Messages.READING_SOD_SUCCEEDED)
|
||||
// val gson = Gson()
|
||||
// Log.d(TAG, "============FIRST CONSOLE LOG=============")
|
||||
// Log.d(TAG, "dg1File: " + gson.toJson(dg1File))
|
||||
@@ -443,7 +466,7 @@ class RNPassportReaderModule(private val reactContext: ReactApplicationContext)
|
||||
|
||||
private fun doChipAuth(service: PassportService) {
|
||||
try {
|
||||
eventMessageEmitter("Reading DG14.....")
|
||||
eventMessageEmitter(Messages.READING_DG14)
|
||||
val dg14In = service.getInputStream(PassportService.EF_DG14)
|
||||
dg14Encoded = IOUtils.toByteArray(dg14In)
|
||||
val dg14InByte = ByteArrayInputStream(dg14Encoded)
|
||||
@@ -458,6 +481,7 @@ class RNPassportReaderModule(private val reactContext: ReactApplicationContext)
|
||||
securityInfo.subjectPublicKey,
|
||||
)
|
||||
chipAuthSucceeded = true
|
||||
eventMessageEmitter(Messages.CHIP_AUTH_SUCCEEDED)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
|
||||
@@ -27,7 +27,7 @@ target "Self" do
|
||||
config = use_native_modules!
|
||||
|
||||
use_frameworks!
|
||||
pod "NFCPassportReader", git: "https://github.com/seshanthS/NFCPassportReader", commit: "cd18444e6d7dbf5a665f8a5b4809c5c655a9114d"
|
||||
pod "NFCPassportReader", git: "https://github.com/seshanthS/NFCPassportReader", commit: "74098a5e29c23b3f5a58dc14a336556fa89c0ad6"
|
||||
|
||||
pod "QKMRZScanner"
|
||||
pod "lottie-ios"
|
||||
|
||||
@@ -1848,7 +1848,7 @@ DEPENDENCIES:
|
||||
- lottie-ios
|
||||
- lottie-react-native (from `../../node_modules/lottie-react-native`)
|
||||
- Mixpanel-swift (~> 5.0.0)
|
||||
- NFCPassportReader (from `https://github.com/seshanthS/NFCPassportReader`, commit `cd18444e6d7dbf5a665f8a5b4809c5c655a9114d`)
|
||||
- NFCPassportReader (from `https://github.com/seshanthS/NFCPassportReader`, commit `74098a5e29c23b3f5a58dc14a336556fa89c0ad6`)
|
||||
- QKMRZScanner
|
||||
- RCT-Folly (from `../../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
|
||||
- RCT-Folly/Fabric (from `../../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
|
||||
@@ -1978,7 +1978,7 @@ EXTERNAL SOURCES:
|
||||
lottie-react-native:
|
||||
:path: "../../node_modules/lottie-react-native"
|
||||
NFCPassportReader:
|
||||
:commit: cd18444e6d7dbf5a665f8a5b4809c5c655a9114d
|
||||
:commit: 74098a5e29c23b3f5a58dc14a336556fa89c0ad6
|
||||
:git: https://github.com/seshanthS/NFCPassportReader
|
||||
RCT-Folly:
|
||||
:podspec: "../../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec"
|
||||
@@ -2143,7 +2143,7 @@ EXTERNAL SOURCES:
|
||||
|
||||
CHECKOUT OPTIONS:
|
||||
NFCPassportReader:
|
||||
:commit: cd18444e6d7dbf5a665f8a5b4809c5c655a9114d
|
||||
:commit: 74098a5e29c23b3f5a58dc14a336556fa89c0ad6
|
||||
:git: https://github.com/seshanthS/NFCPassportReader
|
||||
SwiftQRScanner:
|
||||
:commit: c71ff91297640a944de4bca61434155c3f9b0979
|
||||
@@ -2264,6 +2264,6 @@ SPEC CHECKSUMS:
|
||||
SwiftyTesseract: 1f3d96668ae92dc2208d9842c8a59bea9fad2cbb
|
||||
Yoga: b05994d1933f507b0a28ceaa4fdb968dc18da178
|
||||
|
||||
PODFILE CHECKSUM: 9caf39dd17c6bf25ed459fdf269610aabdd595b5
|
||||
PODFILE CHECKSUM: 575af0f0872fa8a7ad99a695e9a9d96845ac15ea
|
||||
|
||||
COCOAPODS: 1.16.2
|
||||
|
||||
@@ -40,7 +40,12 @@ import useUserStore from '../../stores/userStore';
|
||||
import analytics from '../../utils/analytics';
|
||||
import { black, slate100, slate400, slate500, white } from '../../utils/colors';
|
||||
import { dinot } from '../../utils/fonts';
|
||||
import { buttonTap } from '../../utils/haptic';
|
||||
import {
|
||||
buttonTap,
|
||||
feedbackSuccess,
|
||||
feedbackUnsuccessful,
|
||||
impactLight,
|
||||
} from '../../utils/haptic';
|
||||
import { registerModalCallbacks } from '../../utils/modalCallbackRegistry';
|
||||
import { parseScanResponse, scan } from '../../utils/nfcScanner';
|
||||
|
||||
@@ -68,6 +73,7 @@ const PassportNFCScanScreen: React.FC<PassportNFCScanScreenProps> = ({}) => {
|
||||
const [isNfcEnabled, setIsNfcEnabled] = useState(true);
|
||||
const [isNfcSheetOpen, setIsNfcSheetOpen] = useState(false);
|
||||
const [dialogMessage, setDialogMessage] = useState('');
|
||||
const [nfcMessage, setNfcMessage] = useState<string | null>(null);
|
||||
|
||||
const animationRef = useRef<LottieView>(null);
|
||||
|
||||
@@ -288,7 +294,32 @@ const PassportNFCScanScreen: React.FC<PassportNFCScanScreenProps> = ({}) => {
|
||||
if (Platform.OS === 'android' && emitter) {
|
||||
const subscription = emitter.addListener(
|
||||
'NativeEvent',
|
||||
(event: string) => console.info(event),
|
||||
(event: string) => {
|
||||
console.info(event);
|
||||
setNfcMessage(event);
|
||||
// Haptic feedback mapping for completion/error only
|
||||
if (
|
||||
event === 'PACE succeeded' ||
|
||||
event === 'BAC succeeded' ||
|
||||
event === 'Chip authentication succeeded'
|
||||
) {
|
||||
feedbackSuccess(); // Major success
|
||||
} else if (
|
||||
event === 'Reading DG1 succeeded' ||
|
||||
event === 'Reading DG2 succeeded' ||
|
||||
event === 'Reading SOD succeeded' ||
|
||||
event === 'Reading COM succeeded'
|
||||
) {
|
||||
impactLight(); // Minor DG step
|
||||
} else if (
|
||||
event === 'BAC failed' ||
|
||||
event === 'PACE failed' ||
|
||||
event.toLowerCase().includes('failed') ||
|
||||
event.toLowerCase().includes('error')
|
||||
) {
|
||||
feedbackUnsuccessful(); // Error
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return () => {
|
||||
@@ -310,7 +341,7 @@ const PassportNFCScanScreen: React.FC<PassportNFCScanScreenProps> = ({}) => {
|
||||
animationRef.current?.play();
|
||||
}, 5000); // Pause 5 seconds before playing again
|
||||
}}
|
||||
source={passportVerifyAnimation}
|
||||
source={passportVerifyAnimation as any}
|
||||
style={styles.animation}
|
||||
cacheComposition={true}
|
||||
renderMode="HARDWARE"
|
||||
@@ -322,8 +353,14 @@ const PassportNFCScanScreen: React.FC<PassportNFCScanScreenProps> = ({}) => {
|
||||
<TextsContainer>
|
||||
<Title children="Ready to scan" />
|
||||
<BodyText textAlign="center">
|
||||
Hold your device near the NFC tag and stop moving when it
|
||||
vibrates.
|
||||
{nfcMessage && nfcMessage.trim().length > 0 ? (
|
||||
nfcMessage
|
||||
) : (
|
||||
<>
|
||||
Hold your device near the NFC tag and stop moving when it
|
||||
vibrates.
|
||||
</>
|
||||
)}
|
||||
</BodyText>
|
||||
</TextsContainer>
|
||||
<Image
|
||||
|
||||
Reference in New Issue
Block a user