diff --git a/android/src/main/java/com/mobilepaymentssdkreactnative/Utils.kt b/android/src/main/java/com/mobilepaymentssdkreactnative/Utils.kt index 227dbe8..a2d38a5 100644 --- a/android/src/main/java/com/mobilepaymentssdkreactnative/Utils.kt +++ b/android/src/main/java/com/mobilepaymentssdkreactnative/Utils.kt @@ -330,8 +330,7 @@ fun ReaderInfo.toReaderInfoMap(): WritableMap { return WritableNativeMap().apply { putString("id", id) putString("model", model.toModelString()) - putString("state", state.toStateString()) - putString("status", status.toStatusString()) + putMap("status", status.toStatusMap()) putString("serialNumber", serialNumber) putString("name", name) putMap("batteryStatus", batteryStatus?.toBatteryStatusMap()) @@ -370,27 +369,49 @@ fun ReaderInfo.Model.toModelString(): String { } } -fun ReaderInfo.State.toStateString(): String { - return when(this) { - is ReaderInfo.State.Ready ->"READY" - is ReaderInfo.State.Disabled ->"DISABLE" - is ReaderInfo.State.Connecting ->"CONNECTING" - is ReaderInfo.State.Disconnected ->"DISCONNECTED" - is ReaderInfo.State.FailedToConnect->"FAILED_TO_CONNECT" - is ReaderInfo.State.UpdatingFirmware ->"UPDATING_FIRMWARE" - } -} - fun ReaderInfo.Status.toStatusString(): String { return when (this) { is ReaderInfo.Status.Ready -> "READY" is ReaderInfo.Status.ConnectingToDevice -> "CONNECTING_TO_DEVICE" is ReaderInfo.Status.ConnectingToSquare -> "CONNECTING_TO_SQUARE" is ReaderInfo.Status.Faulty -> "FAULTY" - is ReaderInfo.Status.ReaderUnavailable -> "READER_UNAVAILABLE_${this.reason.name}" + is ReaderInfo.Status.ReaderUnavailable -> "READER_UNAVAILABLE" } } +fun ReaderInfo.Status.toUnavailableReasonString(): String? { + if (this is ReaderInfo.Status.ReaderUnavailable) { + return when (reason) { + ReaderInfo.Status.ReaderUnavailable.ReaderUnavailableReason.INTERNAL_ERROR -> "INTERNAL_ERROR" + ReaderInfo.Status.ReaderUnavailable.ReaderUnavailableReason.BLUETOOTH_DISABLED -> "BLUETOOTH_DISABLED" + ReaderInfo.Status.ReaderUnavailable.ReaderUnavailableReason.BLUETOOTH_FAILURE -> "BLUETOOTH_FAILURE" + ReaderInfo.Status.ReaderUnavailable.ReaderUnavailableReason.SECURE_CONNECTION_TO_SQUARE_FAILURE -> "SECURE_CONNECTION_TO_SQUARE_FAILURE" + ReaderInfo.Status.ReaderUnavailable.ReaderUnavailableReason.SECURE_CONNECTION_NETWORK_FAILURE -> "SECURE_CONNECTION_NETWORK_FAILURE" + ReaderInfo.Status.ReaderUnavailable.ReaderUnavailableReason.OFFLINE_SESSION_EXPIRED -> "OFFLINE_SESSION_EXPIRED" + ReaderInfo.Status.ReaderUnavailable.ReaderUnavailableReason.READER_UNAVAILABLE_OFFLINE -> "READER_UNAVAILABLE_OFFLINE" + ReaderInfo.Status.ReaderUnavailable.ReaderUnavailableReason.OFFLINE_MODE_DISABLED -> "OFFLINE_MODE_DISABLED" + ReaderInfo.Status.ReaderUnavailable.ReaderUnavailableReason.READER_UPDATE_FAILED -> "READER_UPDATE_FAILED" + ReaderInfo.Status.ReaderUnavailable.ReaderUnavailableReason.BLOCKING_UPDATE -> "BLOCKING_UPDATE" + ReaderInfo.Status.ReaderUnavailable.ReaderUnavailableReason.MERCHANT_SUSPENDED -> "MERCHANT_SUSPENDED" + ReaderInfo.Status.ReaderUnavailable.ReaderUnavailableReason.MERCHANT_INELIGIBLE -> "MERCHANT_INELIGIBLE" + ReaderInfo.Status.ReaderUnavailable.ReaderUnavailableReason.MERCHANT_NOT_ACTIVATED -> "MERCHANT_NOT_ACTIVATED" + ReaderInfo.Status.ReaderUnavailable.ReaderUnavailableReason.DEVICE_NOT_SUPPORTED -> "DEVICE_NOT_SUPPORTED" + ReaderInfo.Status.ReaderUnavailable.ReaderUnavailableReason.READER_FIRMWARE_UPDATE_REQUIRED -> "READER_FIRMWARE_UPDATE_REQUIRED" + ReaderInfo.Status.ReaderUnavailable.ReaderUnavailableReason.READER_NOT_SUPPORTED -> "READER_NOT_SUPPORTED" + ReaderInfo.Status.ReaderUnavailable.ReaderUnavailableReason.DEVICE_ROOTED -> "DEVICE_ROOTED" + ReaderInfo.Status.ReaderUnavailable.ReaderUnavailableReason.DEVICE_DEVELOPER_MODE -> "DEVICE_DEVELOPER_MODE" + ReaderInfo.Status.ReaderUnavailable.ReaderUnavailableReason.DISABLED -> "DISABLED" + } + } + return null; +} + +fun ReaderInfo.Status.toStatusMap(): WritableMap { + return WritableNativeMap().apply { + putString("readerUnavailableReason", toUnavailableReasonString()) + putString("status", toStatusString()) + } +} fun ReaderChangedEvent.toChangedEventMap(): WritableMap { return WritableNativeMap().apply { diff --git a/example/src/App.tsx b/example/src/App.tsx index 0653529..1a958ce 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -3,12 +3,13 @@ import { NavigationContainer } from '@react-navigation/native'; import HomeView from './Screens/HomeScreen'; import PermissionsScreen from './Screens/PermissionsScreen'; import { StatusBar } from 'react-native'; +import { SafeAreaProvider } from 'react-native-safe-area-context'; const Stack = createNativeStackNavigator(); export default function App() { return ( - <> + ); } diff --git a/example/src/Screens/HomeScreen.tsx b/example/src/Screens/HomeScreen.tsx index b31a6f1..a8c7448 100644 --- a/example/src/Screens/HomeScreen.tsx +++ b/example/src/Screens/HomeScreen.tsx @@ -11,19 +11,14 @@ import { type PaymentParameters, type PromptParameters, ProcessingMode, + type Failure, } from 'mobile-payments-sdk-react-native'; import React, { useState } from 'react'; -import { - View, - Text, - Image, - StyleSheet, - SafeAreaView, - TouchableOpacity, -} from 'react-native'; +import { View, Text, Image, StyleSheet, TouchableOpacity } from 'react-native'; import uuid from 'react-native-uuid'; import LoadingButton from '../components/LoadingButton'; import HeaderButton from '../components/HeaderButton'; +import { SafeAreaView } from 'react-native-safe-area-context'; const HomeView = () => { const navigation = useNavigation(); @@ -126,8 +121,8 @@ const styles = StyleSheet.create({ backgroundColor: 'white', }, header: { + justifyContent: 'space-between', flexDirection: 'row', - marginBottom: 50, paddingLeft: 16, paddingRight: 16, }, @@ -136,7 +131,8 @@ const styles = StyleSheet.create({ }, content: { alignItems: 'center', - flex: 9, + flex: 1, + justifyContent: 'center', paddingLeft: 16, paddingRight: 16, }, @@ -152,7 +148,6 @@ const styles = StyleSheet.create({ marginBottom: 32, }, mockButton: { - flex: 1, alignItems: 'center', }, mockReaderText: { diff --git a/example/src/Screens/PermissionsScreen.tsx b/example/src/Screens/PermissionsScreen.tsx index 3e68e2c..ed42a9f 100644 --- a/example/src/Screens/PermissionsScreen.tsx +++ b/example/src/Screens/PermissionsScreen.tsx @@ -4,7 +4,6 @@ import { Text, ScrollView, StyleSheet, - SafeAreaView, Alert, Platform, } from 'react-native'; @@ -29,7 +28,7 @@ import { } from 'react-native-permissions'; import LoadingButton from '../components/LoadingButton'; import BuildConfig from 'react-native-build-config'; - +import { SafeAreaView } from 'react-native-safe-area-context'; export const requestBluetooth = () => { requestMultiple( @@ -39,6 +38,7 @@ export const requestBluetooth = () => { PERMISSIONS.ANDROID.BLUETOOTH_SCAN, ], ios: [PERMISSIONS.IOS.BLUETOOTH_PERIPHERAL], + default: [], }) ).then((statuses) => { console.log(statuses); diff --git a/ios/Mappers.swift b/ios/Mappers.swift index d8ff1f8..c03c2eb 100644 --- a/ios/Mappers.swift +++ b/ios/Mappers.swift @@ -143,7 +143,6 @@ class Mappers { return [ "batteryStatus" : reader.batteryStatus?.toMap() ?? NSNull(), "cardInsertionStatus": reader.cardInsertionStatus.toName(), - "connectionInfo": reader.connectionInfo.toMap(), "firmwareInfo" : reader.firmwareInfo?.toMap() ?? NSNull(), "id": String(reader.id), "isBlinkable" : reader.isBlinkable, @@ -152,12 +151,74 @@ class Mappers { "model": reader.model.toName(), "name" : reader.name, "serialNumber" : reader.serialNumber ?? NSNull(), - "state" : reader.state.toName(), - "supportedCardEntryMethods" : reader.supportedInputMethods.toList() + "supportedCardEntryMethods" : reader.supportedInputMethods.toList(), + "status": reader.statusInfo.toMap() ] } } +extension ReaderStatusInfo { + func toMap() -> NSDictionary { + return [ + "status" : status.toName(), + "readerUnavailableReason" : unavailableReasonInfo?.reason.toName() ?? NSNull(), + ] + } +} + +extension ReaderStatus { + func toName() -> String { + return switch self { + case .connectingToDevice: + "CONNECTING_TO_DEVICE" + case .connectingToSquare: + "CONNECTING_TO_SQUARE" + case .readerUnavailable : + "READER_UNAVAILABLE" + case .faulty: + "FAULTY" + case .ready: + "READY" + default : + "UNKNOWN" + } + } +} + +extension ReaderUnavailableReason { + func toName() -> String { + return switch self { + case .internalError: + "INTERNAL_ERROR" + case .bluetoothDisabled: + "BLUETOOTH_DISABLED" + case .bluetoothFailure: + "BLUETOOTH_FAILURE" + case .secureConnectionToSquareFailure: + "SECURE_CONNECTION_TO_SQUARE_FAILURE" + case .secureConnectionNetworkFailure: + "SECURE_CONNECTION_NETWORK_FAILURE" + case .blockingFirmwareUpdate: + "BLOCKING_UPDATE" + case .maxReadersConnected: + "MAX_READERS_CONNECTED" + case .notConnectedToInternet + : "NOT_CONNECTED_TO_INTERNET" + case .readerTimeout: + "READER_TIMEOUT" + case .revokedByDevice: + "REVOKED_BY_DEVICE" + case .tapToPayError: + "TAP_TO_PAY_ERROR" + case .tapToPayIsNotLinked: + "TAP_TO_PAY_IS_NOT_LINKED" + default: + "UNKNOWN" + } + } +} + + extension SquareMobilePaymentsSDK.AuthorizationState { func mapToString() -> String { switch self { diff --git a/src/models/enums.ts b/src/models/enums.ts index 54d493a..278066e 100644 --- a/src/models/enums.ts +++ b/src/models/enums.ts @@ -220,6 +220,12 @@ export enum ReaderUnavailableReason { DEVICE_ROOTED = 'DEVICE_ROOTED', DEVICE_DEVELOPER_MODE = 'DEVICE_DEVELOPER_MODE', DISABLED = 'DISABLED', + MAX_READERS_CONNECTED = 'MAX_READERS_CONNECTED', + NOT_CONNECTED_TO_INTERNET = 'NOT_CONNECTED_TO_INTERNET', + READER_TIMEOUT = 'READER_TIMEOUT', + REVOKED_BY_DEVICE = 'REVOKED_BY_DEVICE', + TAP_TO_PAY_ERROR = 'TAP_TO_PAY_ERROR', + TAP_TO_PAY_IS_NOT_LINKED = 'TAP_TO_PAY_IS_NOT_LINKED', } export enum CardEntryMethod { diff --git a/src/models/objects.ts b/src/models/objects.ts index 211010c..2226761 100644 --- a/src/models/objects.ts +++ b/src/models/objects.ts @@ -18,7 +18,6 @@ import type { ReaderConnectionState, ReaderInternalStatus, ReaderModel, - ReaderState, ReaderUnavailableReason, SourceType, } from './enums'; @@ -179,7 +178,6 @@ export type ReaderStatus = { export type ReaderInfo = { id: String; model: ReaderModel; - state: ReaderState; status: ReaderStatus; serialNumber?: String; name: String; @@ -189,9 +187,7 @@ export type ReaderInfo = { supportedCardEntryMethods: CardEntryMethod[]; isForgettable: Boolean; isBlinkable: Boolean; - cardInsertionStatus?: CardInsertionStatus; - connectionInfo?: ReaderConnectionInfo; firmwareInfo?: ReaderFirmwareInfo; isConnectionRetryable?: Boolean; }; @@ -199,6 +195,5 @@ export type ReaderInfo = { export type ReaderChangedEvent = { change: ReaderChange; reader: ReaderInfo; - readerState: ReaderState; readerSerialNumber?: String; };