rn-system-bar 3.0.2 → 3.0.3

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.
@@ -1,6 +1,9 @@
1
1
  // ─────────────────────────────────────────────
2
2
  // rn-system-bar · SystemBarModule.kt
3
- // Android Native Module Old + New Architecture
3
+ // v4 Navigation bar removed (handled by expo-navigation-bar).
4
+ // Status bar removed (handled by RN StatusBar).
5
+ // Only: Brightness, Volume, Screen flags, Orientation.
6
+ // Zero deprecated APIs.
4
7
  // ─────────────────────────────────────────────
5
8
 
6
9
  package com.systembar
@@ -8,11 +11,11 @@ package com.systembar
8
11
  import android.app.Activity
9
12
  import android.content.Context
10
13
  import android.content.pm.ActivityInfo
11
- import android.graphics.Color
12
14
  import android.media.AudioManager
13
15
  import android.os.Build
14
16
  import android.provider.Settings
15
17
  import android.view.View
18
+ import android.view.WindowInsets
16
19
  import android.view.WindowInsetsController
17
20
  import android.view.WindowManager
18
21
 
@@ -24,7 +27,6 @@ class SystemBarModule(
24
27
 
25
28
  override fun getName(): String = "SystemBar"
26
29
 
27
- // ── Helper ─────────────────────────────────────
28
30
  private fun activity(): Activity? = reactContext.currentActivity
29
31
 
30
32
  private fun audioManager(): AudioManager =
@@ -35,186 +37,7 @@ class SystemBarModule(
35
37
  "notification" -> AudioManager.STREAM_NOTIFICATION
36
38
  "alarm" -> AudioManager.STREAM_ALARM
37
39
  "system" -> AudioManager.STREAM_SYSTEM
38
- else -> AudioManager.STREAM_MUSIC // default: "music"
39
- }
40
-
41
- // ═══════════════════════════════════════════════
42
- // NAVIGATION BAR
43
- // ═══════════════════════════════════════════════
44
-
45
- @ReactMethod
46
- fun setNavigationBarColor(color: String) {
47
- val act = activity() ?: return
48
- act.runOnUiThread {
49
- try {
50
- act.window.navigationBarColor = Color.parseColor(color)
51
- } catch (e: Exception) {
52
- // ignore invalid color
53
- }
54
- }
55
- }
56
-
57
- @ReactMethod
58
- fun setNavigationBarVisibility(mode: String) {
59
- val act = activity() ?: return
60
- act.runOnUiThread {
61
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
62
- val controller = act.window.insetsController ?: return@runOnUiThread
63
- if (mode == "hidden") {
64
- controller.hide(android.view.WindowInsets.Type.navigationBars())
65
- } else {
66
- controller.show(android.view.WindowInsets.Type.navigationBars())
67
- }
68
- } else {
69
- @Suppress("DEPRECATION")
70
- if (mode == "hidden") {
71
- act.window.decorView.systemUiVisibility =
72
- act.window.decorView.systemUiVisibility or
73
- View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
74
- View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
75
- } else {
76
- act.window.decorView.systemUiVisibility =
77
- act.window.decorView.systemUiVisibility and
78
- View.SYSTEM_UI_FLAG_HIDE_NAVIGATION.inv()
79
- }
80
- }
81
- }
82
- }
83
-
84
- @ReactMethod
85
- fun setNavigationBarButtonStyle(style: String) {
86
- val act = activity() ?: return
87
- act.runOnUiThread {
88
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
89
- val controller = act.window.insetsController ?: return@runOnUiThread
90
- controller.setSystemBarsAppearance(
91
- if (style == "dark")
92
- WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
93
- else 0,
94
- WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
95
- )
96
- } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
97
- @Suppress("DEPRECATION")
98
- val flags = act.window.decorView.systemUiVisibility
99
- act.window.decorView.systemUiVisibility = if (style == "dark") {
100
- flags or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
101
- } else {
102
- flags and View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR.inv()
103
- }
104
- }
105
- }
106
- }
107
-
108
- @ReactMethod
109
- fun setNavigationBarStyle(style: String) {
110
- // "style" maps to button style + optional color hinting
111
- val act = activity() ?: return
112
- act.runOnUiThread {
113
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
114
- val controller = act.window.insetsController ?: return@runOnUiThread
115
- val useLightIcons = style == "light"
116
- controller.setSystemBarsAppearance(
117
- if (useLightIcons) 0
118
- else WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS,
119
- WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
120
- )
121
- } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
122
- @Suppress("DEPRECATION")
123
- val flags = act.window.decorView.systemUiVisibility
124
- act.window.decorView.systemUiVisibility = when (style) {
125
- "dark" -> flags or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
126
- else -> flags and View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR.inv()
127
- }
128
- }
129
- }
130
- }
131
-
132
- @ReactMethod
133
- fun setNavigationBarBehavior(behavior: String) {
134
- val act = activity() ?: return
135
- act.runOnUiThread {
136
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
137
- val controller = act.window.insetsController ?: return@runOnUiThread
138
- // BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE is the only non-deprecated
139
- // constant on API 30+. "inset-swipe" and "inset-touch" both map to
140
- // the default persistent behavior (bars are always visible after show).
141
- controller.systemBarsBehavior = when (behavior) {
142
- "overlay-swipe" ->
143
- WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
144
- else ->
145
- // "inset-swipe" / "inset-touch": bars stay visible after swipe
146
- @Suppress("DEPRECATION")
147
- WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_SWIPE
148
- }
149
- }
150
- // API < 30: behavior is controlled via IMMERSIVE_STICKY flag
151
- }
152
- }
153
-
154
- // ═══════════════════════════════════════════════
155
- // STATUS BAR
156
- // ═══════════════════════════════════════════════
157
-
158
- @ReactMethod
159
- fun setStatusBarColor(color: String) {
160
- val act = activity() ?: return
161
- act.runOnUiThread {
162
- try {
163
- act.window.statusBarColor = Color.parseColor(color)
164
- } catch (e: Exception) {
165
- // ignore invalid color
166
- }
167
- }
168
- }
169
-
170
- @ReactMethod
171
- fun setStatusBarStyle(style: String) {
172
- val act = activity() ?: return
173
- act.runOnUiThread {
174
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
175
- val controller = act.window.insetsController ?: return@runOnUiThread
176
- controller.setSystemBarsAppearance(
177
- if (style == "dark")
178
- WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
179
- else 0,
180
- WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
181
- )
182
- } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
183
- @Suppress("DEPRECATION")
184
- val flags = act.window.decorView.systemUiVisibility
185
- act.window.decorView.systemUiVisibility = if (style == "dark") {
186
- flags or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
187
- } else {
188
- flags and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
189
- }
190
- }
191
- }
192
- }
193
-
194
- @ReactMethod
195
- fun setStatusBarVisibility(visible: Boolean) {
196
- val act = activity() ?: return
197
- act.runOnUiThread {
198
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
199
- val controller = act.window.insetsController ?: return@runOnUiThread
200
- if (visible) {
201
- controller.show(android.view.WindowInsets.Type.statusBars())
202
- } else {
203
- controller.hide(android.view.WindowInsets.Type.statusBars())
204
- }
205
- } else {
206
- @Suppress("DEPRECATION")
207
- if (visible) {
208
- act.window.decorView.systemUiVisibility =
209
- act.window.decorView.systemUiVisibility and
210
- View.SYSTEM_UI_FLAG_FULLSCREEN.inv()
211
- } else {
212
- act.window.decorView.systemUiVisibility =
213
- act.window.decorView.systemUiVisibility or
214
- View.SYSTEM_UI_FLAG_FULLSCREEN
215
- }
216
- }
217
- }
40
+ else -> AudioManager.STREAM_MUSIC
218
41
  }
