diff --git a/android/src/main/java/com/reactlibrary/RNReactNativeZoomSdkModule.java b/android/src/main/java/com/reactlibrary/RNReactNativeZoomSdkModule.java index ff59bc8..604b0df 100644 --- a/android/src/main/java/com/reactlibrary/RNReactNativeZoomSdkModule.java +++ b/android/src/main/java/com/reactlibrary/RNReactNativeZoomSdkModule.java @@ -1,9 +1,9 @@ package com.reactlibrary; import android.app.Activity; -import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; +import android.graphics.Color; import android.net.Uri; import android.os.AsyncTask; import android.support.annotation.NonNull; @@ -17,15 +17,18 @@ import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.WritableArray; import com.facebook.react.bridge.WritableMap; import com.facetec.zoom.sdk.ZoomAuditTrailType; import com.facetec.zoom.sdk.ZoomCustomization; +import com.facetec.zoom.sdk.ZoomFeedbackCustomization; import com.facetec.zoom.sdk.ZoomFrameCustomization; import com.facetec.zoom.sdk.ZoomDevicePartialLivenessResult; import com.facetec.zoom.sdk.ZoomExternalImageSetVerificationResult; import com.facetec.zoom.sdk.ZoomFaceBiometricMetrics; +import com.facetec.zoom.sdk.ZoomOvalCustomization; import com.facetec.zoom.sdk.ZoomSDK; import com.facetec.zoom.sdk.ZoomSDKStatus; import com.facetec.zoom.sdk.ZoomVerificationActivity; @@ -104,7 +107,6 @@ public void initialize(final ReadableMap opts, final Promise promise) { final String appToken = opts.getString("appToken"); final String facemapEncryptionKey = opts.getString("facemapEncryptionKey"); - AsyncTask.execute(new Runnable() { @Override public void run() { @@ -115,10 +117,16 @@ public void run() { currentCustomization.showRetryScreen= opts.getBoolean("showRetryScreen"); currentCustomization.enableLowLightMode = opts.getBoolean("enableLowLightMode"); - ZoomFrameCustomization frameCustomization = new ZoomFrameCustomization(); - frameCustomization.topMargin = opts.getInt("topMargin"); - frameCustomization.sizeRatio = (float)opts.getDouble("sizeRatio"); - currentCustomization.setFrameCustomization(frameCustomization); + if (opts.hasKey("mainBackgroundColors")) { + ReadableArray mainBackgroundColors = opts.getArray("mainBackgroundColors"); + // This attribute contains array of 2 colors for gradient, but it seems like Java API + // doesn't allow to set gradient, so we take just the first. + currentCustomization.mainBackgroundColor = Color.parseColor(mainBackgroundColors.getString(0)); + } + + addFrameCustomizations(currentCustomization, opts); + addFeedbackCustomizations(currentCustomization, opts); + addOvalCustomizations(currentCustomization, opts); ZoomSDK.setCustomization(currentCustomization); ZoomSDK.initialize(getCurrentActivity(), appToken, new ZoomSDK.InitializeCallback() { @@ -142,6 +150,59 @@ public void onCompletion(boolean successful) { }); } + private void addFrameCustomizations(ZoomCustomization currentCustomization, ReadableMap opts) { + ZoomFrameCustomization frameCustomization = new ZoomFrameCustomization(); + frameCustomization.topMargin = opts.getInt("topMargin"); + frameCustomization.sizeRatio = (float)opts.getDouble("sizeRatio"); + + if (opts.hasKey("backgroundColor")) { + frameCustomization.backgroundColor = Color.parseColor(opts.getString("backgroundColor")); + } + + if (opts.hasKey("borderColor")) { + frameCustomization.borderColor= Color.parseColor(opts.getString("borderColor")); + } + + currentCustomization.setFrameCustomization(frameCustomization); + } + + private void addFeedbackCustomizations(ZoomCustomization currentCustomization, ReadableMap opts) { + if (!opts.isNull("feedbackCustomization")) { + ZoomFeedbackCustomization feedbackCustomization = new ZoomFeedbackCustomization(); + ReadableMap feedbackCustomizationOptions = opts.getMap("feedbackCustomization"); + + if (feedbackCustomizationOptions.hasKey("backgroundColor")) { + ReadableArray backgroundColors = feedbackCustomizationOptions.getArray("backgroundColor"); + // This attribute contains array of 2 colors for gradient, but it seems like Java API + // doesn't allow to set gradient, so we take just the first. + String backgroundColor = backgroundColors.getString(0); + + feedbackCustomization.backgroundColor = Color.parseColor(backgroundColor); + } + + currentCustomization.setFeedbackCustomization(feedbackCustomization); + Log.d(TAG, "Feedback customizations applied."); + } + } + + private void addOvalCustomizations(ZoomCustomization currentCustomization, ReadableMap opts) { + if (!opts.isNull("ovalCustomization")) { + ZoomOvalCustomization ovalCustomization = new ZoomOvalCustomization(); + ReadableMap ovalCustomizationOptions = opts.getMap("ovalCustomization"); + + if (ovalCustomizationOptions.hasKey("progressColor1")) { + ovalCustomization.progressColor1 = Color.parseColor(ovalCustomizationOptions.getString("progressColor1")); + } + + if (ovalCustomizationOptions.hasKey("progressColor2")) { + ovalCustomization.progressColor2 = Color.parseColor(ovalCustomizationOptions.getString("progressColor2")); + } + + currentCustomization.setOvalCustomization(ovalCustomization); + Log.d(TAG, "Oval customizations applied."); + } + } + // private void enroll(JSONArray args, final CallbackContext callbackContext) throws JSONException { // String userId = args.getString(0); // String secret = args.getString(1); diff --git a/defaults.js b/defaults.js index 90fd4b1..694b3b2 100644 --- a/defaults.js +++ b/defaults.js @@ -17,6 +17,8 @@ GJD4GIVvR+j12gXAaftj3ahfYxioBH7F7HQxzmWkwDyn3bqU54eaiB7f0ftsPpWM ceUaqkL2DZUvgN0efEJjnWy5y1/Gkq5GGWCROI9XG/SwXJ30BbVUehTbVcD70+ZF 8QIDAQAB -----END PUBLIC KEY-----`, + feedbackCustomization: {}, + ovalCustomization: {}, // mainBackgroundColors: [UIColor] // mainForegroundColor: UIColor // buttonTextNormalColor: UIColor diff --git a/ios/ZoomAuth.swift b/ios/ZoomAuth.swift index fdf62c9..9703cf0 100644 --- a/ios/ZoomAuth.swift +++ b/ios/ZoomAuth.swift @@ -248,7 +248,7 @@ class ZoomAuth: RCTViewManager, ZoomVerificationDelegate { let publicKey = options["facemapEncryptionKey"] as! String Zoom.sdk.setFacemapEncryptionKey(publicKey: publicKey) } - + Zoom.sdk.auditTrailType = .height640 // otherwise no auditTrail images // Create the customization object @@ -257,12 +257,16 @@ class ZoomAuth: RCTViewManager, ZoomVerificationDelegate { currentCustomization.showUserLockedScreen = (options["showUserLockedScreen"] as? Bool)! currentCustomization.showRetryScreen = (options["showRetryScreen"] as? Bool)! currentCustomization.enableLowLightMode = (options["enableLowLightMode"] as? Bool)! - - // Sample UI Customization: vertically center the ZoOm frame within the device's display - if (options["centerFrame"] as? Bool)! { - centerZoomFrameCustomization(currentZoomCustomization: currentCustomization) + + let mainBackgroundColors = options["mainBackgroundColors"] != nil ? options["mainBackgroundColors"] as! Array : [] + if !mainBackgroundColors.isEmpty { + currentCustomization.mainBackgroundColors = [convertToUIColor(hex: mainBackgroundColors[0]), convertToUIColor(hex: mainBackgroundColors[1])] } + addFrameCustomizations(currentCustomization: currentCustomization, options: options) + addFeedbackCustomizations(currentCustomization: currentCustomization, options: options) + addOvalCustomizations(currentCustomization: currentCustomization, options: options) + // Apply the customization changes Zoom.sdk.setCustomization(currentCustomization) Zoom.sdk.initialize( @@ -294,6 +298,46 @@ class ZoomAuth: RCTViewManager, ZoomVerificationDelegate { } ) } + + func addFrameCustomizations(currentCustomization: ZoomCustomization, options: Dictionary) { + // Sample UI Customization: vertically center the ZoOm frame within the device's display + if (options["centerFrame"] as? Bool)! { + centerZoomFrameCustomization(currentZoomCustomization: currentCustomization) + } + + if (options["backgroundColor"] != nil) { + currentCustomization.frameCustomization.backgroundColor = convertToUIColor(hex: options["backgroundColor"] as! String) + } + + if (options["borderColor"] != nil) { + currentCustomization.frameCustomization.borderColor = convertToUIColor(hex: options["borderColor"] as! String) + } + } + + func addFeedbackCustomizations(currentCustomization: ZoomCustomization, options: Dictionary) { + let feedbackCustomization: Dictionary = options["feedbackCustomization"] as! Dictionary + // Create gradient layer for a custom feedback bar background on iOS + if (!feedbackCustomization.isEmpty) { + let backgroundColors = feedbackCustomization["backgroundColor"] as! Array + let zoomGradientLayer = createGradientLayer(_self: self, hexColor1: backgroundColors[0], hexColor2: backgroundColors[1]) + currentCustomization.feedbackCustomization.backgroundColor = zoomGradientLayer + print("Feedback customizations applied.") + } + } + + func addOvalCustomizations(currentCustomization: ZoomCustomization, options: Dictionary) { + let ovalCustomization: Dictionary = options["ovalCustomization"] as! Dictionary + if (!ovalCustomization.isEmpty) { + let supportedColorOvalCustomizations = ["progressColor1", "progressColor2"] + for property in supportedColorOvalCustomizations { + if (ovalCustomization[property] != nil) { + let value = ovalCustomization[property] + currentCustomization.ovalCustomization.setValue(convertToUIColor(hex: value as! String), forKey: property) + } + } + print("Oval customizations applied.") + } + } func centerZoomFrameCustomization(currentZoomCustomization: ZoomCustomization) { let screenHeight: CGFloat = UIScreen.main.fixedCoordinateSpace.bounds.size.height @@ -308,3 +352,33 @@ class ZoomAuth: RCTViewManager, ZoomVerificationDelegate { currentZoomCustomization.frameCustomization.topMargin = Double(topMarginToCenterFrame) } } + +func createGradientLayer(_self: ZoomAuth, hexColor1: String, hexColor2: String) -> CAGradientLayer { + let gradientLayer = CAGradientLayer() + gradientLayer.frame = _self.view().bounds + gradientLayer.colors = [convertToUIColor(hex: hexColor1).cgColor, convertToUIColor(hex: hexColor2).cgColor] + _self.view().layer.addSublayer(gradientLayer) + return gradientLayer +} + +func convertToUIColor(hex: String, alpha: Int = 1) -> UIColor { + if hex.hasPrefix("#") { + let start = hex.index(hex.startIndex, offsetBy: 1) + let hexColor = String(hex[start...]) + + if hexColor.count == 6 { + let scanner = Scanner(string: hexColor) + var hexNumber: UInt64 = 0 + + if scanner.scanHexInt64(&hexNumber) { + let red = CGFloat((hexNumber & 0xff0000) >> 16) / 255 + let green = CGFloat((hexNumber & 0xff00) >> 8) / 255 + let blue = CGFloat(hexNumber & 0xff) / 255 + + return UIColor(red: red, green: green, blue: blue, alpha: CGFloat(alpha)) + } + } + } + + return UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 1.0) +}