craft-native 0.0.233 → 0.0.235
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/dist/android/templates/MainActivityNative.kt.template +59 -1
- package/dist/cli.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/ios/src/index.d.ts +4 -1
- package/dist/ios/src/index.js +10 -1
- package/dist/ios/templates/CraftNativeScreen.swift +4 -2
- package/package.json +1 -1
|
@@ -8,6 +8,7 @@ import android.content.Context
|
|
|
8
8
|
import android.content.pm.PackageManager
|
|
9
9
|
import android.content.res.ColorStateList
|
|
10
10
|
import android.content.res.Configuration
|
|
11
|
+
import android.content.res.Resources
|
|
11
12
|
import android.database.ContentObserver
|
|
12
13
|
import android.content.Intent
|
|
13
14
|
import android.app.PictureInPictureParams
|
|
@@ -3631,6 +3632,34 @@ private class CraftNativeSideBorderDrawable(
|
|
|
3631
3632
|
override fun getOpacity(): Int = PixelFormat.TRANSLUCENT
|
|
3632
3633
|
}
|
|
3633
3634
|
|
|
3635
|
+
/** Protects only the native three-button region; content keeps its authored background. */
|
|
3636
|
+
private class CraftNativeNavigationBarProtection : Drawable() {
|
|
3637
|
+
private val paint = Paint()
|
|
3638
|
+
private var left = 0
|
|
3639
|
+
private var right = 0
|
|
3640
|
+
private var bottom = 0
|
|
3641
|
+
|
|
3642
|
+
fun update(color: Int, left: Int, right: Int, bottom: Int) {
|
|
3643
|
+
if (paint.color == color && this.left == left && this.right == right && this.bottom == bottom) return
|
|
3644
|
+
paint.color = color
|
|
3645
|
+
this.left = left
|
|
3646
|
+
this.right = right
|
|
3647
|
+
this.bottom = bottom
|
|
3648
|
+
invalidateSelf()
|
|
3649
|
+
}
|
|
3650
|
+
|
|
3651
|
+
override fun draw(canvas: Canvas) {
|
|
3652
|
+
if (left > 0) canvas.drawRect(bounds.left.toFloat(), bounds.top.toFloat(), (bounds.left + left).toFloat(), bounds.bottom.toFloat(), paint)
|
|
3653
|
+
if (right > 0) canvas.drawRect((bounds.right - right).toFloat(), bounds.top.toFloat(), bounds.right.toFloat(), bounds.bottom.toFloat(), paint)
|
|
3654
|
+
if (bottom > 0) canvas.drawRect(bounds.left.toFloat(), (bounds.bottom - bottom).toFloat(), bounds.right.toFloat(), bounds.bottom.toFloat(), paint)
|
|
3655
|
+
}
|
|
3656
|
+
|
|
3657
|
+
override fun setAlpha(alpha: Int) { paint.alpha = alpha; invalidateSelf() }
|
|
3658
|
+
override fun setColorFilter(filter: ColorFilter?) { paint.colorFilter = filter; invalidateSelf() }
|
|
3659
|
+
@Suppress("DEPRECATION")
|
|
3660
|
+
override fun getOpacity(): Int = PixelFormat.TRANSLUCENT
|
|
3661
|
+
}
|
|
3662
|
+
|
|
3634
3663
|
/** WebView-free host for a route bundle compiled by `stx native compile`. */
|
|
3635
3664
|
class MainActivity : AppCompatActivity() {
|
|
3636
3665
|
private class Screen(
|
|
@@ -3805,6 +3834,8 @@ class MainActivity : AppCompatActivity() {
|
|
|
3805
3834
|
private var initialDeepLinkClaimed = false
|
|
3806
3835
|
private var defaultTextColor = Color.WHITE
|
|
3807
3836
|
private var windowSafeInsets = intArrayOf(0, 0, 0, 0)
|
|
3837
|
+
private var navigationButtonInsets = intArrayOf(0, 0, 0)
|
|
3838
|
+
private val navigationBarProtection = CraftNativeNavigationBarProtection()
|
|
3808
3839
|
private var useMessagePorts = false
|
|
3809
3840
|
private val imageExecutor = Executors.newFixedThreadPool(2)
|
|
3810
3841
|
private val imageCache by lazy { CraftNativeImageCache(File(cacheDir, "craft-native-images")) }
|
|
@@ -3844,10 +3875,17 @@ class MainActivity : AppCompatActivity() {
|
|
|
3844
3875
|
if (savedInstanceState == null) pendingNotificationTap = notificationTap(intent)
|
|
3845
3876
|
setContentView(R.layout.activity_main)
|
|
3846
3877
|
root = findViewById(R.id.native_root)
|
|
3878
|
+
root.foreground = navigationBarProtection
|
|
3847
3879
|
ViewCompat.setOnApplyWindowInsetsListener(root) { view, insets ->
|
|
3848
3880
|
val safe = insets.getInsets(WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout())
|
|
3849
3881
|
val ime = insets.getInsets(WindowInsetsCompat.Type.ime())
|
|
3850
3882
|
windowSafeInsets = intArrayOf(safe.left, safe.top, safe.right, safe.bottom)
|
|
3883
|
+
val tappable = insets.getInsets(WindowInsetsCompat.Type.tappableElement())
|
|
3884
|
+
val buttons = intArrayOf(tappable.left, tappable.right, tappable.bottom)
|
|
3885
|
+
if (!navigationButtonInsets.contentEquals(buttons)) {
|
|
3886
|
+
navigationButtonInsets = buttons
|
|
3887
|
+
visibleScreen?.let(::applyScreenBackground)
|
|
3888
|
+
}
|
|
3851
3889
|
keyboardInset = max(0, ime.bottom - safe.bottom)
|
|
3852
3890
|
updateSafeAreaViews()
|
|
3853
3891
|
updateKeyboardAvoidingViews()
|
|
@@ -4576,13 +4614,33 @@ class MainActivity : AppCompatActivity() {
|
|
|
4576
4614
|
// only the visible one may change the colour behind system bars.
|
|
4577
4615
|
if (visibleScreen === screen) {
|
|
4578
4616
|
root.setBackgroundColor(background)
|
|
4617
|
+
// Android 15's launcher taskbar can retain system-themed button
|
|
4618
|
+
// colours even when the app requests another icon appearance.
|
|
4619
|
+
// Match that palette only behind tappable navigation buttons.
|
|
4620
|
+
// Gesture navigation and authored screen/status backgrounds stay
|
|
4621
|
+
// edge-to-edge; no global theme or system setting is changed.
|
|
4622
|
+
val protectButtons = Build.VERSION.SDK_INT >= 35 && navigationButtonInsets.any { it > 0 }
|
|
4623
|
+
val systemNight = Resources.getSystem().configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
|
|
4624
|
+
val navigationBackground = if (protectButtons) {
|
|
4625
|
+
getColor(if (systemNight) android.R.color.system_neutral1_900 else android.R.color.system_neutral1_50)
|
|
4626
|
+
} else background
|
|
4627
|
+
navigationBarProtection.update(navigationBackground,
|
|
4628
|
+
if (protectButtons) navigationButtonInsets[0] else 0,
|
|
4629
|
+
if (protectButtons) navigationButtonInsets[1] else 0,
|
|
4630
|
+
if (protectButtons) navigationButtonInsets[2] else 0)
|
|
4579
4631
|
WindowCompat.getInsetsController(window, window.decorView)
|
|
4580
|
-
.isAppearanceLightNavigationBars = Color.luminance(
|
|
4632
|
+
.isAppearanceLightNavigationBars = Color.luminance(navigationBackground) >= 0.5f
|
|
4581
4633
|
// Android 15+ draws the root behind transparent system bars.
|
|
4582
4634
|
// Older releases still paint separate window bar surfaces.
|
|
4583
4635
|
if (Build.VERSION.SDK_INT < 35) {
|
|
4584
4636
|
window.statusBarColor = background
|
|
4585
4637
|
window.navigationBarColor = background
|
|
4638
|
+
} else {
|
|
4639
|
+
// Android 15 still overlays a three-button scrim by
|
|
4640
|
+
// default. The root already paints this inset and the
|
|
4641
|
+
// glyph appearance above follows its actual luminance.
|
|
4642
|
+
window.navigationBarColor = Color.TRANSPARENT
|
|
4643
|
+
window.isNavigationBarContrastEnforced = false
|
|
4586
4644
|
}
|
|
4587
4645
|
}
|
|
4588
4646
|
}
|
package/dist/cli.js
CHANGED
|
@@ -3424,7 +3424,7 @@ function pinCraftNativeDependency(packagePath, craftVersion) {
|
|
|
3424
3424
|
`);
|
|
3425
3425
|
}
|
|
3426
3426
|
// package.json
|
|
3427
|
-
var version = "0.0.
|
|
3427
|
+
var version = "0.0.235";
|
|
3428
3428
|
|
|
3429
3429
|
// bin/cli.ts
|
|
3430
3430
|
var spawnedFrom = process6.env[CRAFT_CLI_SPAWN_MARKER];
|
package/dist/index.cjs
CHANGED
package/dist/index.js
CHANGED
package/dist/ios/src/index.d.ts
CHANGED
|
@@ -503,7 +503,10 @@ export declare function installRuntime(output: string, runtimeDir: string): Prom
|
|
|
503
503
|
* valid Swift type.
|
|
504
504
|
*/
|
|
505
505
|
export declare function productName(name: string): string;
|
|
506
|
-
/** Restore package-owned Swift
|
|
506
|
+
/** Restore package-owned Swift, retaining Xcode metadata and bundled screens.
|
|
507
|
+
* Xcode Cloud assigns the distributed build number independently of the source
|
|
508
|
+
* config; keep the packaged runtime identity in step with Apple's build.
|
|
509
|
+
*/
|
|
507
510
|
export declare function restoreShell(output: string): void;
|
|
508
511
|
export { assertNoApplicationSwiftSources, findApplicationSwiftSources } from './source-audit.js';
|
|
509
512
|
export declare function init(options: InitOptions): Promise<void>;
|
package/dist/ios/src/index.js
CHANGED
|
@@ -1057,8 +1057,17 @@ function productName(name) {
|
|
|
1057
1057
|
return /^\d/.test(joined) ? `App${joined}` : joined;
|
|
1058
1058
|
}
|
|
1059
1059
|
function restoreShell(output) {
|
|
1060
|
-
const
|
|
1060
|
+
const file = join3(output, "craft.config.json");
|
|
1061
|
+
const config = JSON.parse(readFileSync2(file, "utf8"));
|
|
1062
|
+
const cloudBuild = process.env.CI_BUILD_NUMBER;
|
|
1063
|
+
if (cloudBuild !== undefined) {
|
|
1064
|
+
if (!/^[1-9]\d*$/.test(cloudBuild) || cloudBuild.trim() !== cloudBuild)
|
|
1065
|
+
throw new Error("CI_BUILD_NUMBER must be a positive integer");
|
|
1066
|
+
config.buildNumber = cloudBuild;
|
|
1067
|
+
}
|
|
1061
1068
|
writeShell(output, config);
|
|
1069
|
+
if (cloudBuild !== undefined)
|
|
1070
|
+
writeFileSync2(file, JSON.stringify(config, null, 2));
|
|
1062
1071
|
}
|
|
1063
1072
|
function writeShell(output, config) {
|
|
1064
1073
|
if (!config.appName || !/^[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)+$/.test(config.bundleId))
|
|
@@ -7454,7 +7454,6 @@ final class CraftNativeScreenController: UIViewController, UIScrollViewDelegate,
|
|
|
7454
7454
|
var traits: UIAccessibilityTraits = []
|
|
7455
7455
|
switch type {
|
|
7456
7456
|
case "Slider", "Picker", "DatePicker": traits.insert(.adjustable)
|
|
7457
|
-
case "Switch": traits.insert(.button)
|
|
7458
7457
|
default: break
|
|
7459
7458
|
}
|
|
7460
7459
|
switch role ?? type.lowercased() {
|
|
@@ -7496,7 +7495,10 @@ final class CraftNativeScreenController: UIViewController, UIScrollViewDelegate,
|
|
|
7496
7495
|
// that is what UI tests and VoiceOver read focus from. Setting them
|
|
7497
7496
|
// froze them, so it read as static text that never had focus ("neither
|
|
7498
7497
|
// element nor any descendant has keyboard focus"); it keeps its own.
|
|
7499
|
-
|
|
7498
|
+
// UISwitch also owns its native identity and enabled/on state.
|
|
7499
|
+
// Assigning .button changes its legacy AX type into a button while
|
|
7500
|
+
// modern XCTest still identifies its UIKit class as a switch.
|
|
7501
|
+
if view is UITextView || view is UISwitch { return }
|
|
7500
7502
|
view.accessibilityTraits = traits
|
|
7501
7503
|
}
|
|
7502
7504
|
|