Skip to content

Commit

Permalink
Merge pull request #1 from brainylab/features
Browse files Browse the repository at this point in the history
feat(initalizing-project): iniciando projeto
  • Loading branch information
andrefelipeschulle authored Jul 31, 2023
2 parents ebdaeba + cc4d23f commit 3f506ea
Show file tree
Hide file tree
Showing 26 changed files with 16,798 additions and 90 deletions.
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules/
lib/
3 changes: 3 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
extends: ['@brainylab/eslint-config-react-native'],
};
7 changes: 7 additions & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
arrowParens: 'avoid',
bracketSameLine: true,
bracketSpacing: false,
singleQuote: true,
trailingComma: 'all',
};
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import groovy.json.JsonSlurper
def registrationCompat = {
def reactNativeManifest = file("$projectDir/../node_modules/react-native/package.json").exists()
? file("$projectDir/../node_modules/react-native/package.json") // developer mode, to run example app
: file("$projectDir/../../react-native/package.json")
: file("$projectDir/../../../react-native/package.json")
def reactNativeVersion = new JsonSlurper().parseText(reactNativeManifest.text).version as String
// Fabric was introduced at [email protected], full CMake support were introduced at [email protected]
// Use Android.mk for compatibility with [email protected]/0.69
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.brainylab.reactnativeexternalscanner

import android.content.Context
import android.content.res.Configuration
import android.view.InputDevice
import android.view.KeyCharacterMap
import android.view.inputmethod.InputMethodManager
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext

object ExternalScannerUtil {
fun isExternalScanner(inputDevice: InputDevice, resourcesConfiguration: Configuration): Boolean {
val sources = inputDevice.sources
if ((sources and InputDevice.SOURCE_KEYBOARD) != InputDevice.SOURCE_KEYBOARD) {
return false // Not a keyboard device
}

// Check if the device has a key character map
val keyCharacterMap = inputDevice.keyCharacterMap
if (keyCharacterMap == null || keyCharacterMap.keyboardType == KeyCharacterMap.VIRTUAL_KEYBOARD) {
return false // Virtual (on-screen) keyboard
}

// Check if the device has a physical keyboard (i.e., not a virtual keyboard)
val hasPhysicalKeyboard = (resourcesConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS)

// If it has a physical keyboard, and it's not virtual (emulator or virtual device)
return hasPhysicalKeyboard && !inputDevice.isVirtual
}

fun hasExternalScanner(reactContext: ReactApplicationContext): Boolean {
val inputManager = reactContext.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
val inputDevices = InputDevice.getDeviceIds()
val resourcesConfiguration = reactContext.resources.configuration

for (deviceId in inputDevices) {
val device = InputDevice.getDevice(deviceId)
if (device != null && isExternalScanner(device, resourcesConfiguration)) {
return true
}
}
return false
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.brainylab.reactnativeexternalscanner

import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.WritableMap
import com.facebook.react.uimanager.events.Event
import com.facebook.react.uimanager.events.RCTModernEventEmitter


class ExternalScannerViewSingleValueEvent(viewId: Int, private val codeValue: String): Event<ExternalScannerViewSingleValueEvent>(viewId) {
override fun getEventName(): String {
return "topOnSingleValueScanned"
}

override fun dispatchModern(rctEventEmitter: RCTModernEventEmitter?) {
super.dispatchModern(rctEventEmitter)
rctEventEmitter?.receiveEvent(
-1,
viewTag, eventName,
Arguments.createMap()
)
}

override fun getEventData(): WritableMap {
val event: WritableMap = Arguments.createMap()
event.putString("value", codeValue)
return event
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.brainylab.reactnativeexternalscanner

import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.WritableMap
import com.facebook.react.uimanager.events.Event
import com.facebook.react.uimanager.events.RCTModernEventEmitter


class ExternalScannerViewValueEvent(viewId: Int, private val codeValue: String): Event<ExternalScannerViewValueEvent>(viewId) {
override fun getEventName(): String {
return "topOnValueScanned"
}

override fun dispatchModern(rctEventEmitter: RCTModernEventEmitter?) {
super.dispatchModern(rctEventEmitter)
rctEventEmitter?.receiveEvent(
-1,
viewTag, eventName,
Arguments.createMap()
)
}

override fun getEventData(): WritableMap {
val event: WritableMap = Arguments.createMap()
event.putString("value", codeValue)
return event
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.brainylab.reactnativeexternalscanner

import android.content.Context
import android.content.res.Configuration
import android.view.InputDevice
import android.view.KeyCharacterMap
import android.view.KeyEvent
import android.view.inputmethod.InputMethodManager
import com.facebook.react.bridge.*
import com.facebook.react.modules.core.DeviceEventManagerModule

class ReactNativeExternalScannerModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
override fun getName(): String {
return "ReactNativeExternalScannerModule"
}

@ReactMethod
fun hasExternalKeyboard(promise: Promise) {
val isExternal = ExternalScannerUtil.hasExternalScanner(reactApplicationContext)

if(isExternal) {
promise.resolve(true)
} else {
promise.resolve(false)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@ import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.ViewManager
import java.util.ArrayList

class ReactNativeExternalScannerViewPackage : ReactPackage {
class ReactNativeExternalScannerPackage : ReactPackage {
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
val viewManagers: MutableList<ViewManager<*, *>> = ArrayList()
viewManagers.add(ReactNativeExternalScannerViewManager())
viewManagers.add(ReactNativeExternalScannerViewManager(reactContext))
return viewManagers
}

override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
return emptyList()
val modules = mutableListOf<NativeModule>()
modules.add(ReactNativeExternalScannerModule(reactContext))
return modules
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,95 @@ package com.brainylab.reactnativeexternalscanner
import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import android.view.KeyEvent
import android.view.InputDevice
import android.view.InputDevice.SOURCE_KEYBOARD
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.WritableMap
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter
import com.facebook.react.bridge.ReactContext
import com.facebook.react.uimanager.events.EventDispatcher
import com.facebook.react.uimanager.UIManagerHelper

class ReactNativeExternalScannerView : View {
constructor(context: Context?) : super(context)
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
)
class ReactNativeExternalScannerView(context: Context) : ViewGroup(context) {
private var codeScanned: StringBuilder = StringBuilder()
private var childView: View? = null
private var hasExternalKeyboard: Boolean = false
private var mContext: ReactApplicationContext? = null
var activeInterceptor: Boolean = true

fun setChildView(view: View) {
if (childView != null) {
removeView(childView)
}
childView = view
addView(view)
}

fun setChildParams(params: ViewGroup.LayoutParams) {
childView?.layoutParams = params
requestLayout()
}


override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
childView?.let { child ->
val centerX = (right - left) / 2
val centerY = (bottom - top) / 2

val childLeft = centerX - child.measuredWidth / 2
val childTop = centerY - child.measuredHeight / 2

val childRight = childLeft + child.measuredWidth
val childBottom = childTop + child.measuredHeight

child.layout(childLeft, childTop, childRight, childBottom)
}
}

fun checkForExternalKeyboard(mContext: ReactApplicationContext) {
val isExternal = ExternalScannerUtil.hasExternalScanner(mContext)

hasExternalKeyboard = isExternal;
}

private fun getEventDispatcherForReactTag(reactContext: ReactContext, tag: Int): EventDispatcher? {
return UIManagerHelper.getEventDispatcherForReactTag(reactContext, tag)
}


init {
isFocusableInTouchMode = true
requestFocus()

setOnKeyListener { _, keyCode, event ->
if (!hasExternalKeyboard) return@setOnKeyListener false

val reactContext = context as ReactContext

if (event.action == KeyEvent.ACTION_DOWN && activeInterceptor) {
when (keyCode) {
KeyEvent.KEYCODE_ENTER -> {
val eventDispatcherValue = getEventDispatcherForReactTag(reactContext, id)
eventDispatcherValue?.dispatchEvent(ExternalScannerViewValueEvent(id, codeScanned.toString()))
codeScanned = StringBuilder() // clear string
true
}
else -> {
val keyChar = event.unicodeChar.toChar()
val valueInString = keyChar.toString()
codeScanned.append(valueInString)

val eventDispatcherSingle = getEventDispatcherForReactTag(reactContext, id)
eventDispatcherSingle?.dispatchEvent(ExternalScannerViewSingleValueEvent(id, valueInString))
true
}
}
} else {
false
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
package com.brainylab.reactnativeexternalscanner

import android.graphics.Color
import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.uimanager.SimpleViewManager
import com.facebook.react.uimanager.ViewGroupManager
import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.ViewManagerDelegate
import com.facebook.react.uimanager.annotations.ReactProp
import com.facebook.react.viewmanagers.ReactNativeExternalScannerViewManagerInterface
import com.facebook.react.viewmanagers.ReactNativeExternalScannerViewManagerDelegate
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.soloader.SoLoader
import com.facebook.react.common.MapBuilder

@ReactModule(name = ReactNativeExternalScannerViewManager.NAME)
class ReactNativeExternalScannerViewManager : SimpleViewManager<ReactNativeExternalScannerView>(),
class ReactNativeExternalScannerViewManager(private val mCallerContext: ReactApplicationContext) : ViewGroupManager<ReactNativeExternalScannerView>(),
ReactNativeExternalScannerViewManagerInterface<ReactNativeExternalScannerView> {
private val mDelegate: ViewManagerDelegate<ReactNativeExternalScannerView>

Expand All @@ -28,12 +29,24 @@ class ReactNativeExternalScannerViewManager : SimpleViewManager<ReactNativeExter
}

public override fun createViewInstance(context: ThemedReactContext): ReactNativeExternalScannerView {
return ReactNativeExternalScannerView(context)
val externalScannerView = ReactNativeExternalScannerView(context);
externalScannerView.checkForExternalKeyboard(mCallerContext)
return externalScannerView;
}

@ReactProp(name = "color")
override fun setColor(view: ReactNativeExternalScannerView?, color: String?) {
view?.setBackgroundColor(Color.parseColor(color))
@ReactProp(name = "active")
override fun setActive(view: ReactNativeExternalScannerView, active: Boolean) {
view.activeInterceptor = active
}

override fun getExportedCustomDirectEventTypeConstants(): Map<String?, Any> {
return MapBuilder.builder<String, Any>()
.put("topOnValueScanned",
MapBuilder.of("registrationName", "onCodeScanned")
)
.put("topOnSingleValueScanned",
MapBuilder.of("registrationName", "onSingleCodeScanned")
).build()
}

companion object {
Expand Down
1 change: 1 addition & 0 deletions example/babel.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const path = require('path');

const pak = require('../package.json');

module.exports = {
Expand Down
5 changes: 3 additions & 2 deletions example/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { AppRegistry } from 'react-native';
import {AppRegistry} from 'react-native';

import {name as appName} from './app.json';
import App from './src/App';
import { name as appName } from './app.json';

AppRegistry.registerComponent(appName, () => App);
Loading

0 comments on commit 3f506ea

Please sign in to comment.