@craft-native/android 0.0.140 → 0.0.142

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 CHANGED
@@ -97,13 +97,17 @@ craft android build --native-bundle ../native-screen.js
97
97
  ```
98
98
 
99
99
  Native mode maps STX `View`, `SafeAreaView`, `Text`, `Button`, `Link`,
100
- `Pressable`, `TouchableOpacity`, `TouchableHighlight`, `TextInput`, `Picker`, `Modal`, `Switch`, `Slider`, `ActivityIndicator`, `Image`, `ScrollView`,
100
+ `Pressable`, `TouchableOpacity`, `TouchableHighlight`, `TextInput`, `Picker`, `Modal`, `Switch`, `Slider`, `ActivityIndicator`, `Image`, `Video`, `ScrollView`,
101
101
  and `FlatList` to Android views. `Picker` renders `<select>`/`<option>` values
102
102
  with `onValueChange` or `onChange`. `Modal` is parent-scoped and supports
103
103
  `visible`, `transparent`, `animationType`, `onShow`, `onDismiss`, and
104
104
  `onRequestClose` for Android back handling. `Switch` supports state-aware `trackColor`
105
105
  and `thumbColor`, while `Slider` supports track/thumb tint props and `step`
106
- snapping. `Image` reports load lifecycle events and structured failures.
106
+ snapping. `ActivityIndicator` keeps a visible stopped indicator genuinely
107
+ non-animated when `animating={false}` and `hidesWhenStopped={false}`. `Image`
108
+ reports load lifecycle events and structured failures. `Video` uses the native
109
+ `VideoView` for URI playback with autoplay, pause, looping, mute, controls, and
110
+ resize-mode props.
107
111
  `FlatList` uses
108
112
  `RecyclerView`, stable IDs, and `DiffUtil` for keyed recycling, grids,
109
113
  horizontal and inverted layouts, list chrome, and end-reached pagination.
@@ -116,6 +120,8 @@ same shrink defaults as the iOS renderer; buttons and editable fields retain
116
120
  their intrinsic width unless explicitly configured.
117
121
  Wrapped containers also honor `alignContent` (`center`, `flex-end`,
118
122
  `space-between`, `space-around`, and `stretch`) consistently across hosts.
123
+ Shared wrapped-line IDs are accepted only when they are complete and monotonic;
124
+ invalid bridge data falls back to the host layout implementation.
119
125
  Push, replace, and back preserve the
120
126
  previous screen's views and JavaScript state; Android's system back button pops
121
127
  the route. Native mode accepts neither `--html-path` nor `--dev-server`. Its
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@craft-native/android",
3
- "version": "0.0.140",
3
+ "version": "0.0.142",
4
4
  "homepage": "https://github.com/craft-native/craft/tree/main/packages/android#readme",
5
5
  "repository": {
6
6
  "type": "git",
@@ -35,6 +35,7 @@ import com.google.mlkit.vision.objects.defaults.ObjectDetectorOptions
35
35
  import com.google.mlkit.vision.text.TextRecognition
36
36
  import com.google.mlkit.vision.text.latin.TextRecognizerOptions
37
37
  import org.json.JSONArray
38
+ import kotlin.math.roundToInt
38
39
  import androidx.biometric.BiometricManager
39
40
  import androidx.biometric.BiometricPrompt
40
41
  import androidx.fragment.app.FragmentActivity
@@ -231,6 +232,54 @@ object CraftNative {
231
232
  private external fun nativeGetDeviceInfo(activity: Activity): String?
232
233
  private external fun nativeGetMemoryUsage(): String?
233
234
  private external fun nativeLog(message: String): Boolean
235
+ private external fun nativeFlexRow(
236
+ available: Float,
237
+ gap: Float,
238
+ justify: Int,
239
+ basis: FloatArray,
240
+ grow: FloatArray,
241
+ shrink: FloatArray,
242
+ min: FloatArray,
243
+ max: FloatArray,
244
+ margins: FloatArray,
245
+ ): FloatArray?
246
+ private external fun nativeFlexLineBreaks(
247
+ available: Float,
248
+ gap: Float,
249
+ wrap: Int,
250
+ basis: FloatArray,
251
+ margins: FloatArray,
252
+ ): FloatArray?
253
+ private external fun nativeFlexLineDistribution(
254
+ available: Float,
255
+ gap: Float,
256
+ alignment: Int,
257
+ lineCrosses: FloatArray,
258
+ ): FloatArray?
259
+ private external fun nativeCrossAxisPosition(
260
+ available: Float,
261
+ size: Float,
262
+ leading: Float,
263
+ trailing: Float,
264
+ alignment: Int,
265
+ ): Float
266
+ private external fun nativeGrid(
267
+ availableWidth: Float,
268
+ availableHeight: Float,
269
+ columns: Int,
270
+ columnGap: Float,
271
+ rowGap: Float,
272
+ intrinsicWidth: FloatArray,
273
+ intrinsicHeight: FloatArray,
274
+ explicitWidth: FloatArray,
275
+ explicitHeight: FloatArray,
276
+ minWidth: FloatArray,
277
+ maxWidth: FloatArray,
278
+ minHeight: FloatArray,
279
+ maxHeight: FloatArray,
280
+ margins: FloatArray,
281
+ flags: FloatArray,
282
+ ): FloatArray?
234
283
  private external fun nativeClipboardRead(activity: Activity): String?
235
284
  private external fun nativeClipboardWrite(activity: Activity, text: String): Boolean
236
285
  private external fun nativeOpenUrl(activity: Activity, url: String): Boolean
@@ -386,6 +435,94 @@ object CraftNative {
386
435
  }
387
436
  }
388
437
 
438
+ /** Resolve a flex line in Zig, or null for the Kotlin fallback. */
439
+ fun flexRow(
440
+ available: Float,
441
+ gap: Float,
442
+ justify: Int,
443
+ basis: FloatArray,
444
+ grow: FloatArray,
445
+ shrink: FloatArray,
446
+ min: FloatArray,
447
+ max: FloatArray,
448
+ margins: FloatArray,
449
+ ): FloatArray? {
450
+ if (!isAvailable) return null
451
+ return try {
452
+ // The shared result stores widths in the first half and the
453
+ // corresponding main-axis positions in the second half.
454
+ nativeFlexRow(available, gap, justify, basis, grow, shrink, min, max, margins)
455
+ ?.takeIf { it.size >= basis.size && it.all { value -> value.isFinite() } }
456
+ } catch (e: UnsatisfiedLinkError) {
457
+ null
458
+ }
459
+ }
460
+
461
+ /** Form wrapped flex lines in Zig, or null for the Kotlin fallback. */
462
+ fun flexLines(available: Float, gap: Float, wrap: Boolean, basis: FloatArray, margins: FloatArray): IntArray? {
463
+ if (!isAvailable) return null
464
+ return try {
465
+ nativeFlexLineBreaks(available, gap, if (wrap) 1 else 0, basis, margins)
466
+ ?.takeIf { it.size >= basis.size && it.all { value -> value.isFinite() } }
467
+ ?.map { it.roundToInt() }
468
+ ?.toIntArray()
469
+ } catch (e: UnsatisfiedLinkError) {
470
+ null
471
+ }
472
+ }
473
+
474
+ /** Distribute wrapped flex lines in Zig, or null for the Kotlin fallback. */
475
+ fun flexLineDistribution(available: Float, gap: Float, alignment: Int, lineCrosses: FloatArray): Pair<FloatArray, FloatArray>? {
476
+ if (!isAvailable || lineCrosses.isEmpty()) return null
477
+ return try {
478
+ nativeFlexLineDistribution(available, gap, alignment, lineCrosses)
479
+ ?.takeIf { it.size >= lineCrosses.size * 2 && it.all { value -> value.isFinite() } }
480
+ ?.let { flattened ->
481
+ flattened.copyOfRange(0, lineCrosses.size) to flattened.copyOfRange(lineCrosses.size, lineCrosses.size * 2)
482
+ }
483
+ } catch (e: UnsatisfiedLinkError) {
484
+ null
485
+ }
486
+ }
487
+
488
+ /** Resolve one flex item's cross-axis offset in Zig, or null for fallback. */
489
+ fun crossAxisPosition(available: Float, size: Float, leading: Float, trailing: Float, alignment: Int): Float? {
490
+ if (!isAvailable) return null
491
+ return try {
492
+ nativeCrossAxisPosition(available, size, leading, trailing, alignment)
493
+ .takeIf { it.isFinite() }
494
+ } catch (e: UnsatisfiedLinkError) {
495
+ null
496
+ }
497
+ }
498
+
499
+ /** Resolve equal-track grid frames in Zig, or null for Kotlin fallback. */
500
+ fun grid(
501
+ availableWidth: Float,
502
+ availableHeight: Float,
503
+ columns: Int,
504
+ columnGap: Float,
505
+ rowGap: Float,
506
+ intrinsicWidth: FloatArray,
507
+ intrinsicHeight: FloatArray,
508
+ explicitWidth: FloatArray,
509
+ explicitHeight: FloatArray,
510
+ minWidth: FloatArray,
511
+ maxWidth: FloatArray,
512
+ minHeight: FloatArray,
513
+ maxHeight: FloatArray,
514
+ margins: FloatArray,
515
+ flags: FloatArray,
516
+ ): FloatArray? {
517
+ if (!isAvailable) return null
518
+ return try {
519
+ nativeGrid(availableWidth, availableHeight, columns, columnGap, rowGap, intrinsicWidth, intrinsicHeight, explicitWidth, explicitHeight, minWidth, maxWidth, minHeight, maxHeight, margins, flags)
520
+ ?.takeIf { it.size >= intrinsicWidth.size * 4 && it.all { value -> value.isFinite() } }
521
+ } catch (e: UnsatisfiedLinkError) {
522
+ null
523
+ }
524
+ }
525
+
389
526
  /**
390
527
  * The clipboard's text, or null to use the Kotlin implementation.
391
528
  *