rn-system-bar 3.1.1 → 3.1.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,9 +1,9 @@
|
|
|
1
1
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
2
|
-
|
|
2
|
+
xmlns:tools="http://schemas.android.com/tools">
|
|
3
3
|
|
|
4
4
|
<!-- Required for writing system brightness -->
|
|
5
|
-
<uses-permission
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
<uses-permission
|
|
6
|
+
android:name="android.permission.WRITE_SETTINGS"
|
|
7
|
+
tools:ignore="ProtectedPermissions" />
|
|
8
8
|
|
|
9
9
|
</manifest>
|
|
@@ -8,6 +8,7 @@ import android.app.Activity
|
|
|
8
8
|
import android.content.Context
|
|
9
9
|
import android.content.Intent
|
|
10
10
|
import android.content.pm.ActivityInfo
|
|
11
|
+
import android.graphics.Color
|
|
11
12
|
import android.hardware.display.DisplayManager
|
|
12
13
|
import android.media.AudioManager
|
|
13
14
|
import android.os.Build
|
|
@@ -20,6 +21,7 @@ import android.view.WindowManager
|
|
|
20
21
|
import com.facebook.react.bridge.*
|
|
21
22
|
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
22
23
|
|
|
24
|
+
@Suppress("DEPRECATION", "OVERRIDE_DEPRECATION")
|
|
23
25
|
class SystemBarModule(
|
|
24
26
|
private val reactContext: ReactApplicationContext
|
|
25
27
|
) : ReactContextBaseJavaModule(reactContext) {
|
|
@@ -42,64 +44,65 @@ class SystemBarModule(
|
|
|
42
44
|
else -> AudioManager.STREAM_MUSIC
|
|
43
45
|
}
|
|
44
46
|
|
|
47
|
+
private fun emit(event: String, data: WritableMap) {
|
|
48
|
+
reactContext
|
|
49
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
50
|
+
.emit(event, data)
|
|
51
|
+
}
|
|
52
|
+
|
|
45
53
|
// ═══════════════════════════════════════════════
|
|
46
54
|
// NAVIGATION BAR COLOR
|
|
47
|
-
//
|
|
55
|
+
// WindowInsetsController API 30+, fallback for older.
|
|
56
|
+
// navigationBarColor deprecated on API 35+ but still
|
|
57
|
+
// works — suppressed at class level.
|
|
48
58
|
// ═══════════════════════════════════════════════
|
|
49
59
|
|
|
50
60
|
@ReactMethod
|
|
51
61
|
fun setNavigationBarColor(color: String) {
|
|
52
62
|
activity()?.runOnUiThread {
|
|
53
63
|
try {
|
|
54
|
-
|
|
55
|
-
|
|
64
|
+
val parsed = Color.parseColor(color)
|
|
65
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
|
66
|
+
// API 35+ — use WindowInsetsController appearance for tinting
|
|
67
|
+
val controller = activity()!!.window.insetsController
|
|
68
|
+
// Nav bar color via window attribute still works as tint on 35+
|
|
69
|
+
activity()!!.window.navigationBarColor = parsed
|
|
70
|
+
} else {
|
|
71
|
+
activity()!!.window.navigationBarColor = parsed
|
|
72
|
+
}
|
|
56
73
|
} catch (_: Exception) {}
|
|
57
74
|
}
|
|
58
75
|
}
|
|
59
76
|
|
|
60
77
|
// ═══════════════════════════════════════════════
|
|
61
78
|
// BRIGHTNESS
|
|
62
|
-
//
|
|
63
|
-
// setBrightness — TWO things at once:
|
|
64
|
-
// 1. window.attributes.screenBrightness → current screen (instant)
|
|
65
|
-
// 2. Settings.System.SCREEN_BRIGHTNESS → system brightness persisted
|
|
66
|
-
//
|
|
67
|
-
// Requires WRITE_SETTINGS permission.
|
|
68
|
-
// If permission not granted → request it, still apply window brightness.
|
|
69
|
-
//
|
|
70
|
-
// getBrightness — reads SYSTEM brightness (0–255 → 0.0–1.0)
|
|
71
|
-
// so the slider always shows the true system value.
|
|
72
79
|
// ═══════════════════════════════════════════════
|
|
73
80
|
|
|
74
81
|
@ReactMethod
|
|
75
82
|
fun setBrightness(level: Float) {
|
|
76
83
|
val clamped = level.coerceIn(0.01f, 1f)
|
|
77
84
|
|
|
78
|
-
//
|
|
85
|
+
// Window brightness — instant, no permission needed
|
|
79
86
|
activity()?.runOnUiThread {
|
|
80
87
|
val lp = activity()!!.window.attributes
|
|
81
88
|
lp.screenBrightness = clamped
|
|
82
89
|
activity()!!.window.attributes = lp
|
|
83
90
|
}
|
|
84
91
|
|
|
85
|
-
//
|
|
92
|
+
// System brightness — persisted, needs WRITE_SETTINGS
|
|
86
93
|
val sysValue = (clamped * 255).toInt().coerceIn(1, 255)
|
|
87
|
-
|
|
88
94
|
if (Settings.System.canWrite(reactContext)) {
|
|
89
|
-
// Permission granted — write system brightness
|
|
90
95
|
Settings.System.putInt(
|
|
91
96
|
reactContext.contentResolver,
|
|
92
97
|
Settings.System.SCREEN_BRIGHTNESS,
|
|
93
98
|
sysValue
|
|
94
99
|
)
|
|
95
|
-
// Also disable auto-brightness so manual value sticks
|
|
96
100
|
Settings.System.putInt(
|
|
97
101
|
reactContext.contentResolver,
|
|
98
102
|
Settings.System.SCREEN_BRIGHTNESS_MODE,
|
|
99
103
|
Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL
|
|
100
104
|
)
|
|
101
105
|
} else {
|
|
102
|
-
// No permission — open system settings so user can grant it once
|
|
103
106
|
val intent = Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS).apply {
|
|
104
107
|
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
|
105
108
|
}
|
|
@@ -110,7 +113,6 @@ class SystemBarModule(
|
|
|
110
113
|
@ReactMethod
|
|
111
114
|
fun getBrightness(promise: Promise) {
|
|
112
115
|
try {
|
|
113
|
-
// Always read from system setting so value matches device brightness bar
|
|
114
116
|
val sys = Settings.System.getInt(
|
|
115
117
|
reactContext.contentResolver,
|
|
116
118
|
Settings.System.SCREEN_BRIGHTNESS,
|
|
@@ -178,7 +180,6 @@ class SystemBarModule(
|
|
|
178
180
|
c.show(WindowInsets.Type.statusBars() or WindowInsets.Type.navigationBars())
|
|
179
181
|
}
|
|
180
182
|
} else {
|
|
181
|
-
@Suppress("DEPRECATION")
|
|
182
183
|
activity()!!.window.decorView.systemUiVisibility = if (enable) {
|
|
183
184
|
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
|
|
184
185
|
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
|
|
@@ -202,6 +203,7 @@ class SystemBarModule(
|
|
|
202
203
|
|
|
203
204
|
// ═══════════════════════════════════════════════
|
|
204
205
|
// ORIENTATION
|
|
206
|
+
// "auto" = FULL_SENSOR (follows system auto-rotate)
|
|
205
207
|
// ═══════════════════════════════════════════════
|
|
206
208
|
|
|
207
209
|
@ReactMethod
|
|
@@ -211,36 +213,41 @@ class SystemBarModule(
|
|
|
211
213
|
"landscape" -> ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
|
|
212
214
|
"landscape-left" -> ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
|
|
213
215
|
"landscape-right" -> ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
|
|
216
|
+
// "auto" = respect system auto-rotate toggle
|
|
214
217
|
else -> ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
|
|
215
218
|
}
|
|
216
219
|
}
|
|
217
220
|
|
|
218
221
|
// ═══════════════════════════════════════════════
|
|
219
|
-
// SCREENCAST
|
|
222
|
+
// SCREENCAST — list all presentation displays
|
|
220
223
|
// ═══════════════════════════════════════════════
|
|
221
224
|
|
|
222
225
|
private var displayListener: DisplayManager.DisplayListener? = null
|
|
223
226
|
|
|
224
|
-
private fun
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
227
|
+
private fun buildDisplayListMap(): WritableMap {
|
|
228
|
+
val dm = displayManager()
|
|
229
|
+
val map = Arguments.createMap()
|
|
230
|
+
val displays = dm.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION)
|
|
231
|
+
val arr = Arguments.createArray()
|
|
232
|
+
|
|
233
|
+
for (d in displays) {
|
|
234
|
+
val item = Arguments.createMap()
|
|
235
|
+
item.putInt("id", d.displayId)
|
|
236
|
+
item.putString("name", d.name)
|
|
237
|
+
item.putBoolean("isValid", d.isValid)
|
|
238
|
+
arr.pushMap(item)
|
|
239
|
+
}
|
|
229
240
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
val presentations = dm.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION)
|
|
234
|
-
val isCasting = presentations.isNotEmpty()
|
|
235
|
-
map.putBoolean("isCasting", isCasting)
|
|
236
|
-
if (isCasting) map.putString("displayName", presentations[0].name)
|
|
241
|
+
map.putBoolean("isCasting", displays.isNotEmpty())
|
|
242
|
+
map.putArray("displays", arr)
|
|
243
|
+
if (displays.isNotEmpty()) map.putString("displayName", displays[0].name)
|
|
237
244
|
else map.putNull("displayName")
|
|
238
245
|
return map
|
|
239
246
|
}
|
|
240
247
|
|
|
241
248
|
@ReactMethod
|
|
242
249
|
fun getScreencastInfo(promise: Promise) {
|
|
243
|
-
try { promise.resolve(
|
|
250
|
+
try { promise.resolve(buildDisplayListMap()) }
|
|
244
251
|
catch (e: Exception) { promise.reject("SCREENCAST_ERROR", e.message, e) }
|
|
245
252
|
}
|
|
246
253
|
|
|
@@ -248,9 +255,9 @@ class SystemBarModule(
|
|
|
248
255
|
fun startScreencastListener() {
|
|
249
256
|
if (displayListener != null) return
|
|
250
257
|
val listener = object : DisplayManager.DisplayListener {
|
|
251
|
-
override fun onDisplayAdded(id: Int) { emit("SystemBar_ScreencastChange",
|
|
252
|
-
override fun onDisplayRemoved(id: Int) { emit("SystemBar_ScreencastChange",
|
|
253
|
-
override fun onDisplayChanged(id: Int) { emit("SystemBar_ScreencastChange",
|
|
258
|
+
override fun onDisplayAdded(id: Int) { emit("SystemBar_ScreencastChange", buildDisplayListMap()) }
|
|
259
|
+
override fun onDisplayRemoved(id: Int) { emit("SystemBar_ScreencastChange", buildDisplayListMap()) }
|
|
260
|
+
override fun onDisplayChanged(id: Int) { emit("SystemBar_ScreencastChange", buildDisplayListMap()) }
|
|
254
261
|
}
|
|
255
262
|
displayListener = listener
|
|
256
263
|
displayManager().registerDisplayListener(listener, null)
|
package/lib/src/types.d.ts
CHANGED
|
@@ -5,7 +5,13 @@ export type NavigationBarVisibility = "visible" | "hidden";
|
|
|
5
5
|
export type StatusBarStyle = "light" | "dark";
|
|
6
6
|
export type Orientation = "portrait" | "landscape" | "landscape-left" | "landscape-right" | "auto";
|
|
7
7
|
export type VolumeStream = "music" | "ring" | "notification" | "alarm" | "system";
|
|
8
|
+
export interface ScreencastDisplay {
|
|
9
|
+
id: number;
|
|
10
|
+
name: string;
|
|
11
|
+
isValid: boolean;
|
|
12
|
+
}
|
|
8
13
|
export interface ScreencastInfo {
|
|
9
14
|
isCasting: boolean;
|
|
10
15
|
displayName: string | null;
|
|
16
|
+
displays: ScreencastDisplay[];
|
|
11
17
|
}
|
package/lib/src/useSystemBar.js
CHANGED
package/package.json
CHANGED
package/src/types.ts
CHANGED
|
@@ -26,7 +26,14 @@ export type VolumeStream =
|
|
|
26
26
|
| "alarm"
|
|
27
27
|
| "system";
|
|
28
28
|
|
|
29
|
+
export interface ScreencastDisplay {
|
|
30
|
+
id: number;
|
|
31
|
+
name: string;
|
|
32
|
+
isValid: boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
29
35
|
export interface ScreencastInfo {
|
|
30
36
|
isCasting: boolean;
|
|
31
37
|
displayName: string | null;
|
|
38
|
+
displays: ScreencastDisplay[];
|
|
32
39
|
}
|