219
42
 
220
43
  // ═══════════════════════════════════════════════
@@ -237,13 +60,11 @@ class SystemBarModule(
237
60
  val act = activity()
238
61
  if (act != null) {
239
62
  val lp = act.window.attributes
240
- // screenBrightness == -1 means "use system default"
241
63
  if (lp.screenBrightness >= 0f) {
242
64
  promise.resolve(lp.screenBrightness.toDouble())
243
65
  return
244
66
  }
245
67
  }
246
- // Fall back to system brightness setting (0–255 → 0.0–1.0)
247
68
  val sysBrightness = Settings.System.getInt(
248
69
  reactContext.contentResolver,
249
70
  Settings.System.SCREEN_BRIGHTNESS,
@@ -270,23 +91,21 @@ class SystemBarModule(
270
91
  fun setVolume(level: Float, stream: String) {
271
92
  try {
272
93
  val am = audioManager()
273
- val streamType = streamType(stream)
274
- val max = am.getStreamMaxVolume(streamType)
94
+ val type = streamType(stream)
95
+ val max = am.getStreamMaxVolume(type)
275
96
  val vol = (level.coerceIn(0f, 1f) * max).toInt()
276
97
  val flags = if (suppressVolumeHUD) 0 else AudioManager.FLAG_SHOW_UI
277
- am.setStreamVolume(streamType, vol, flags)
278
- } catch (e: Exception) {
279
- // ignore
280
- }
98
+ am.setStreamVolume(type, vol, flags)
99
+ } catch (_: Exception) {}
281
100
  }
282
101
 
283
102
  @ReactMethod
284
103
  fun getVolume(stream: String, promise: Promise) {
285
104
  try {
286
105
  val am = audioManager()
287
- val streamType = streamType(stream)
288
- val current = am.getStreamVolume(streamType)
289
- val max = am.getStreamMaxVolume(streamType)
106
+ val type = streamType(stream)
107
+ val current = am.getStreamVolume(type)
108
+ val max = am.getStreamMaxVolume(type)
290
109
  promise.resolve(if (max > 0) current.toDouble() / max else 0.0)
291
110
  } catch (e: Exception) {
292
111
  promise.reject("VOLUME_ERROR", e.message, e)
@@ -314,32 +133,30 @@ class SystemBarModule(
314
133
  val act = activity() ?: return
315
134
  act.runOnUiThread {
316
135
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
136
+ // API 30+ — WindowInsetsController (modern, no deprecated flags)
317
137
  val controller = act.window.insetsController ?: return@runOnUiThread
318
138
  if (enable) {
319
139
  controller.hide(
320
- android.view.WindowInsets.Type.statusBars() or
321
- android.view.WindowInsets.Type.navigationBars()
140
+ WindowInsets.Type.statusBars() or WindowInsets.Type.navigationBars()
322
141
  )
323
142
  controller.systemBarsBehavior =
324
143
  WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
325
144
  } else {
326
145
  controller.show(
327
- android.view.WindowInsets.Type.statusBars() or
328
- android.view.WindowInsets.Type.navigationBars()
146
+ WindowInsets.Type.statusBars() or WindowInsets.Type.navigationBars()
329
147
  )
330
148
  }
331
149
  } else {
150
+ // API 21–29: only path available; suppressed intentionally
332
151
  @Suppress("DEPRECATION")
333
- if (enable) {
334
- act.window.decorView.systemUiVisibility =
335
- View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
336
- View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
337
- View.SYSTEM_UI_FLAG_FULLSCREEN or
338
- View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
339
- View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
152
+ act.window.decorView.systemUiVisibility = if (enable) {
153
+ View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
154
+ View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
155
+ View.SYSTEM_UI_FLAG_FULLSCREEN or
156
+ View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
157
+ View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
340
158
  } else {
341
- act.window.decorView.systemUiVisibility =
342
- View.SYSTEM_UI_FLAG_VISIBLE
159
+ View.SYSTEM_UI_FLAG_VISIBLE
343
160
  }
344
161
  }
345
162
  }
@@ -353,11 +170,11 @@ class SystemBarModule(
353
170
  fun setOrientation(mode: String) {
354
171
  val act = activity() ?: return
355
172
  act.requestedOrientation = when (mode) {
356
- "portrait" -> ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
357
- "landscape" -> ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
358
- "landscape-left" -> ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
359
- "landscape-right" -> ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
360
- else -> ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR // "auto"
173
+ "portrait" -> ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
174
+ "landscape" -> ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
175
+ "landscape-left" -> ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
176
+ "landscape-right" -> ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
177
+ else -> ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
361
178
  }
362
179
  }
363
- }
180
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rn-system-bar",
3
- "version": "3.0.2",
3
+ "version": "3.0.3",
4
4
  "description": "Control Android & iOS system bars, brightness, volume, orientation and screen flags from React Native.",
5
5
  "main": "index.ts",
6
6
  "react-native": "index.ts",
package/src/SystemBar.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  // ─────────────────────────────────────────────
2
2
  // rn-system-bar · SystemBar.ts
3
+ // v4 — expo-navigation-bar based, zero deprecated APIs
3
4
  // ─────────────────────────────────────────────
4
5
 
5
- import { NativeModules, Platform } from "react-native";
6
+ import * as NavigationBar from "expo-navigation-bar";
7
+ import { NativeModules, Platform, StatusBar } from "react-native";
6
8
 
7
9
  import type {
8
10
  NavigationBarBehavior,
@@ -14,20 +16,15 @@ import type {
14
16
  VolumeStream,
15
17
  } from "./types";
16
18
 
17
- const { SystemBar } = NativeModules;
18
-
19
- // ─── Guard helper ──────────────────────────────
20
- // Navigation-bar APIs are Android-only.
21
- // iOS has no navigation bar concept.
22
- // All other APIs work on both platforms.
19
+ const { SystemBar: SystemBarNative } = NativeModules;
23
20
 
24
21
  const isAndroid = Platform.OS === "android";
25
22
 
26
- const androidOnly = (name: string) => {
23
+ const androidOnly = (name: string): boolean => {
27
24
  if (!isAndroid) {
28
25
  if (__DEV__) {
29
26
  console.warn(
30
- `[rn-system-bar] ${name}() is Android-only and has no effect on iOS.`
27
+ `[rn-system-bar] ${name}() is Android-only and is a no-op on iOS.`,
31
28
  );
32
29
  }
33
30
  return false;
@@ -35,28 +32,28 @@ const androidOnly = (name: string) => {
35
32
  return true;
36
33
  };
37
34
 
38
- const checkModule = () => {
39
- if (!SystemBar) {
35
+ const checkNative = () => {
36
+ if (!SystemBarNative) {
40
37
  throw new Error(
41
- "[rn-system-bar] Native module not found. " +
42
- "Did you forget to run `pod install` (iOS) or rebuild the Android project?"
38
+ "[rn-system-bar] Native module not found. Rebuild your Android/iOS project.",
43
39
  );
44
40
  }
45
41
  };
46
42
 
47
43
  // ═══════════════════════════════════════════════
48
- // NAVIGATION BAR (Android-only)
44
+ // NAVIGATION BAR — expo-navigation-bar (Android only)
45
+ // Uses WindowInsetsController internally on API 30+.
46
+ // Zero deprecated APIs.
49
47
  // ═══════════════════════════════════════════════
50
48
 
51
49
  /**
52
50
  * Set navigation bar background color.
53
- * @param color Hex color string e.g. "#000000"
51
+ * @param color Hex string e.g. "#000000"
54
52
  * @platform android
55
53
  */
56
- export const setNavigationBarColor = (color: string): void => {
57
- if (!androidOnly("setNavigationBarColor")) return;
58
- checkModule();
59
- SystemBar.setNavigationBarColor(color);
54
+ export const setNavigationBarColor = (color: string): Promise<void> => {
55
+ if (!androidOnly("setNavigationBarColor")) return Promise.resolve();
56
+ return NavigationBar.setBackgroundColorAsync(color);
60
57
  };
61
58
 
62
59
  /**
@@ -64,91 +61,96 @@ export const setNavigationBarColor = (color: string): void => {
64
61
  * @platform android
65
62
  */
66
63
  export const setNavigationBarVisibility = (
67
- mode: NavigationBarVisibility
68
- ): void => {
69
- if (!androidOnly("setNavigationBarVisibility")) return;
70
- checkModule();
71
- SystemBar.setNavigationBarVisibility(mode);
64
+ mode: NavigationBarVisibility,
65
+ ): Promise<void> => {
66
+ if (!androidOnly("setNavigationBarVisibility")) return Promise.resolve();
67
+ return NavigationBar.setVisibilityAsync(mode);
72
68
  };
73
69
 
74
70
  /**
75
- * Set icon/button style of the navigation bar.
71
+ * Set navigation bar icon/button style.
76
72
  * @param style "light" = white icons | "dark" = black icons
77
73
  * @platform android
78
74
  */
79
75
  export const setNavigationBarButtonStyle = (
80
- style: NavigationBarButtonStyle
81
- ): void => {
82
- if (!androidOnly("setNavigationBarButtonStyle")) return;
83
- checkModule();
84
- SystemBar.setNavigationBarButtonStyle(style);
76
+ style: NavigationBarButtonStyle,
77
+ ): Promise<void> => {
78
+ if (!androidOnly("setNavigationBarButtonStyle")) return Promise.resolve();
79
+ return NavigationBar.setButtonStyleAsync(style);
85
80
  };
86
81
 
87
82
  /**
88
- * Set the overall visual style of the navigation bar.
83
+ * Set navigation bar visual style.
89
84
  * @platform android
90
85
  */
91
- export const setNavigationBarStyle = (style: NavigationBarStyle): void => {
92
- if (!androidOnly("setNavigationBarStyle")) return;
93
- checkModule();
94
- SystemBar.setNavigationBarStyle(style);
86
+ export const setNavigationBarStyle = (
87
+ style: NavigationBarStyle,
88
+ ): Promise<void> => {
89
+ if (!androidOnly("setNavigationBarStyle")) return Promise.resolve();
90
+ const buttonStyle: NavigationBarButtonStyle =
91
+ style === "dark" || style === "auto" ? "dark" : "light";
92
+ return NavigationBar.setButtonStyleAsync(buttonStyle);
95
93
  };
96
94
 
97
95
  /**
98
- * Set the gesture behavior of the navigation bar.
96
+ * Set navigation bar gesture behavior.
99
97
  * @platform android
100
98
  */
101
99
  export const setNavigationBarBehavior = (
102
- behavior: NavigationBarBehavior
103
- ): void => {
104
- if (!androidOnly("setNavigationBarBehavior")) return;
105
- checkModule();
106
- SystemBar.setNavigationBarBehavior(behavior);
100
+ behavior: NavigationBarBehavior,
101
+ ): Promise<void> => {
102
+ if (!androidOnly("setNavigationBarBehavior")) return Promise.resolve();
103
+ return NavigationBar.setBehaviorAsync(behavior);
107
104
  };
108
105
 
109
106
  // ═══════════════════════════════════════════════
110
107
  // STATUS BAR
108
+ // React Native StatusBar — cross-platform, no deprecated APIs.
111
109
  // ═══════════════════════════════════════════════
112
110
 
113
111
  /**
114
112
  * Set status bar background color.
115
- * @param color Hex color string e.g. "#FF0000"
116
- * @platform android (iOS ignores background color by OS design)
113
+ * @platform android
117
114
  */
118
- export const setStatusBarColor = (color: string): void => {
115
+ export const setStatusBarColor = (color: string, animated = false): void => {
119
116
  if (!androidOnly("setStatusBarColor")) return;
120
- checkModule();
121
- SystemBar.setStatusBarColor(color);
117
+ StatusBar.setBackgroundColor(color, animated);
122
118
  };
123
119
 
124
120
  /**
125
- * Set status bar icon style (light/dark icons).
126
- * Works on both Android and iOS.
121
+ * Set status bar icon style.
122
+ * "light" = white icons | "dark" = dark icons
127
123
  */
128
- export const setStatusBarStyle = (style: StatusBarStyle): void => {
129
- checkModule();
130
- SystemBar.setStatusBarStyle(style);
124
+ export const setStatusBarStyle = (
125
+ style: StatusBarStyle,
126
+ animated = false,
127
+ ): void => {
128
+ StatusBar.setBarStyle(
129
+ style === "light" ? "light-content" : "dark-content",
130
+ animated,
131
+ );
131
132
  };
132
133
 
133
134
  /**
134
135
  * Show or hide the status bar.
135
136
  */
136
- export const setStatusBarVisibility = (visible: boolean): void => {
137
- checkModule();
138
- SystemBar.setStatusBarVisibility(visible);
137
+ export const setStatusBarVisibility = (
138
+ visible: boolean,
139
+ animated = false,
140
+ ): void => {
141
+ StatusBar.setHidden(!visible, animated ? "slide" : "none");
139
142
  };
140
143
 
141
144
  // ═══════════════════════════════════════════════
142
- // BRIGHTNESS
145
+ // BRIGHTNESS — native module
143
146
  // ═══════════════════════════════════════════════
144
147
 
145
148
  /**
146
- * Set screen brightness.
147
- * @param level 0.0 (min) – 1.0 (max)
149
+ * Set screen brightness (0.0 – 1.0).
148
150
  */
149
151
  export const setBrightness = (level: number): void => {
150
- checkModule();
151
- SystemBar.setBrightness(Math.max(0, Math.min(1, level)));
152
+ checkNative();
153
+ SystemBarNative.setBrightness(Math.max(0, Math.min(1, level)));
152
154
  };
153
155
 
154
156
  /**
@@ -156,81 +158,76 @@ export const setBrightness = (level: number): void => {
156
158
  * @returns Promise<number> 0.0 – 1.0
157
159
  */
158
160
  export const getBrightness = (): Promise<number> => {
159
- checkModule();
160
- return SystemBar.getBrightness();
161
+ checkNative();
162
+ return SystemBarNative.getBrightness();
161
163
  };
162
164
 
163
165
  // ═══════════════════════════════════════════════
164
- // VOLUME
166
+ // VOLUME — native module
165
167
  // ═══════════════════════════════════════════════
166
168
 
167
169
  /**
168
- * Set volume level.
169
- * @param level 0.0 (mute) 1.0 (max)
170
- * @param stream Audio stream to target (default: "music")
170
+ * Set volume level (0.0 – 1.0).
171
+ * @param stream "music" | "ring" | "notification" | "alarm" | "system"
171
172
  */
172
173
  export const setVolume = (
173
174
  level: number,
174
- stream: VolumeStream = "music"
175
+ stream: VolumeStream = "music",
175
176
  ): void => {
176
- checkModule();
177
- SystemBar.setVolume(Math.max(0, Math.min(1, level)), stream);
177
+ checkNative();
178
+ SystemBarNative.setVolume(Math.max(0, Math.min(1, level)), stream);
178
179
  };
179
180
 
180
181
  /**
181
- * Get current volume level.
182
- * @param stream Audio stream to query (default: "music")
183
- * @returns Promise<number> 0.0 – 1.0
182
+ * Get current volume level (0.0 – 1.0).
184
183
  */
185
184
  export const getVolume = (stream: VolumeStream = "music"): Promise<number> => {
186
- checkModule();
187
- return SystemBar.getVolume(stream);
185
+ checkNative();
186
+ return SystemBarNative.getVolume(stream);
188
187
  };
189
188
 
190
189
  /**
191
- * Show or hide the system Volume HUD when changing volume.
192
- * @param visible false = suppress the volume popup
190
+ * Show or hide the system volume popup.
193
191
  * @platform android
194
192
  */
195
193
  export const setVolumeHUDVisible = (visible: boolean): void => {
196
194
  if (!androidOnly("setVolumeHUDVisible")) return;
197
- checkModule();
198
- SystemBar.setVolumeHUDVisible(visible);
195
+ checkNative();
196
+ SystemBarNative.setVolumeHUDVisible(visible);
199
197
  };
200
198
 
201
199
  // ═══════════════════════════════════════════════
202
- // SCREEN
200
+ // SCREEN — native module
203
201
  // ═══════════════════════════════════════════════
204
202
 
205
203
  /**
206
- * Prevent the screen from sleeping.
207
- * @param enable true = keep screen on | false = allow sleep
204
+ * Prevent the screen from going to sleep.
208
205
  */
209
206
  export const keepScreenOn = (enable: boolean): void => {
210
- checkModule();
211
- SystemBar.keepScreenOn(enable);
207
+ checkNative();
208
+ SystemBarNative.keepScreenOn(enable);
212
209
  };
213
210
 
214
211
  /**
215
- * Enable or disable immersive fullscreen mode.
216
- * Hides both status bar and navigation bar.
212
+ * Enable immersive fullscreen (hides status + nav bar).
213
+ * Uses WindowInsetsController on API 30+.
217
214
  * @platform android
218
215
  */
219
216
  export const immersiveMode = (enable: boolean): void => {
220
217
  if (!androidOnly("immersiveMode")) return;
221
- checkModule();
222
- SystemBar.immersiveMode(enable);
218
+ checkNative();
219
+ SystemBarNative.immersiveMode(enable);
223
220
  };
224
221
 
225
222
  // ═══════════════════════════════════════════════
226
- // ORIENTATION
223
+ // ORIENTATION — native module
227
224
  // ═══════════════════════════════════════════════
228
225
 
229
226
  /**
230
227
  * Lock or unlock screen orientation.
231
- * @param mode "portrait" | "landscape" | "landscape-left" | "landscape-right" | "auto"
228
+ * "portrait" | "landscape" | "landscape-left" | "landscape-right" | "auto"
232
229
  */
233
230
  export const setOrientation = (mode: Orientation): void => {
234
- checkModule();
235
- SystemBar.setOrientation(mode);
231
+ checkNative();
232
+ SystemBarNative.setOrientation(mode);
236
233
  };