mirror of
https://github.com/selfxyz/self.git
synced 2026-01-09 14:48:06 -05:00
Working demo app mrz scan screen (#1232)
* Add camera permission to demo manifest * save wip * save buidling wip * enable camera * working mrz scan * cr feedback
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="5dp" />
|
||||
<solid android:color="@android:color/transparent" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="@color/grey_2" />
|
||||
</shape>
|
||||
@@ -0,0 +1,20 @@
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_checked="true">
|
||||
<shape>
|
||||
<corners
|
||||
android:topLeftRadius="5dp"
|
||||
android:bottomLeftRadius="5dp" />
|
||||
<solid android:color="@color/blue_light"></solid>
|
||||
</shape>
|
||||
</item>
|
||||
<item android:state_pressed="true">
|
||||
<shape>
|
||||
<solid android:color="@color/white"></solid>
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<solid android:color="@android:color/transparent"></solid>
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
||||
@@ -0,0 +1,20 @@
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_checked="true">
|
||||
<shape>
|
||||
<corners
|
||||
android:topRightRadius="5dp"
|
||||
android:bottomRightRadius="5dp" />
|
||||
<solid android:color="@color/blue_light"></solid>
|
||||
</shape>
|
||||
</item>
|
||||
<item android:state_pressed="true">
|
||||
<shape>
|
||||
<solid android:color="@color/white"></solid>
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<solid android:color="@android:color/transparent"></solid>
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
||||
18
packages/mobile-sdk-alpha/android/src/main/res/font/bold.xml
Normal file
18
packages/mobile-sdk-alpha/android/src/main/res/font/bold.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<font-family xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<font
|
||||
android:fontStyle="normal"
|
||||
android:fontWeight="700"
|
||||
android:font="@font/roboto_bold"
|
||||
app:fontStyle="normal"
|
||||
app:fontWeight="700"
|
||||
app:font="@font/roboto_bold" />
|
||||
<font
|
||||
android:fontStyle="italic"
|
||||
android:fontWeight="700"
|
||||
android:font="@font/roboto_bold_italic"
|
||||
app:fontStyle="italic"
|
||||
app:fontWeight="700"
|
||||
app:font="@font/roboto_bold_italic" />
|
||||
</font-family>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<font-family xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<font
|
||||
android:fontStyle="normal"
|
||||
android:fontWeight="500"
|
||||
android:font="@font/roboto_medium"
|
||||
app:fontStyle="normal"
|
||||
app:fontWeight="500"
|
||||
app:font="@font/roboto_medium" />
|
||||
<font
|
||||
android:fontStyle="italic"
|
||||
android:fontWeight="500"
|
||||
android:font="@font/roboto_medium_italic"
|
||||
app:fontStyle="italic"
|
||||
app:fontWeight="500"
|
||||
app:font="@font/roboto_medium_italic" />
|
||||
</font-family>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<font-family xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<font
|
||||
android:fontStyle="normal"
|
||||
android:fontWeight="400"
|
||||
android:font="@font/roboto_regular"
|
||||
app:fontStyle="normal"
|
||||
app:fontWeight="400"
|
||||
app:font="@font/roboto_regular" />
|
||||
<font
|
||||
android:fontStyle="italic"
|
||||
android:fontWeight="400"
|
||||
android:font="@font/roboto_italic"
|
||||
app:fontStyle="italic"
|
||||
app:fontWeight="400"
|
||||
app:font="@font/roboto_italic" />
|
||||
</font-family>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -14,7 +14,11 @@ module.exports = {
|
||||
ios: {
|
||||
podspecPath: path.join(packageRoot, 'mobile-sdk-alpha.podspec'),
|
||||
},
|
||||
android: null,
|
||||
android: {
|
||||
sourceDir: path.join(packageRoot, 'android'),
|
||||
packageImportPath: 'import com.selfxyz.selfSDK.RNSelfPassportReaderPackage;',
|
||||
packageInstance: 'new RNSelfPassportReaderPackage()',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -125,7 +125,7 @@ export const MRZScannerView: React.FC<MRZScannerViewProps> = ({
|
||||
<View style={containerStyle}>
|
||||
<RCTFragment
|
||||
RCTFragmentViewManager={NativeMRZScannerView as any}
|
||||
fragmentComponentName="PassportOCRViewManager"
|
||||
fragmentComponentName="SelfOCRViewManager"
|
||||
isMounted={true}
|
||||
style={{
|
||||
height: PixelRatio.getPixelSizeForLayoutSize(800),
|
||||
|
||||
@@ -42,6 +42,12 @@ android {
|
||||
buildFeatures {
|
||||
buildConfig true
|
||||
}
|
||||
|
||||
packaging {
|
||||
resources {
|
||||
excludes += ['META-INF/versions/9/OSGI-INF/MANIFEST.MF']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
apply from: file("../../node_modules/react-native-vector-icons/fonts.gradle")
|
||||
@@ -52,4 +58,8 @@ dependencies {
|
||||
if (project.hasProperty('newArchEnabled') ? newArchEnabled.toBoolean() : false) {
|
||||
implementation("com.facebook.react:react-android-codegen:0.76.9")
|
||||
}
|
||||
|
||||
// Manually add mobile-sdk-alpha dependency
|
||||
implementation project(':mobile-sdk-alpha')
|
||||
implementation 'com.google.android.material:material:1.12.0'
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
|
||||
<application
|
||||
android:name=".MainApplication"
|
||||
|
||||
@@ -9,14 +9,16 @@ import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
|
||||
import com.facebook.react.defaults.DefaultReactNativeHost
|
||||
import com.facebook.soloader.SoLoader
|
||||
import com.facebook.react.soloader.OpenSourceMergedSoMapping
|
||||
import com.selfxyz.selfSDK.RNSelfPassportReaderPackage
|
||||
|
||||
class MainApplication : Application(), ReactApplication {
|
||||
|
||||
private val mReactNativeHost: ReactNativeHost = object : DefaultReactNativeHost(this) {
|
||||
override fun getPackages(): List<ReactPackage> {
|
||||
// Packages that cannot be autolinked yet can be added manually here, for example:
|
||||
// packages.add(new MyReactNativePackage());
|
||||
return PackageList(this).packages
|
||||
val packages = PackageList(this).packages.toMutableList()
|
||||
// Manually add the SelfSDK package
|
||||
packages.add(RNSelfPassportReaderPackage())
|
||||
return packages
|
||||
}
|
||||
|
||||
override fun getJSMainModuleName(): String {
|
||||
|
||||
@@ -5,4 +5,6 @@ extensions.configure(com.facebook.react.ReactSettingsExtension){ ex ->
|
||||
}
|
||||
rootProject.name = 'SelfDemoApp'
|
||||
include ':app'
|
||||
include ':mobile-sdk-alpha'
|
||||
project(':mobile-sdk-alpha').projectDir = new File(rootProject.projectDir, '../../mobile-sdk-alpha/android')
|
||||
includeBuild('../../../node_modules/@react-native/gradle-plugin')
|
||||
|
||||
@@ -76,23 +76,19 @@ export default function DocumentCamera({ onBack }: Props) {
|
||||
onBack();
|
||||
}}
|
||||
contentStyle={styles.screenContent}
|
||||
rightAction={
|
||||
<TouchableOpacity accessibilityRole="button" onPress={handleSaveDocument}>
|
||||
<Text style={styles.headerAction}>Save Document</Text>
|
||||
</TouchableOpacity>
|
||||
}
|
||||
>
|
||||
{permissionStatus === 'loading' && renderLoading()}
|
||||
{permissionStatus === 'denied' && renderPermissionDenied()}
|
||||
|
||||
{permissionStatus === 'granted' && (
|
||||
<View style={styles.contentWrapper}>
|
||||
<View style={styles.instructionsContainer}>
|
||||
<Text style={styles.instructionsTitle}>Position your document</Text>
|
||||
<Text style={styles.instructionsText}>{instructionsText}</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.cameraWrapper}>
|
||||
<MRZScannerView style={styles.scanner} onMRZDetected={handleMRZDetected} onError={handleScannerError} />
|
||||
<View style={styles.overlay} accessibilityLiveRegion="polite" pointerEvents="none">
|
||||
<Text style={styles.overlayTitle}>Position your document</Text>
|
||||
<Text style={styles.overlayText}>{instructionsText}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={styles.statusContainer}>
|
||||
@@ -110,9 +106,7 @@ export default function DocumentCamera({ onBack }: Props) {
|
||||
{scanState === 'error' && error && <Text style={[styles.statusText, styles.errorText]}>{error}</Text>}
|
||||
</View>
|
||||
|
||||
{mrzResult && <DocumentScanResultCard result={mrzResult} />}
|
||||
|
||||
<View style={styles.actions}>
|
||||
<View style={[styles.actions, mrzResult && styles.actionsWithResult]}>
|
||||
<TouchableOpacity accessibilityRole="button" onPress={handleScanAgain} style={styles.secondaryButton}>
|
||||
<Text style={styles.secondaryButtonText}>Scan Again</Text>
|
||||
</TouchableOpacity>
|
||||
@@ -121,6 +115,8 @@ export default function DocumentCamera({ onBack }: Props) {
|
||||
<Text style={styles.primaryButtonText}>Save Document</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{mrzResult && <DocumentScanResultCard result={mrzResult} />}
|
||||
</View>
|
||||
)}
|
||||
</ScreenLayout>
|
||||
@@ -134,6 +130,20 @@ const styles = StyleSheet.create({
|
||||
contentWrapper: {
|
||||
flex: 1,
|
||||
},
|
||||
instructionsContainer: {
|
||||
marginBottom: 16,
|
||||
},
|
||||
instructionsTitle: {
|
||||
color: '#0f172a',
|
||||
fontWeight: '600',
|
||||
fontSize: 16,
|
||||
marginBottom: 4,
|
||||
},
|
||||
instructionsText: {
|
||||
color: '#475569',
|
||||
fontSize: 14,
|
||||
lineHeight: 20,
|
||||
},
|
||||
cameraWrapper: {
|
||||
backgroundColor: '#0f172a',
|
||||
borderRadius: 16,
|
||||
@@ -147,31 +157,14 @@ const styles = StyleSheet.create({
|
||||
height: '100%',
|
||||
backgroundColor: '#0f172a',
|
||||
},
|
||||
overlay: {
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
backgroundColor: 'rgba(15, 23, 42, 0.75)',
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 12,
|
||||
},
|
||||
overlayTitle: {
|
||||
color: '#f8fafc',
|
||||
fontWeight: '600',
|
||||
fontSize: 16,
|
||||
marginBottom: 4,
|
||||
},
|
||||
overlayText: {
|
||||
color: '#e2e8f0',
|
||||
fontSize: 14,
|
||||
},
|
||||
statusContainer: {
|
||||
marginBottom: 16,
|
||||
alignItems: 'center',
|
||||
},
|
||||
statusRow: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: 8,
|
||||
},
|
||||
statusText: {
|
||||
@@ -191,6 +184,9 @@ const styles = StyleSheet.create({
|
||||
flexDirection: 'row',
|
||||
gap: 12,
|
||||
},
|
||||
actionsWithResult: {
|
||||
marginBottom: 16,
|
||||
},
|
||||
primaryButton: {
|
||||
flex: 1,
|
||||
backgroundColor: '#0f172a',
|
||||
@@ -215,10 +211,6 @@ const styles = StyleSheet.create({
|
||||
fontSize: 15,
|
||||
fontWeight: '600',
|
||||
},
|
||||
headerAction: {
|
||||
color: '#2563eb',
|
||||
fontWeight: '600',
|
||||
},
|
||||
centeredState: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
|
||||
Reference in New Issue
Block a user