craft-native 0.0.354 → 0.0.358

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.
@@ -162,6 +162,9 @@ class CraftNativeMutationDocument {
162
162
  )
163
163
  }
164
164
 
165
+ /** The committed root may have any protocol id supplied by the compiler. */
166
+ fun document(): JSONObject? = rootId?.let { materialize(it, nodes) }
167
+
165
168
  fun node(id: String): JSONObject? = materialize(id, nodes)
166
169
 
167
170
  /** Reserve surviving protocol nodes before reusing an authored keyed slot. */
@@ -899,6 +899,7 @@ internal class CraftNativeFlexLayout(context: Context) : LinearLayout(context) {
899
899
  private var wrapReverse = false
900
900
  private var unboundedWidth = false
901
901
  private var authoredPadding = intArrayOf(0, 0, 0, 0)
902
+ private var windowSafeAreaInsets = intArrayOf(0, 0, 0, 0)
902
903
  private var safeAreaPadding = intArrayOf(0, 0, 0, 0)
903
904
  private var applyingPadding = false
904
905
  private var safeAreaEdges = setOf("top", "right", "bottom", "left")
@@ -962,18 +963,20 @@ internal class CraftNativeFlexLayout(context: Context) : LinearLayout(context) {
962
963
  }
963
964
 
964
965
  fun setWindowSafeInsets(left: Int, top: Int, right: Int, bottom: Int) {
965
- val insets = intArrayOf(left, top, right, bottom)
966
- safeAreaPadding = intArrayOf(
967
- if ("left" in safeAreaEdges) insets[0] else 0,
968
- if ("top" in safeAreaEdges) insets[1] else 0,
969
- if ("right" in safeAreaEdges) insets[2] else 0,
970
- if ("bottom" in safeAreaEdges) insets[3] else 0,
971
- )
966
+ windowSafeAreaInsets = intArrayOf(left, top, right, bottom)
972
967
  applySafeAreaPadding()
973
968
  invalidateMeasurements()
974
969
  }
975
970
 
976
971
  private fun applySafeAreaPadding() {
972
+ // Keep the unfiltered insets so changing edges takes effect immediately,
973
+ // including restoring an edge without another platform inset dispatch.
974
+ safeAreaPadding = intArrayOf(
975
+ if ("left" in safeAreaEdges) windowSafeAreaInsets[0] else 0,
976
+ if ("top" in safeAreaEdges) windowSafeAreaInsets[1] else 0,
977
+ if ("right" in safeAreaEdges) windowSafeAreaInsets[2] else 0,
978
+ if ("bottom" in safeAreaEdges) windowSafeAreaInsets[3] else 0,
979
+ )
977
980
  setPadding(authoredPadding[0], authoredPadding[1], authoredPadding[2], authoredPadding[3])
978
981
  }
979
982
 
@@ -5147,7 +5150,7 @@ class MainActivity : AppCompatActivity() {
5147
5150
 
5148
5151
  private fun refreshScreenTheme(screen: Screen) {
5149
5152
  applyScreenBackground(screen)
5150
- screen.mutations.node("root")?.let { renderCommitted(screen, it) }
5153
+ screen.mutations.document()?.let { renderCommitted(screen, it) }
5151
5154
  screen.controls.values.mapNotNull {
5152
5155
  when (it) {
5153
5156
  is CraftNativeRefreshableFlatList -> it.list
@@ -5165,7 +5168,7 @@ class MainActivity : AppCompatActivity() {
5165
5168
  private fun updateSafeAreaViews() {
5166
5169
  if (!::root.isInitialized) return
5167
5170
  val active = visibleScreen ?: screens.lastOrNull { it.active }
5168
- val rootNode = active?.mutations?.node("root")
5171
+ val rootNode = active?.mutations?.document()
5169
5172
  val safeRoot = rootNode?.let { canonicalType(it.optString("type")) == "SafeAreaView" } == true
5170
5173
  root.setPadding(
5171
5174
  if (safeRoot) 0 else windowSafeInsets[0],
@@ -5184,7 +5187,7 @@ class MainActivity : AppCompatActivity() {
5184
5187
  * against zero insets.
5185
5188
  */
5186
5189
  private fun updateSafeAreaInsets(screen: Screen) {
5187
- val rootNode = screen.mutations.node("root")
5190
+ val rootNode = screen.mutations.document()
5188
5191
  val safeRoot = rootNode?.let { canonicalType(it.optString("type")) == "SafeAreaView" } == true
5189
5192
  val tree = screen.view.getChildAt(0) as? CraftNativeFlexLayout
5190
5193
  if (safeRoot) tree?.setWindowSafeInsets(windowSafeInsets[0], windowSafeInsets[1], windowSafeInsets[2], windowSafeInsets[3])
@@ -5511,6 +5514,17 @@ class MainActivity : AppCompatActivity() {
5511
5514
  }
5512
5515
  }
5513
5516
 
5517
+ private fun updateStatusBarProps(screen: Screen, props: JSONObject) {
5518
+ val style = craftNativeOptionalString(props.opt("barStyle"))
5519
+ val hidden = if (props.has("hidden") && !props.isNull("hidden")) craftNativeBoolean(props.opt("hidden")) else null
5520
+ val changed = screen.statusBarStyle != style || screen.statusBarHidden != hidden
5521
+ screen.statusBarStyle = style
5522
+ screen.statusBarHidden = hidden
5523
+ // MUTATE can reconcile this node without committing the whole screen.
5524
+ // Retained screens keep their props until their next visible commit.
5525
+ if (changed && visibleScreen === screen) applyStatusBar(screen)
5526
+ }
5527
+
5514
5528
  private fun applyStatusBar(screen: Screen) {
5515
5529
  val controller = WindowCompat.getInsetsController(window, window.decorView)
5516
5530
  val night = (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES
@@ -5582,8 +5596,7 @@ class MainActivity : AppCompatActivity() {
5582
5596
  isLongClickable = selectable
5583
5597
  }
5584
5598
  "StatusBar" -> (previous as? CraftNativeFlexLayout ?: CraftNativeFlexLayout(this)).apply {
5585
- screen.statusBarStyle = craftNativeOptionalString(props.opt("barStyle"))
5586
- screen.statusBarHidden = if (props.has("hidden") && !props.isNull("hidden")) craftNativeBoolean(props.opt("hidden")) else null
5599
+ updateStatusBarProps(screen, props)
5587
5600
  visibility = View.GONE
5588
5601
  }
5589
5602
  "RefreshControl" -> (previous as? CraftNativeFlexLayout ?: CraftNativeFlexLayout(this)).apply {
package/dist/cli.js CHANGED
@@ -3047,7 +3047,7 @@ function pinCraftNativeDependency(packagePath, craftVersion) {
3047
3047
  `);
3048
3048
  }
3049
3049
  // package.json
3050
- var version = "0.0.354";
3050
+ var version = "0.0.358";
3051
3051
 
3052
3052
  // bin/cli.ts
3053
3053
  var spawnedFrom = process6.env[CRAFT_CLI_SPAWN_MARKER];
package/dist/index.cjs CHANGED
@@ -375,7 +375,7 @@ function craftBinaryNotFoundMessage(triedPath) {
375
375
  `);
376
376
  }
377
377
  // package.json
378
- var version = "0.0.354";
378
+ var version = "0.0.358";
379
379
 
380
380
  // src/sdk-version.ts
381
381
  var SDK_VERSION = version;
package/dist/index.js CHANGED
@@ -117,7 +117,7 @@ function craftBinaryNotFoundMessage(triedPath) {
117
117
  `);
118
118
  }
119
119
  // package.json
120
- var version = "0.0.354";
120
+ var version = "0.0.358";
121
121
 
122
122
  // src/sdk-version.ts
123
123
  var SDK_VERSION = version;
package/dist/types.d.ts CHANGED
@@ -1632,11 +1632,13 @@ export interface CraftHapticsAPI {
1632
1632
  * `screen_sharing.zig` for the signal table.
1633
1633
  */
1634
1634
  export interface CraftScreenSharingAPI {
1635
+ /** Read current native indicators. Rejects if a bounded Accessibility read is incomplete. */
1635
1636
  getState(): Promise<ScreenSharingState>;
1636
1637
  /**
1637
1638
  * Start polling. Emits `craft:screenSharing:change` whenever the resolved
1638
- * state differs, including once immediately. Interval is clamped to
1639
- * 250ms–60s.
1639
+ * confirmed state differs, including once after the first complete read.
1640
+ * Incomplete native reads are retried without emitting a false stop.
1641
+ * Interval is clamped to 250ms–60s.
1640
1642
  */
1641
1643
  watch(intervalMs?: number): Promise<{
1642
1644
  ok: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "craft-native",
3
- "version": "0.0.354",
3
+ "version": "0.0.358",
4
4
  "type": "module",
5
5
  "description": "Build desktop apps with web languages - TypeScript SDK for Craft",
6
6
  "author": "Chris Breuer <chris@stacksjs.org>",