react-native-ensys-camera-x 1.0.9 → 1.0.10

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.
@@ -275,8 +275,10 @@ class CameraTheme(
275
275
  val prefs = context.getSharedPreferences("CameraSettings", Context.MODE_PRIVATE)
276
276
  val jsonString = prefs.getString("cameraTheme", null)
277
277
 
278
- // Default palette (Dark)
279
- var colors = CameraThemeColors(
278
+ // Default palette (Dark). Kept in a named val so the Light-theme
279
+ // guard below can revert to it: native Android screens never adopt
280
+ // a Light theme (see the light-theme check after parsing).
281
+ val defaultDarkColors = CameraThemeColors(
280
282
  background = Color.parseColor("#000000"),
281
283
  surface = Color.parseColor("#111827"),
282
284
  surfaceMuted = Color.parseColor("#1F2937"),
@@ -295,6 +297,7 @@ class CameraTheme(
295
297
  error = Color.parseColor("#FF5B5B"),
296
298
  warning = Color.parseColor("#FBBF24")
297
299
  )
300
+ var colors = defaultDarkColors
298
301
 
299
302
  var typography = CameraThemeTypography("System", 18f, 16f, 13f, 14f)
300
303
  var spacing = CameraThemeSpacing(4, 8, 12, 16, 20, 24)
@@ -362,6 +365,18 @@ class CameraTheme(
362
365
  }
363
366
  }
364
367
 
368
+ // Native Android screens stay Dark regardless of the host's
369
+ // light/dark switch: only the React Native surfaces follow the host
370
+ // into Light. If the resolved/persisted theme reads as Light (this
371
+ // can only happen for a theme persisted by an older build, since
372
+ // `setCameraTheme` no longer stores Light themes), revert the color
373
+ // palette to the Dark defaults. Typography/spacing/radius are left
374
+ // as configured because they aren't light/dark specific, so branded
375
+ // fonts and metrics survive. Dark themes are untouched.
376
+ if (!colors.isDark) {
377
+ colors = defaultDarkColors
378
+ }
379
+
365
380
  // Flatten the theme's `components` section into per-component
366
381
  // key→string maps consumed via componentColor()/componentValue().
367
382
  val componentOverrides = mutableMapOf<String, Map<String, String>>()
@@ -1403,11 +1403,46 @@ class CustomCameraModule(
1403
1403
 
1404
1404
  @ReactMethod
1405
1405
  override fun setCameraTheme(theme: String, promise: Promise) {
1406
+ // Native Android screens must never switch to a Light theme: when the host
1407
+ // toggles Light, only the React Native surfaces follow. A Light theme push
1408
+ // is therefore NOT persisted natively, so the last Dark theme (or the Dark
1409
+ // default) is retained and native chrome stays Dark. Dark theme pushes —
1410
+ // including branded dark palettes — are saved as before, so Dark behavior is
1411
+ // unchanged. `CameraTheme.load()` applies the same guard defensively for any
1412
+ // Light theme persisted by an older build.
1413
+ if (isLightThemeJson(theme)) {
1414
+ // Re-read whatever Dark theme is already stored (no-op if unchanged) so a
1415
+ // subsequent load reflects the retained theme rather than the ignored push.
1416
+ CameraTheme.invalidate()
1417
+ promise.resolve(null)
1418
+ return
1419
+ }
1406
1420
  saveSetting("cameraTheme", theme)
1407
1421
  CameraTheme.invalidate()
1408
1422
  promise.resolve(null)
1409
1423
  }
1410
1424
 
1425
+ /**
1426
+ * Whether a `setCameraTheme` payload describes a Light theme, i.e. its
1427
+ * `colors.background` reads as light (relative luminance >= 0.5). Mirrors
1428
+ * [isColorDark] / the JS `isDarkTheme()` so the native/RN light-dark split
1429
+ * agrees. A payload with no parseable background is treated as NOT light, so
1430
+ * malformed themes fall through to the normal save path unchanged.
1431
+ */
1432
+ private fun isLightThemeJson(theme: String): Boolean {
1433
+ if (!theme.trimStart().startsWith("{")) return false
1434
+ return try {
1435
+ val background = org.json.JSONObject(theme)
1436
+ .optJSONObject("colors")
1437
+ ?.optString("background")
1438
+ ?.takeIf { it.isNotEmpty() }
1439
+ ?: return false
1440
+ !isColorDark(android.graphics.Color.parseColor(background))
1441
+ } catch (e: Exception) {
1442
+ false
1443
+ }
1444
+ }
1445
+
1411
1446
  @ReactMethod
1412
1447
  override fun setCameraConfig(configJson: String, promise: Promise) {
1413
1448
  saveSetting("cameraConfig", configJson)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-ensys-camera-x",
3
- "version": "1.0.9",
3
+ "version": "1.0.10",
4
4
  "description": "Full-screen native Android camera and media picker for React Native — photo/video capture, gallery multi-select, and an editor (crop, rotate, filters, stickers, emoji, text, drawing, trim) in one call. Fully white-labelled: every icon, colour and string is configurable.",
5
5
  "source": "./src/index.tsx",
6
6
  "main": "./lib/module/index.js",