@rejaul/react-native-printer-kit 0.3.4 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +293 -14
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/rejaul/reactnativeprinterkit/ReactNativePrinterKitModule.kt +267 -31
- package/lib/module/NativeReactNativePrinterKit.js +19 -0
- package/lib/module/NativeReactNativePrinterKit.js.map +1 -1
- package/lib/module/enums.js +45 -0
- package/lib/module/enums.js.map +1 -0
- package/lib/module/index.js +107 -6
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/NativeReactNativePrinterKit.d.ts +241 -5
- package/lib/typescript/src/NativeReactNativePrinterKit.d.ts.map +1 -1
- package/lib/typescript/src/enums.d.ts +44 -0
- package/lib/typescript/src/enums.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +73 -7
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/NativeReactNativePrinterKit.ts +280 -5
- package/src/enums.ts +69 -0
- package/src/index.tsx +155 -9
package/android/src/main/java/com/rejaul/reactnativeprinterkit/ReactNativePrinterKitModule.kt
CHANGED
|
@@ -15,18 +15,29 @@ import com.facebook.react.bridge.WritableArray
|
|
|
15
15
|
import com.facebook.react.bridge.WritableMap
|
|
16
16
|
import com.facebook.react.modules.core.PermissionAwareActivity
|
|
17
17
|
import com.rezaul.printerkit.BluetoothPermissions
|
|
18
|
-
import com.rezaul.printerkit.
|
|
19
|
-
import com.rezaul.printerkit.
|
|
20
|
-
import com.rezaul.printerkit.
|
|
21
|
-
import com.rezaul.printerkit.ConnectPrinterParams
|
|
22
|
-
import com.rezaul.printerkit.
|
|
23
|
-
import com.rezaul.printerkit.
|
|
24
|
-
import com.rezaul.printerkit.
|
|
25
|
-
import com.rezaul.printerkit.
|
|
26
|
-
import com.rezaul.printerkit.
|
|
27
|
-
import com.rezaul.printerkit.
|
|
28
|
-
import com.rezaul.printerkit.
|
|
29
|
-
import com.rezaul.printerkit.PrintTextParams
|
|
18
|
+
import com.rezaul.printerkit.PosPrinter
|
|
19
|
+
import com.rezaul.printerkit.PrinterService
|
|
20
|
+
import com.rezaul.printerkit.model.BluetoothPrinterDevice
|
|
21
|
+
import com.rezaul.printerkit.model.ConnectPrinterParams
|
|
22
|
+
import com.rezaul.printerkit.model.FileLocation
|
|
23
|
+
import com.rezaul.printerkit.model.HtmlToPdfParams
|
|
24
|
+
import com.rezaul.printerkit.model.PdfToImageParams
|
|
25
|
+
import com.rezaul.printerkit.model.PrintHtmlParams
|
|
26
|
+
import com.rezaul.printerkit.model.PrintImageBase64Params
|
|
27
|
+
import com.rezaul.printerkit.model.PrintImageFileParams
|
|
28
|
+
import com.rezaul.printerkit.model.PrintPdfParams
|
|
29
|
+
import com.rezaul.printerkit.model.PrintTextParams
|
|
30
|
+
import com.rezaul.printerkit.model.PrinterConnectionType
|
|
31
|
+
import com.rezaul.printerkit.model.PrinterFilter
|
|
32
|
+
import com.rezaul.printerkit.model.PrinterImageType
|
|
33
|
+
import com.rezaul.printerkit.model.HtmlToImageParams
|
|
34
|
+
import com.rezaul.printerkit.model.ReadDirParams
|
|
35
|
+
import com.rezaul.printerkit.model.ReadFileFormat
|
|
36
|
+
import com.rezaul.printerkit.model.ReadFileParams
|
|
37
|
+
import com.rezaul.printerkit.model.ReadFileResult
|
|
38
|
+
import com.rezaul.printerkit.model.RemoveFileParams
|
|
39
|
+
import com.rezaul.printerkit.model.SaveFileParams
|
|
40
|
+
import com.rezaul.printerkit.model.UsbPrinterDevice
|
|
30
41
|
import java.util.concurrent.Executors
|
|
31
42
|
|
|
32
43
|
/** Reads an optional numeric field, falling back to [default] if absent/null. */
|
|
@@ -41,21 +52,33 @@ private fun ReadableMap.optIntOrNull(key: String): Int? =
|
|
|
41
52
|
private fun ReadableMap.optLong(key: String, default: Long): Long =
|
|
42
53
|
if (hasKey(key) && !isNull(key)) getDouble(key).toLong() else default
|
|
43
54
|
|
|
55
|
+
/** Reads an optional string field, or null if absent/null. */
|
|
56
|
+
private fun ReadableMap.optString(key: String): String? =
|
|
57
|
+
if (hasKey(key) && !isNull(key)) getString(key) else null
|
|
58
|
+
|
|
59
|
+
/** Reads an optional boolean field, falling back to [default] if absent/null. */
|
|
60
|
+
private fun ReadableMap.optBoolean(key: String, default: Boolean): Boolean =
|
|
61
|
+
if (hasKey(key) && !isNull(key)) getBoolean(key) else default
|
|
62
|
+
|
|
63
|
+
/** Parses an enum by name, falling back to [default] for a missing or unknown value. */
|
|
64
|
+
private inline fun <reified T : Enum<T>> enumOrDefault(name: String?, default: T): T =
|
|
65
|
+
name?.let { runCatching { enumValueOf<T>(it) }.getOrNull() } ?: default
|
|
66
|
+
|
|
44
67
|
/**
|
|
45
|
-
* Bridges [com.rezaul.printerkit.
|
|
68
|
+
* Bridges [com.rezaul.printerkit.PosPrinter] to React Native.
|
|
46
69
|
*
|
|
47
|
-
* Connect/print calls run through a bound [
|
|
48
|
-
* on module init) instead of a bare [
|
|
49
|
-
* the app being swiped away from Recents - see [
|
|
70
|
+
* Connect/print calls run through a bound [PrinterService] (started once,
|
|
71
|
+
* on module init) instead of a bare [PosPrinter], so the connection survives
|
|
72
|
+
* the app being swiped away from Recents - see [PrinterService]. Calls made
|
|
50
73
|
* before the service finishes binding (essentially instant, but not synchronous) are
|
|
51
74
|
* queued and run once it connects.
|
|
52
75
|
*
|
|
53
|
-
* All blocking Bluetooth/PDF/image I/O runs on a single background executor, off the
|
|
76
|
+
* All blocking Bluetooth/USB/network/PDF/image I/O runs on a single background executor, off the
|
|
54
77
|
* calling (JS) thread - also serializing printer writes, since concurrent writes to
|
|
55
78
|
* the same socket from two overlapping calls would corrupt the output.
|
|
56
79
|
*
|
|
57
80
|
* Every JS-facing method that takes data receives a single [ReadableMap] (the object
|
|
58
|
-
* param the TS Spec declares), matching [com.rezaul.printerkit.
|
|
81
|
+
* param the TS Spec declares), matching [com.rezaul.printerkit.PosPrinter]'s own
|
|
59
82
|
* single-params-object functions on the native side.
|
|
60
83
|
*/
|
|
61
84
|
class ReactNativePrinterKitModule(reactContext: ReactApplicationContext) :
|
|
@@ -63,17 +86,17 @@ class ReactNativePrinterKitModule(reactContext: ReactApplicationContext) :
|
|
|
63
86
|
|
|
64
87
|
private val executor = Executors.newSingleThreadExecutor()
|
|
65
88
|
|
|
66
|
-
// getBondedBluetoothPrinters()
|
|
67
|
-
// answer immediately, so
|
|
68
|
-
// waiting on the service to bind.
|
|
69
|
-
private val standalonePrinter by lazy {
|
|
89
|
+
// getBondedBluetoothPrinters(), getUsbPrinters() and the USB permission calls need no
|
|
90
|
+
// connection and must answer immediately, so they use their own plain PosPrinter
|
|
91
|
+
// rather than waiting on the service to bind.
|
|
92
|
+
private val standalonePrinter by lazy { PosPrinter(reactApplicationContext) }
|
|
70
93
|
|
|
71
|
-
private var printerService:
|
|
72
|
-
private val pendingActions = mutableListOf<(
|
|
94
|
+
private var printerService: PrinterService? = null
|
|
95
|
+
private val pendingActions = mutableListOf<(PrinterService) -> Unit>()
|
|
73
96
|
|
|
74
97
|
private val serviceConnection = object : ServiceConnection {
|
|
75
98
|
override fun onServiceConnected(name: ComponentName?, binder: IBinder?) {
|
|
76
|
-
val service = (binder as
|
|
99
|
+
val service = (binder as PrinterService.LocalBinder).getService()
|
|
77
100
|
printerService = service
|
|
78
101
|
val queued = synchronized(pendingActions) {
|
|
79
102
|
val copy = pendingActions.toList()
|
|
@@ -89,13 +112,13 @@ class ReactNativePrinterKitModule(reactContext: ReactApplicationContext) :
|
|
|
89
112
|
}
|
|
90
113
|
|
|
91
114
|
init {
|
|
92
|
-
val intent = Intent(reactApplicationContext,
|
|
115
|
+
val intent = Intent(reactApplicationContext, PrinterService::class.java)
|
|
93
116
|
reactApplicationContext.startService(intent)
|
|
94
117
|
reactApplicationContext.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
|
|
95
118
|
}
|
|
96
119
|
|
|
97
120
|
/** Runs [action] with the bound service, once available (queued if not yet bound). */
|
|
98
|
-
private fun withService(action: (
|
|
121
|
+
private fun withService(action: (PrinterService) -> Unit) {
|
|
99
122
|
val service = printerService
|
|
100
123
|
if (service != null) {
|
|
101
124
|
action(service)
|
|
@@ -108,6 +131,17 @@ class ReactNativePrinterKitModule(reactContext: ReactApplicationContext) :
|
|
|
108
131
|
val map = Arguments.createMap()
|
|
109
132
|
map.putString("name", device.name)
|
|
110
133
|
map.putString("address", device.address)
|
|
134
|
+
map.putString("confidence", device.confidence.name)
|
|
135
|
+
map.putString("reason", device.reason)
|
|
136
|
+
return map
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
private fun usbToMap(device: UsbPrinterDevice): WritableMap {
|
|
140
|
+
val map = Arguments.createMap()
|
|
141
|
+
map.putString("name", device.name)
|
|
142
|
+
map.putInt("vendorId", device.vendorId)
|
|
143
|
+
map.putInt("productId", device.productId)
|
|
144
|
+
map.putString("deviceName", device.deviceName)
|
|
111
145
|
return map
|
|
112
146
|
}
|
|
113
147
|
|
|
@@ -155,24 +189,74 @@ class ReactNativePrinterKitModule(reactContext: ReactApplicationContext) :
|
|
|
155
189
|
}
|
|
156
190
|
}
|
|
157
191
|
|
|
158
|
-
override fun getBondedBluetoothPrinters(): WritableArray {
|
|
192
|
+
override fun getBondedBluetoothPrinters(params: ReadableMap): WritableArray {
|
|
193
|
+
val filter = enumOrDefault(params.optString("filter"), PrinterFilter.ALL)
|
|
194
|
+
val keywords = params.getArray("extraNameKeywords")?.let { array ->
|
|
195
|
+
(0 until array.size()).mapNotNull { array.getString(it) }
|
|
196
|
+
} ?: emptyList()
|
|
159
197
|
val result: WritableArray = Arguments.createArray()
|
|
160
|
-
standalonePrinter.getBondedBluetoothPrinters().forEach { device ->
|
|
198
|
+
standalonePrinter.getBondedBluetoothPrinters(filter, keywords).forEach { device ->
|
|
161
199
|
result.pushMap(deviceToMap(device))
|
|
162
200
|
}
|
|
163
201
|
return result
|
|
164
202
|
}
|
|
165
203
|
|
|
204
|
+
override fun getUsbPrinters(): WritableArray {
|
|
205
|
+
val result: WritableArray = Arguments.createArray()
|
|
206
|
+
standalonePrinter.getUsbPrinters().forEach { device ->
|
|
207
|
+
result.pushMap(usbToMap(device))
|
|
208
|
+
}
|
|
209
|
+
return result
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
override fun hasUsbPermission(params: ReadableMap): Boolean {
|
|
213
|
+
if (!params.hasKey("vendorId") || !params.hasKey("productId")) return false
|
|
214
|
+
return standalonePrinter.hasUsbPermission(
|
|
215
|
+
params.getDouble("vendorId").toInt(),
|
|
216
|
+
params.getDouble("productId").toInt()
|
|
217
|
+
)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
override fun requestUsbPermission(params: ReadableMap, promise: Promise) {
|
|
221
|
+
if (!params.hasKey("vendorId") || !params.hasKey("productId")) {
|
|
222
|
+
promise.reject("ERROR", "vendorId and productId are required")
|
|
223
|
+
return
|
|
224
|
+
}
|
|
225
|
+
try {
|
|
226
|
+
// The result arrives on the main thread once the user answers the system dialog.
|
|
227
|
+
standalonePrinter.requestUsbPermission(
|
|
228
|
+
params.getDouble("vendorId").toInt(),
|
|
229
|
+
params.getDouble("productId").toInt()
|
|
230
|
+
) { granted -> promise.resolve(granted) }
|
|
231
|
+
} catch (e: Exception) {
|
|
232
|
+
promise.reject("ERROR", e.message)
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
166
236
|
override fun connectPrinter(params: ReadableMap, promise: Promise) {
|
|
167
|
-
val
|
|
237
|
+
val type = enumOrDefault(params.optString("type"), PrinterConnectionType.BLUETOOTH)
|
|
238
|
+
// USB printers are identified by vendorId/productId, so address may be empty for them.
|
|
239
|
+
val address = params.optString("address") ?: if (type == PrinterConnectionType.USB) "" else null
|
|
168
240
|
if (address == null) {
|
|
169
241
|
promise.reject("ERROR", "address is required")
|
|
170
242
|
return
|
|
171
243
|
}
|
|
244
|
+
val defaults = ConnectPrinterParams(address)
|
|
245
|
+
val connectParams = ConnectPrinterParams(
|
|
246
|
+
address = address,
|
|
247
|
+
notificationTitle = params.optString("notificationTitle") ?: defaults.notificationTitle,
|
|
248
|
+
type = type,
|
|
249
|
+
port = params.optInt("port", defaults.port),
|
|
250
|
+
timeoutMs = params.optInt("timeoutMs", defaults.timeoutMs),
|
|
251
|
+
vendorId = params.optIntOrNull("vendorId"),
|
|
252
|
+
productId = params.optIntOrNull("productId"),
|
|
253
|
+
disconnectedNotificationTitle =
|
|
254
|
+
params.optString("disconnectedNotificationTitle") ?: defaults.disconnectedNotificationTitle
|
|
255
|
+
)
|
|
172
256
|
withService { service ->
|
|
173
257
|
executor.execute {
|
|
174
258
|
try {
|
|
175
|
-
promise.resolve(service.connectAndKeepAlive(
|
|
259
|
+
promise.resolve(service.connectAndKeepAlive(connectParams))
|
|
176
260
|
} catch (e: Exception) {
|
|
177
261
|
promise.reject("ERROR", e.message)
|
|
178
262
|
}
|
|
@@ -218,6 +302,157 @@ class ReactNativePrinterKitModule(reactContext: ReactApplicationContext) :
|
|
|
218
302
|
}
|
|
219
303
|
}
|
|
220
304
|
|
|
305
|
+
override fun isPrinterReady(promise: Promise) {
|
|
306
|
+
withService { service ->
|
|
307
|
+
executor.execute {
|
|
308
|
+
try {
|
|
309
|
+
promise.resolve(service.printer.isPrinterReady())
|
|
310
|
+
} catch (e: Exception) {
|
|
311
|
+
promise.reject("ERROR", e.message)
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
override fun getPrinterStatus(params: ReadableMap, promise: Promise) {
|
|
318
|
+
withService { service ->
|
|
319
|
+
executor.execute {
|
|
320
|
+
try {
|
|
321
|
+
val status = service.printer.getPrinterStatus(params.optInt("timeoutMs", 800))
|
|
322
|
+
// Unknown (null) fields must reach JS as null, which makeNativeMap preserves.
|
|
323
|
+
promise.resolve(Arguments.makeNativeMap(status.toMap()))
|
|
324
|
+
} catch (e: Exception) {
|
|
325
|
+
promise.reject("ERROR", e.message)
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
override fun printTestPage(promise: Promise) {
|
|
332
|
+
withService { service ->
|
|
333
|
+
executor.execute {
|
|
334
|
+
try {
|
|
335
|
+
service.printer.printTestPage()
|
|
336
|
+
promise.resolve(null)
|
|
337
|
+
} catch (e: Exception) {
|
|
338
|
+
promise.reject("ERROR", e.message)
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
override fun saveFile(params: ReadableMap, promise: Promise) {
|
|
345
|
+
// Exactly one of sourcePath / text / base64 is validated by the native library, which
|
|
346
|
+
// answers with result.success = false and a message, so nothing to reject here.
|
|
347
|
+
executor.execute {
|
|
348
|
+
try {
|
|
349
|
+
val result = standalonePrinter.saveFile(
|
|
350
|
+
SaveFileParams(
|
|
351
|
+
sourcePath = params.optString("sourcePath"),
|
|
352
|
+
text = params.optString("text"),
|
|
353
|
+
base64 = params.optString("base64"),
|
|
354
|
+
fileName = params.optString("fileName"),
|
|
355
|
+
location = enumOrDefault(params.optString("location"), FileLocation.DOWNLOADS),
|
|
356
|
+
customFolder = params.optString("customFolder"),
|
|
357
|
+
subFolder = params.optString("subFolder"),
|
|
358
|
+
mimeType = params.optString("mimeType"),
|
|
359
|
+
overwrite = params.optBoolean("overwrite", false),
|
|
360
|
+
deleteSource = params.optBoolean("deleteSource", false)
|
|
361
|
+
)
|
|
362
|
+
)
|
|
363
|
+
promise.resolve(Arguments.makeNativeMap(result.toMap()))
|
|
364
|
+
} catch (e: Exception) {
|
|
365
|
+
promise.reject("ERROR", e.message)
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
override fun readFile(params: ReadableMap, promise: Promise) {
|
|
371
|
+
val path = params.getString("path")
|
|
372
|
+
if (path == null) {
|
|
373
|
+
promise.reject("ERROR", "path is required")
|
|
374
|
+
return
|
|
375
|
+
}
|
|
376
|
+
val formatName = params.optString("format")
|
|
377
|
+
val format = if (formatName == null) ReadFileFormat.BASE64 else ReadFileFormat.fromWireName(formatName)
|
|
378
|
+
if (format == null) {
|
|
379
|
+
// Same "never rejects" contract as the other file functions: a bad format is a failed result.
|
|
380
|
+
val failed = ReadFileResult(false, error = "Unknown format: $formatName (use base64, dataUri, text, hex or bytes)")
|
|
381
|
+
promise.resolve(Arguments.makeNativeMap(failed.toMap()))
|
|
382
|
+
return
|
|
383
|
+
}
|
|
384
|
+
executor.execute {
|
|
385
|
+
try {
|
|
386
|
+
val result = standalonePrinter.readFile(
|
|
387
|
+
ReadFileParams(
|
|
388
|
+
path = path,
|
|
389
|
+
format = format,
|
|
390
|
+
encoding = params.optString("encoding"),
|
|
391
|
+
maxBytes = params.optLong("maxBytes", ReadFileParams.DEFAULT_MAX_BYTES)
|
|
392
|
+
)
|
|
393
|
+
)
|
|
394
|
+
promise.resolve(Arguments.makeNativeMap(result.toMap()))
|
|
395
|
+
} catch (e: Exception) {
|
|
396
|
+
promise.reject("ERROR", e.message)
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
override fun htmlToImage(params: ReadableMap, promise: Promise) {
|
|
402
|
+
val html = params.getString("html")
|
|
403
|
+
if (html == null) {
|
|
404
|
+
promise.reject("ERROR", "html is required")
|
|
405
|
+
return
|
|
406
|
+
}
|
|
407
|
+
// htmlToImage hops to the main thread for the WebView and does the rendering on its own
|
|
408
|
+
// background thread, so it can be called straight from here.
|
|
409
|
+
standalonePrinter.htmlToImage(
|
|
410
|
+
HtmlToImageParams(
|
|
411
|
+
html = html,
|
|
412
|
+
outputPath = params.optString("outputPath"),
|
|
413
|
+
imageType = if (params.getString("imageType") == "JPEG") PrinterImageType.JPEG else PrinterImageType.PNG,
|
|
414
|
+
targetWidthPx = params.optIntOrNull("targetWidthPx"),
|
|
415
|
+
pageWidthDp = params.optInt("pageWidthDp", 412),
|
|
416
|
+
heightDp = params.optIntOrNull("heightDp"),
|
|
417
|
+
minPageHeightDp = params.optInt("minPageHeightDp", 1000)
|
|
418
|
+
)
|
|
419
|
+
) { path ->
|
|
420
|
+
promise.resolve(path)
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
override fun readDir(params: ReadableMap, promise: Promise) {
|
|
425
|
+
val path = params.getString("path")
|
|
426
|
+
if (path == null) {
|
|
427
|
+
promise.reject("ERROR", "path is required")
|
|
428
|
+
return
|
|
429
|
+
}
|
|
430
|
+
executor.execute {
|
|
431
|
+
try {
|
|
432
|
+
val result = standalonePrinter.readDir(ReadDirParams(path))
|
|
433
|
+
promise.resolve(Arguments.makeNativeMap(result.toMap()))
|
|
434
|
+
} catch (e: Exception) {
|
|
435
|
+
promise.reject("ERROR", e.message)
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
override fun removeFile(params: ReadableMap, promise: Promise) {
|
|
441
|
+
val path = params.getString("path")
|
|
442
|
+
if (path == null) {
|
|
443
|
+
promise.reject("ERROR", "path is required")
|
|
444
|
+
return
|
|
445
|
+
}
|
|
446
|
+
executor.execute {
|
|
447
|
+
try {
|
|
448
|
+
val result = standalonePrinter.removeFile(RemoveFileParams(path))
|
|
449
|
+
promise.resolve(Arguments.makeNativeMap(result.toMap()))
|
|
450
|
+
} catch (e: Exception) {
|
|
451
|
+
promise.reject("ERROR", e.message)
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
221
456
|
override fun printText(params: ReadableMap, promise: Promise) {
|
|
222
457
|
val text = params.getString("text")
|
|
223
458
|
if (text == null) {
|
|
@@ -355,6 +590,7 @@ class ReactNativePrinterKitModule(reactContext: ReactApplicationContext) :
|
|
|
355
590
|
service.printer.htmlToPdf(
|
|
356
591
|
HtmlToPdfParams(
|
|
357
592
|
html = html,
|
|
593
|
+
outputPath = params.optString("outputPath"),
|
|
358
594
|
pageWidthDp = params.optInt("pageWidthDp", 412),
|
|
359
595
|
heightDp = params.optIntOrNull("heightDp"),
|
|
360
596
|
minPageHeightDp = params.optInt("minPageHeightDp", 1000)
|
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import { TurboModuleRegistry, Platform } from 'react-native';
|
|
4
|
+
|
|
5
|
+
/** How sure the library is that a paired Bluetooth device is a printer. */
|
|
6
|
+
|
|
7
|
+
/** `ALL` lists every paired device, `LIKELY_PRINTERS` hides non-printers, `STRICT` keeps only certain ones. */
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* `null` means "unknown" - the printer did not answer or does not report that condition. It is NOT "ok".
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* `PICTURES` is the public Pictures folder, so the image also shows in the Gallery app; it accepts images
|
|
15
|
+
* only (a `.png`/`.jpg` file name or an `image/...` `mimeType`) and refuses anything else.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The shape `readFile` returns the content in: `base64` (plain), `dataUri` (`data:<type>;base64,...`), `text`
|
|
20
|
+
* (decoded string), `hex` (two lower-case digits per byte) or `bytes` (array of numbers 0..255, max 1 MB).
|
|
21
|
+
*/
|
|
22
|
+
|
|
4
23
|
function getModule() {
|
|
5
24
|
return Platform.OS === 'android' ? TurboModuleRegistry.getEnforcing('ReactNativePrinterKit') : {};
|
|
6
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["TurboModuleRegistry","Platform","getModule","OS","getEnforcing"],"sourceRoot":"../../src","sources":["NativeReactNativePrinterKit.ts"],"mappings":";;AAAA,SAASA,mBAAmB,EAAoBC,QAAQ,QAAQ,cAAc;
|
|
1
|
+
{"version":3,"names":["TurboModuleRegistry","Platform","getModule","OS","getEnforcing"],"sourceRoot":"../../src","sources":["NativeReactNativePrinterKit.ts"],"mappings":";;AAAA,SAASA,mBAAmB,EAAoBC,QAAQ,QAAQ,cAAc;;AAE9E;;AAGA;;AA2DA;AACA;AACA;;AAYA;AACA;AACA;AACA;;AA+HA;AACA;AACA;AACA;;AA2PA,SAASC,SAASA,CAAA,EAAS;EACzB,OAAOD,QAAQ,CAACE,EAAE,KAAK,SAAS,GAC5BH,mBAAmB,CAACI,YAAY,CAAO,uBAAuB,CAAC,GAC9D,CAAC,CAAU;AAClB;AAEA,eAAeF,SAAS,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// Runtime values for the string unions the native module uses, so callers can write
|
|
4
|
+
// `PrinterFilter.LIKELY_PRINTERS` instead of a bare string. Each object is checked
|
|
5
|
+
// against its union with `satisfies`, so a typo or a value the native side does not
|
|
6
|
+
// know fails to compile. The plain strings keep working everywhere too.
|
|
7
|
+
|
|
8
|
+
/** How sure the library is that a paired Bluetooth device is a printer. */
|
|
9
|
+
export const PrinterConfidence = {
|
|
10
|
+
CONFIDENT: 'CONFIDENT',
|
|
11
|
+
LIKELY: 'LIKELY',
|
|
12
|
+
UNKNOWN: 'UNKNOWN'
|
|
13
|
+
};
|
|
14
|
+
/** `ALL` lists every paired device, `LIKELY_PRINTERS` hides non-printers, `STRICT` keeps only certain ones. */
|
|
15
|
+
export const PrinterFilter = {
|
|
16
|
+
ALL: 'ALL',
|
|
17
|
+
LIKELY_PRINTERS: 'LIKELY_PRINTERS',
|
|
18
|
+
STRICT: 'STRICT'
|
|
19
|
+
};
|
|
20
|
+
export const PrinterConnectionType = {
|
|
21
|
+
BLUETOOTH: 'BLUETOOTH',
|
|
22
|
+
NETWORK: 'NETWORK',
|
|
23
|
+
USB: 'USB'
|
|
24
|
+
};
|
|
25
|
+
export const PrinterImageType = {
|
|
26
|
+
PNG: 'PNG',
|
|
27
|
+
JPEG: 'JPEG'
|
|
28
|
+
};
|
|
29
|
+
export const FileLocation = {
|
|
30
|
+
CACHE: 'CACHE',
|
|
31
|
+
APP_FILES: 'APP_FILES',
|
|
32
|
+
DOWNLOADS: 'DOWNLOADS',
|
|
33
|
+
DOCUMENTS: 'DOCUMENTS',
|
|
34
|
+
PICTURES: 'PICTURES',
|
|
35
|
+
CUSTOM_FOLDER: 'CUSTOM_FOLDER'
|
|
36
|
+
};
|
|
37
|
+
/** The shape `readFile` returns the content in. */
|
|
38
|
+
export const ReadFileFormat = {
|
|
39
|
+
BASE64: 'base64',
|
|
40
|
+
DATA_URI: 'dataUri',
|
|
41
|
+
TEXT: 'text',
|
|
42
|
+
HEX: 'hex',
|
|
43
|
+
BYTES: 'bytes'
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=enums.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["PrinterConfidence","CONFIDENT","LIKELY","UNKNOWN","PrinterFilter","ALL","LIKELY_PRINTERS","STRICT","PrinterConnectionType","BLUETOOTH","NETWORK","USB","PrinterImageType","PNG","JPEG","FileLocation","CACHE","APP_FILES","DOWNLOADS","DOCUMENTS","PICTURES","CUSTOM_FOLDER","ReadFileFormat","BASE64","DATA_URI","TEXT","HEX","BYTES"],"sourceRoot":"../../src","sources":["enums.ts"],"mappings":";;AASA;AACA;AACA;AACA;;AAEA;AACA,OAAO,MAAMA,iBAAiB,GAAG;EAC/BC,SAAS,EAAE,WAAW;EACtBC,MAAM,EAAE,QAAQ;EAChBC,OAAO,EAAE;AACX,CAA2E;AAI3E;AACA,OAAO,MAAMC,aAAa,GAAG;EAC3BC,GAAG,EAAE,KAAK;EACVC,eAAe,EAAE,iBAAiB;EAClCC,MAAM,EAAE;AACV,CAAmE;AAGnE,OAAO,MAAMC,qBAAqB,GAAG;EACnCC,SAAS,EAAE,WAAW;EACtBC,OAAO,EAAE,SAAS;EAClBC,GAAG,EAAE;AACP,CAGC;AAID,OAAO,MAAMC,gBAAgB,GAAG;EAC9BC,GAAG,EAAE,KAAK;EACVC,IAAI,EAAE;AACR,CAAyE;AAIzE,OAAO,MAAMC,YAAY,GAAG;EAC1BC,KAAK,EAAE,OAAO;EACdC,SAAS,EAAE,WAAW;EACtBC,SAAS,EAAE,WAAW;EACtBC,SAAS,EAAE,WAAW;EACtBC,QAAQ,EAAE,UAAU;EACpBC,aAAa,EAAE;AACjB,CAAiE;AAGjE;AACA,OAAO,MAAMC,cAAc,GAAG;EAC5BC,MAAM,EAAE,QAAQ;EAChBC,QAAQ,EAAE,SAAS;EACnBC,IAAI,EAAE,MAAM;EACZC,GAAG,EAAE,KAAK;EACVC,KAAK,EAAE;AACT,CAAwD","ignoreList":[]}
|
package/lib/module/index.js
CHANGED
|
@@ -25,16 +25,43 @@ export function requestBluetoothPermission() {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
* Get
|
|
28
|
+
* Get the Bluetooth devices already paired (bonded) with this device, best printer
|
|
29
|
+
* matches first. Every device carries a `confidence`. Pass
|
|
30
|
+
* `{ filter: 'LIKELY_PRINTERS' }` to hide devices that do not look like printers
|
|
31
|
+
* (headphones, watches...), or `extraNameKeywords` for a printer with an unusual name.
|
|
29
32
|
*/
|
|
30
|
-
export function getBondedBluetoothPrinters() {
|
|
31
|
-
return ReactNativePrinterKit.getBondedBluetoothPrinters();
|
|
33
|
+
export function getBondedBluetoothPrinters(params = {}) {
|
|
34
|
+
return ReactNativePrinterKit.getBondedBluetoothPrinters(params);
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
/**
|
|
35
|
-
*
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
* USB printers currently plugged in. Needs a phone with USB host (OTG).
|
|
39
|
+
*/
|
|
40
|
+
export function getUsbPrinters() {
|
|
41
|
+
return ReactNativePrinterKit.getUsbPrinters();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Whether the user already granted this app access to that USB printer.
|
|
46
|
+
*/
|
|
47
|
+
export function hasUsbPermission(params) {
|
|
48
|
+
return ReactNativePrinterKit.hasUsbPermission(params);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Shows the system USB permission dialog. Call before `connectPrinter` with
|
|
53
|
+
* `type: 'USB'`. The grant is lost when the app is reinstalled.
|
|
54
|
+
*/
|
|
55
|
+
export function requestUsbPermission(params) {
|
|
56
|
+
return ReactNativePrinterKit.requestUsbPermission(params);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Connect to a printer over Bluetooth (default; paired printer's MAC address),
|
|
61
|
+
* Wi-Fi/LAN (`type: 'NETWORK'`, `address` = IP) or USB (`type: 'USB'` with
|
|
62
|
+
* `vendorId`/`productId`). The connection survives the app being swiped from
|
|
63
|
+
* Recents, and is reconnected to automatically the next time the app starts.
|
|
64
|
+
* Resolves `false` if it could not connect.
|
|
38
65
|
*/
|
|
39
66
|
export function connectPrinter(params) {
|
|
40
67
|
return ReactNativePrinterKit.connectPrinter(params);
|
|
@@ -61,6 +88,77 @@ export function getConnectedPrinter() {
|
|
|
61
88
|
return ReactNativePrinterKit.getConnectedPrinter();
|
|
62
89
|
}
|
|
63
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Whether a printer is connected and currently accepts data. Does not check
|
|
93
|
+
* paper or cover - use `getPrinterStatus()`.
|
|
94
|
+
*/
|
|
95
|
+
export function isPrinterReady() {
|
|
96
|
+
return ReactNativePrinterKit.isPrinterReady();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Asks the printer for its state (online / paper out / cover open / error).
|
|
101
|
+
* Many printers do not answer: then `responded` is `false` and the other fields
|
|
102
|
+
* are `null` (unknown, not "ok"). Some printers report an open cover as
|
|
103
|
+
* `paperOut`, so treat `paperOut: true` as "no paper or cover open".
|
|
104
|
+
*/
|
|
105
|
+
export function getPrinterStatus(params = {}) {
|
|
106
|
+
return ReactNativePrinterKit.getPrinterStatus(params);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Prints a short ASCII test page.
|
|
111
|
+
*/
|
|
112
|
+
export function printTestPage() {
|
|
113
|
+
return ReactNativePrinterKit.printTestPage();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Copies a file (e.g. the PDF from `htmlToPdf`) to cache, app storage, public
|
|
118
|
+
* Downloads/Documents or a chosen folder. Never rejects: check `result.success`.
|
|
119
|
+
*/
|
|
120
|
+
export function saveFile(params) {
|
|
121
|
+
return ReactNativePrinterKit.saveFile(params);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Reads ONE file and returns its content in the shape `format` asks for: `base64` (default), `dataUri`
|
|
126
|
+
* (`data:<type>;base64,...`), `text` (optionally with an `encoding`), `hex` or `bytes` (array of numbers,
|
|
127
|
+
* max 1 MB). `path` is an absolute path or the `content://` Uri `saveFile` returned. A file over `maxBytes`
|
|
128
|
+
* (default 10 MB) is refused instead of loaded. Never rejects: check `result.success`.
|
|
129
|
+
*/
|
|
130
|
+
export function readFile(params) {
|
|
131
|
+
return ReactNativePrinterKit.readFile(params);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Renders HTML to ONE image file (PNG, or JPEG with `imageType: 'JPEG'`) and returns its path, or `null`
|
|
136
|
+
* on failure. Pass `outputPath` to choose the file name. A very tall page can run out of memory (then
|
|
137
|
+
* `null`). For base64 pass the returned path to `readFile`.
|
|
138
|
+
*/
|
|
139
|
+
export function htmlToImage(params) {
|
|
140
|
+
return ReactNativePrinterKit.htmlToImage(params);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Reads ONE folder: the files and folders directly inside it, folders first and then A-Z (it does not
|
|
145
|
+
* go into sub-folders; call it again with an entry's `path` to go deeper). `result.names` is just the
|
|
146
|
+
* names, `result.entries` has `name`, `path`, `isDirectory`, `sizeBytes` and `lastModified`. A path that
|
|
147
|
+
* is a file, missing or relative is refused. Never rejects: check `result.success`.
|
|
148
|
+
*/
|
|
149
|
+
export function readDir(params) {
|
|
150
|
+
return ReactNativePrinterKit.readDir(params);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Deletes ONE file: an absolute path, or the `content://` Uri `saveFile` returned. Never a folder or a
|
|
155
|
+
* pattern; cannot be undone. A missing file is a failure ("File not found"). Never rejects: check
|
|
156
|
+
* `result.success`.
|
|
157
|
+
*/
|
|
158
|
+
export function removeFile(params) {
|
|
159
|
+
return ReactNativePrinterKit.removeFile(params);
|
|
160
|
+
}
|
|
161
|
+
|
|
64
162
|
/**
|
|
65
163
|
* Print raw text using the printer's built-in font (ASCII only - use
|
|
66
164
|
* printHtml() for Bangla or other non-Latin scripts).
|
|
@@ -124,6 +222,9 @@ export function openFile(params) {
|
|
|
124
222
|
return ReactNativePrinterKit.openFile(params);
|
|
125
223
|
}
|
|
126
224
|
|
|
225
|
+
// Export enum-like constants (usable at runtime, and as types of the same name)
|
|
226
|
+
export { FileLocation, PrinterConfidence, PrinterConnectionType, PrinterFilter, PrinterImageType, ReadFileFormat } from "./enums.js";
|
|
227
|
+
|
|
127
228
|
// Export types
|
|
128
229
|
|
|
129
230
|
// Export native module
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["ReactNativePrinterKit","isBluetoothEnabled","hasBluetoothPermission","requestBluetoothPermission","getBondedBluetoothPrinters","
|
|
1
|
+
{"version":3,"names":["ReactNativePrinterKit","isBluetoothEnabled","hasBluetoothPermission","requestBluetoothPermission","getBondedBluetoothPrinters","params","getUsbPrinters","hasUsbPermission","requestUsbPermission","connectPrinter","disconnectPrinter","isConnectedPrinter","getConnectedPrinter","isPrinterReady","getPrinterStatus","printTestPage","saveFile","readFile","htmlToImage","readDir","removeFile","printText","printImage","printImageBase64","pdfToImage","printPdf","htmlToPdf","printHtml","openFile","FileLocation","PrinterConfidence","PrinterConnectionType","PrinterFilter","PrinterImageType","ReadFileFormat"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]}
|