diff --git a/apps/readest-app/public/locales/ar/translation.json b/apps/readest-app/public/locales/ar/translation.json
index 5e97cf55..92d63a73 100644
--- a/apps/readest-app/public/locales/ar/translation.json
+++ b/apps/readest-app/public/locales/ar/translation.json
@@ -615,5 +615,6 @@
"File count: {{size}}": "عدد الملفات: {{size}}",
"Background Read Aloud": "قراءة بصوت عالٍ في الخلفية",
"Ready to read aloud": "جاهز للقراءة بصوت عالٍ",
- "Read Aloud": "القراءة بصوت عالٍ"
+ "Read Aloud": "القراءة بصوت عالٍ",
+ "Screen Brightness": "سطوع الشاشة"
}
diff --git a/apps/readest-app/public/locales/bn/translation.json b/apps/readest-app/public/locales/bn/translation.json
index cbe79583..28c5ec49 100644
--- a/apps/readest-app/public/locales/bn/translation.json
+++ b/apps/readest-app/public/locales/bn/translation.json
@@ -599,5 +599,6 @@
"File count: {{size}}": "ফাইলের সংখ্যা: {{size}}",
"Background Read Aloud": "পটভূমিতে উচ্চস্বরে পড়ুন",
"Ready to read aloud": "উচ্চস্বরে পড়ার জন্য প্রস্তুত",
- "Read Aloud": "উচ্চস্বরে পড়ুন"
+ "Read Aloud": "উচ্চস্বরে পড়ুন",
+ "Screen Brightness": "স্ক্রিন উজ্জ্বলতা"
}
diff --git a/apps/readest-app/public/locales/bo/translation.json b/apps/readest-app/public/locales/bo/translation.json
index 70716e2f..1a36e67f 100644
--- a/apps/readest-app/public/locales/bo/translation.json
+++ b/apps/readest-app/public/locales/bo/translation.json
@@ -595,5 +595,6 @@
"File count: {{size}}": "དེབ་གནས་བཅས་པའི་ཨང་། {{size}}",
"Background Read Aloud": "གནས་སྟངས་ཀྱིས་ཀློག་བྱེད།",
"Ready to read aloud": "དེབ་ཀྱི་སྤྱོད་བྱས་མ་ཐུབ།",
- "Read Aloud": "ཀློག་བྱེད།"
+ "Read Aloud": "ཀློག་བྱེད།",
+ "Screen Brightness": "རྒྱབ་སྐོར་གྱི་འོད་ཟེར།"
}
diff --git a/apps/readest-app/public/locales/de/translation.json b/apps/readest-app/public/locales/de/translation.json
index 271a1fb2..c8a6456f 100644
--- a/apps/readest-app/public/locales/de/translation.json
+++ b/apps/readest-app/public/locales/de/translation.json
@@ -599,5 +599,6 @@
"File count: {{size}}": "Dateianzahl: {{size}}",
"Background Read Aloud": "Hintergrund-Vorlesen",
"Ready to read aloud": "Bereit zum Vorlesen",
- "Read Aloud": "Vorlesen"
+ "Read Aloud": "Vorlesen",
+ "Screen Brightness": "Bildschirmhelligkeit"
}
diff --git a/apps/readest-app/public/locales/el/translation.json b/apps/readest-app/public/locales/el/translation.json
index 988af7b9..5c077f86 100644
--- a/apps/readest-app/public/locales/el/translation.json
+++ b/apps/readest-app/public/locales/el/translation.json
@@ -599,5 +599,6 @@
"File count: {{size}}": "Αριθμός αρχείων: {{size}}",
"Background Read Aloud": "Ανάγνωση στο παρασκήνιο",
"Ready to read aloud": "Έτοιμο για ανάγνωση",
- "Read Aloud": "Ανάγνωση"
+ "Read Aloud": "Ανάγνωση",
+ "Screen Brightness": "Φωτεινότητα οθόνης"
}
diff --git a/apps/readest-app/public/locales/es/translation.json b/apps/readest-app/public/locales/es/translation.json
index a48d2cf3..e16f9a7f 100644
--- a/apps/readest-app/public/locales/es/translation.json
+++ b/apps/readest-app/public/locales/es/translation.json
@@ -603,5 +603,6 @@
"File count: {{size}}": "Número de archivos: {{size}}",
"Background Read Aloud": "Lectura en segundo plano",
"Ready to read aloud": "Listo para leer en voz alta",
- "Read Aloud": "Leer en voz alta"
+ "Read Aloud": "Leer en voz alta",
+ "Screen Brightness": "Brillo de pantalla"
}
diff --git a/apps/readest-app/public/locales/fr/translation.json b/apps/readest-app/public/locales/fr/translation.json
index 0bdeb908..0c897359 100644
--- a/apps/readest-app/public/locales/fr/translation.json
+++ b/apps/readest-app/public/locales/fr/translation.json
@@ -603,5 +603,6 @@
"File count: {{size}}": "Nombre de fichiers : {{size}}",
"Background Read Aloud": "Lecture Vocale en Arrière-Plan",
"Ready to read aloud": "Prêt à lire à haute voix",
- "Read Aloud": "Lire à haute voix"
+ "Read Aloud": "Lire à haute voix",
+ "Screen Brightness": "Luminosité de l'Écran"
}
diff --git a/apps/readest-app/public/locales/hi/translation.json b/apps/readest-app/public/locales/hi/translation.json
index 9e864e15..cd3f16f1 100644
--- a/apps/readest-app/public/locales/hi/translation.json
+++ b/apps/readest-app/public/locales/hi/translation.json
@@ -599,5 +599,6 @@
"File count: {{size}}": "फ़ाइलों की संख्या: {{size}}",
"Background Read Aloud": "पृष्ठभूमि में वाचन",
"Ready to read aloud": "उच्च स्वर में पढ़ने के लिए तैयार",
- "Read Aloud": "उच्च स्वर में पढ़ें"
+ "Read Aloud": "उच्च स्वर में पढ़ें",
+ "Screen Brightness": "स्क्रीन ब्राइटनेस"
}
diff --git a/apps/readest-app/public/locales/id/translation.json b/apps/readest-app/public/locales/id/translation.json
index b9130284..daa09ea6 100644
--- a/apps/readest-app/public/locales/id/translation.json
+++ b/apps/readest-app/public/locales/id/translation.json
@@ -595,5 +595,6 @@
"File count: {{size}}": "Jumlah file: {{size}}",
"Background Read Aloud": "Bacakan Latar Belakang",
"Ready to read aloud": "Siap untuk dibacakan",
- "Read Aloud": "Bacakan"
+ "Read Aloud": "Bacakan",
+ "Screen Brightness": "Kecerahan Layar"
}
diff --git a/apps/readest-app/public/locales/it/translation.json b/apps/readest-app/public/locales/it/translation.json
index 39ec4956..9bb08eb1 100644
--- a/apps/readest-app/public/locales/it/translation.json
+++ b/apps/readest-app/public/locales/it/translation.json
@@ -603,5 +603,6 @@
"File count: {{size}}": "Conteggio file: {{size}}",
"Background Read Aloud": "Riproduzione in background",
"Ready to read aloud": "Pronto per la lettura ad alta voce",
- "Read Aloud": "Leggi ad alta voce"
+ "Read Aloud": "Leggi ad alta voce",
+ "Screen Brightness": "Luminosità dello schermo"
}
diff --git a/apps/readest-app/public/locales/ja/translation.json b/apps/readest-app/public/locales/ja/translation.json
index 839bddca..b6ed63b7 100644
--- a/apps/readest-app/public/locales/ja/translation.json
+++ b/apps/readest-app/public/locales/ja/translation.json
@@ -595,5 +595,6 @@
"File count: {{size}}": "ファイル数: {{size}}",
"Background Read Aloud": "バックグラウンド読み上げ",
"Ready to read aloud": "読み上げの準備ができました",
- "Read Aloud": "読み上げ"
+ "Read Aloud": "読み上げ",
+ "Screen Brightness": "画面の明るさ"
}
diff --git a/apps/readest-app/public/locales/ko/translation.json b/apps/readest-app/public/locales/ko/translation.json
index d5f8027c..8db8c516 100644
--- a/apps/readest-app/public/locales/ko/translation.json
+++ b/apps/readest-app/public/locales/ko/translation.json
@@ -595,5 +595,6 @@
"File count: {{size}}": "파일 수: {{size}}",
"Background Read Aloud": "백그라운드 음성 읽기",
"Ready to read aloud": "읽기 준비 완료",
- "Read Aloud": "음성 읽기"
+ "Read Aloud": "음성 읽기",
+ "Screen Brightness": "화면 밝기"
}
diff --git a/apps/readest-app/public/locales/nl/translation.json b/apps/readest-app/public/locales/nl/translation.json
index 1d8f5558..d169108b 100644
--- a/apps/readest-app/public/locales/nl/translation.json
+++ b/apps/readest-app/public/locales/nl/translation.json
@@ -599,5 +599,6 @@
"File count: {{size}}": "Bestandsaantal: {{size}}",
"Background Read Aloud": "Achtergrond Voorlezen",
"Ready to read aloud": "Klaar om voor te lezen",
- "Read Aloud": "Voorlezen"
+ "Read Aloud": "Voorlezen",
+ "Screen Brightness": "Schermhelderheid"
}
diff --git a/apps/readest-app/public/locales/pl/translation.json b/apps/readest-app/public/locales/pl/translation.json
index 864ae701..cc23a5d1 100644
--- a/apps/readest-app/public/locales/pl/translation.json
+++ b/apps/readest-app/public/locales/pl/translation.json
@@ -607,5 +607,6 @@
"File count: {{size}}": "Liczba plików: {{size}}",
"Background Read Aloud": "Czytanie na głos w tle",
"Ready to read aloud": "Gotowy do przeczytania na głos",
- "Read Aloud": "Czytaj na głos"
+ "Read Aloud": "Czytaj na głos",
+ "Screen Brightness": "Jasność ekranu"
}
diff --git a/apps/readest-app/public/locales/pt/translation.json b/apps/readest-app/public/locales/pt/translation.json
index 8e063404..b020c924 100644
--- a/apps/readest-app/public/locales/pt/translation.json
+++ b/apps/readest-app/public/locales/pt/translation.json
@@ -603,5 +603,6 @@
"File count: {{size}}": "Contagem de arquivos: {{size}}",
"Background Read Aloud": "Leitura em Segundo Plano",
"Ready to read aloud": "Pronto para leitura em voz alta",
- "Read Aloud": "Ler em Voz Alta"
+ "Read Aloud": "Ler em Voz Alta",
+ "Screen Brightness": "Brilho da Tela"
}
diff --git a/apps/readest-app/public/locales/ru/translation.json b/apps/readest-app/public/locales/ru/translation.json
index d05fbac2..9641bb28 100644
--- a/apps/readest-app/public/locales/ru/translation.json
+++ b/apps/readest-app/public/locales/ru/translation.json
@@ -607,5 +607,6 @@
"File count: {{size}}": "Количество файлов: {{size}}",
"Background Read Aloud": "Озвучивание в фоне",
"Ready to read aloud": "Готов к чтению вслух",
- "Read Aloud": "Читать вслух"
+ "Read Aloud": "Читать вслух",
+ "Screen Brightness": "Яркость экрана"
}
diff --git a/apps/readest-app/public/locales/si/translation.json b/apps/readest-app/public/locales/si/translation.json
index c00dba98..1039cc90 100644
--- a/apps/readest-app/public/locales/si/translation.json
+++ b/apps/readest-app/public/locales/si/translation.json
@@ -599,5 +599,6 @@
"File count: {{size}}": "ගොනු ගණන: {{size}}",
"Background Read Aloud": "පසුබිම් පවසා කියවීම",
"Ready to read aloud": "වාදනය කිරීමට සූදානම්",
- "Read Aloud": "පවසා කියවීම"
+ "Read Aloud": "පවසා කියවීම",
+ "Screen Brightness": "තිරයේ දිදුලනුම"
}
diff --git a/apps/readest-app/public/locales/sv/translation.json b/apps/readest-app/public/locales/sv/translation.json
index b10798dd..22a7d3c1 100644
--- a/apps/readest-app/public/locales/sv/translation.json
+++ b/apps/readest-app/public/locales/sv/translation.json
@@ -599,5 +599,6 @@
"Sunset": "Solnedgång",
"Reveal in Finder": "Visa i Finder",
"Reveal in File Explorer": "Visa i Utforskaren",
- "Reveal in Folder": "Visa i mapp"
+ "Reveal in Folder": "Visa i mapp",
+ "Screen Brightness": "Skärmens ljusstyrka"
}
diff --git a/apps/readest-app/public/locales/ta/translation.json b/apps/readest-app/public/locales/ta/translation.json
index 0d267cc8..8eafadcc 100644
--- a/apps/readest-app/public/locales/ta/translation.json
+++ b/apps/readest-app/public/locales/ta/translation.json
@@ -599,5 +599,6 @@
"File count: {{size}}": "கோப்பு எண்ணிக்கை: {{size}}",
"Background Read Aloud": "பின்னணி உரை வாசிப்பு",
"Ready to read aloud": "வாசிக்க தயாராக உள்ளது",
- "Read Aloud": "உரை வாசிப்பு"
+ "Read Aloud": "உரை வாசிப்பு",
+ "Screen Brightness": "திரை பிரகாசம்"
}
diff --git a/apps/readest-app/public/locales/th/translation.json b/apps/readest-app/public/locales/th/translation.json
index 66c5550e..5b3d8f8e 100644
--- a/apps/readest-app/public/locales/th/translation.json
+++ b/apps/readest-app/public/locales/th/translation.json
@@ -595,5 +595,6 @@
"File count: {{size}}": "จำนวนไฟล์: {{size}}",
"Background Read Aloud": "อ่านออกเสียงเบื้องหลัง",
"Ready to read aloud": "พร้อมที่จะอ่านออกเสียง",
- "Read Aloud": "อ่านออกเสียง"
+ "Read Aloud": "อ่านออกเสียง",
+ "Screen Brightness": "ความสว่างหน้าจอ"
}
diff --git a/apps/readest-app/public/locales/tr/translation.json b/apps/readest-app/public/locales/tr/translation.json
index 180a6a7b..c07c1fd2 100644
--- a/apps/readest-app/public/locales/tr/translation.json
+++ b/apps/readest-app/public/locales/tr/translation.json
@@ -599,5 +599,6 @@
"File count: {{size}}": "Dosya sayısı: {{size}}",
"Background Read Aloud": "Arka Planda Sesli Okuma",
"Ready to read aloud": "Sesli okumaya hazır",
- "Read Aloud": "Sesli Oku"
+ "Read Aloud": "Sesli Oku",
+ "Screen Brightness": "Ekran Parlaklığı"
}
diff --git a/apps/readest-app/public/locales/uk/translation.json b/apps/readest-app/public/locales/uk/translation.json
index e53e2935..a83c71ec 100644
--- a/apps/readest-app/public/locales/uk/translation.json
+++ b/apps/readest-app/public/locales/uk/translation.json
@@ -607,5 +607,6 @@
"File count: {{size}}": "Кількість файлів: {{size}}",
"Background Read Aloud": "Озвучування у фоновому режимі",
"Ready to read aloud": "Готовий до читання вголос",
- "Read Aloud": "Читати вголос"
+ "Read Aloud": "Читати вголос",
+ "Screen Brightness": "Яскравість екрану"
}
diff --git a/apps/readest-app/public/locales/vi/translation.json b/apps/readest-app/public/locales/vi/translation.json
index f8f6168b..00edcaf9 100644
--- a/apps/readest-app/public/locales/vi/translation.json
+++ b/apps/readest-app/public/locales/vi/translation.json
@@ -595,5 +595,6 @@
"File count: {{size}}": "Số lượng tệp: {{size}}",
"Background Read Aloud": "Đọc To Nền",
"Ready to read aloud": "Sẵn sàng để đọc to",
- "Read Aloud": "Đọc To"
+ "Read Aloud": "Đọc To",
+ "Screen Brightness": "Độ sáng màn hình"
}
diff --git a/apps/readest-app/public/locales/zh-CN/translation.json b/apps/readest-app/public/locales/zh-CN/translation.json
index 58f659d4..21337980 100644
--- a/apps/readest-app/public/locales/zh-CN/translation.json
+++ b/apps/readest-app/public/locales/zh-CN/translation.json
@@ -595,5 +595,6 @@
"File count: {{size}}": "文件数量: {{size}}",
"Background Read Aloud": "后台语音朗读",
"Ready to read aloud": "语音朗读已就绪",
- "Read Aloud": "语音朗读"
+ "Read Aloud": "语音朗读",
+ "Screen Brightness": "屏幕亮度"
}
diff --git a/apps/readest-app/public/locales/zh-TW/translation.json b/apps/readest-app/public/locales/zh-TW/translation.json
index 7d2fa52e..07edc633 100644
--- a/apps/readest-app/public/locales/zh-TW/translation.json
+++ b/apps/readest-app/public/locales/zh-TW/translation.json
@@ -595,5 +595,6 @@
"File count: {{size}}": "文件數量: {{size}}",
"Background Read Aloud": "背景朗讀",
"Ready to read aloud": "朗讀準備就緒",
- "Read Aloud": "朗讀"
+ "Read Aloud": "朗讀",
+ "Screen Brightness": "螢幕亮度"
}
diff --git a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/android/src/main/java/NativeBridgePlugin.kt b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/android/src/main/java/NativeBridgePlugin.kt
index f57797a8..04b5159e 100644
--- a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/android/src/main/java/NativeBridgePlugin.kt
+++ b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/android/src/main/java/NativeBridgePlugin.kt
@@ -69,6 +69,11 @@ class LockScreenOrientationRequestArgs {
var orientation: String? = null
}
+@InvokeArg
+class SetScreenBrightnessRequestArgs {
+ var brightness: Double? = null // 0.0 to 1.0
+}
+
interface KeyDownInterceptor {
fun interceptVolumeKeys(enabled: Boolean)
fun interceptBackKey(enabled: Boolean)
@@ -76,7 +81,7 @@ interface KeyDownInterceptor {
@TauriPlugin(
permissions = [
- Permission(strings = [Manifest.permission.MANAGE_EXTERNAL_STORAGE], alias = "manageStorage")
+ Permission(strings = [Manifest.permission.MANAGE_EXTERNAL_STORAGE], alias = "manageStorage"),
]
)
class NativeBridgePlugin(private val activity: Activity): Plugin(activity) {
@@ -415,6 +420,44 @@ class NativeBridgePlugin(private val activity: Activity): Plugin(activity) {
invoke.resolve(ret)
}
+ @Command
+ fun get_screen_brightness(invoke: Invoke) {
+ val ret = JSObject()
+ try {
+ val brightness = Settings.System.getInt(
+ activity.contentResolver,
+ Settings.System.SCREEN_BRIGHTNESS
+ )
+ val normalizedBrightness = brightness / 255.0
+ ret.put("brightness", normalizedBrightness)
+ } catch (e: Exception) {
+ ret.put("error", e.message)
+ ret.put("brightness", -1.0)
+ }
+ invoke.resolve(ret)
+ }
+
+ @Command
+ fun set_screen_brightness(invoke: Invoke) {
+ val args = invoke.parseArgs(SetScreenBrightnessRequestArgs::class.java)
+ val ret = JSObject()
+ try {
+ val brightness = (args.brightness ?: 0.5).toFloat()
+ if (brightness < 0.0 || brightness > 1.0) {
+ invoke.reject("Brightness must be between 0.0 and 1.0")
+ return
+ }
+ val layoutParams = activity.window.attributes
+ layoutParams.screenBrightness = brightness
+ activity.window.attributes = layoutParams
+ ret.put("success", true)
+ } catch (e: Exception) {
+ ret.put("success", false)
+ ret.put("error", e.message)
+ }
+ invoke.resolve(ret)
+ }
+
@Command
fun request_manage_storage_permission(invoke: Invoke) {
val ret = JSObject()
diff --git a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/build.rs b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/build.rs
index 30b21d1e..958a1bd9 100644
--- a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/build.rs
+++ b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/build.rs
@@ -15,6 +15,8 @@ const COMMANDS: &[&str] = &[
"iap_restore_purchases",
"get_system_color_scheme",
"get_safe_area_insets",
+ "get_screen_brightness",
+ "set_screen_brightness",
"request_manage_storage_permission",
"checkPermissions",
"requestPermissions",
diff --git a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/ios/Sources/NativeBridgePlugin.swift b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/ios/Sources/NativeBridgePlugin.swift
index d173ada9..8e98f9f5 100644
--- a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/ios/Sources/NativeBridgePlugin.swift
+++ b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/ios/Sources/NativeBridgePlugin.swift
@@ -49,6 +49,10 @@ class LockScreenOrientationRequestArgs: Decodable {
let orientation: String?
}
+class SetScreenBrightnessRequestArgs: Decodable {
+ let brightness: Float?
+}
+
struct InitializeRequest: Decodable {
let publicKey: String?
}
@@ -539,6 +543,28 @@ class NativeBridgePlugin: Plugin {
let colorScheme = (userInterfaceStyle == .dark) ? "dark" : "light"
invoke.resolve(["colorScheme": colorScheme])
}
+
+ @objc public func get_screen_brightness(_ invoke: Invoke) {
+ let brightness = UIScreen.main.brightness
+ invoke.resolve(["brightness": brightness])
+ }
+
+ @objc public func set_screen_brightness(_ invoke: Invoke) {
+ guard let args = try? invoke.parseArgs(SetScreenBrightnessRequestArgs.self) else {
+ return invoke.reject("Failed to parse arguments")
+ }
+
+ let brightness = args.brightness ?? 0.5
+
+ if brightness < 0.0 || brightness > 1.0 {
+ return invoke.reject("Brightness must be between 0.0 and 1.0")
+ }
+
+ DispatchQueue.main.async {
+ UIScreen.main.brightness = CGFloat(brightness)
+ }
+ invoke.resolve(["success": true])
+ }
}
@_cdecl("init_plugin_native_bridge")
diff --git a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/permissions/autogenerated/commands/get_screen_brightness.toml b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/permissions/autogenerated/commands/get_screen_brightness.toml
new file mode 100644
index 00000000..deaf5ad7
--- /dev/null
+++ b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/permissions/autogenerated/commands/get_screen_brightness.toml
@@ -0,0 +1,13 @@
+# Automatically generated - DO NOT EDIT!
+
+"$schema" = "../../schemas/schema.json"
+
+[[permission]]
+identifier = "allow-get-screen-brightness"
+description = "Enables the get_screen_brightness command without any pre-configured scope."
+commands.allow = ["get_screen_brightness"]
+
+[[permission]]
+identifier = "deny-get-screen-brightness"
+description = "Denies the get_screen_brightness command without any pre-configured scope."
+commands.deny = ["get_screen_brightness"]
diff --git a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/permissions/autogenerated/commands/set_screen_brightness.toml b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/permissions/autogenerated/commands/set_screen_brightness.toml
new file mode 100644
index 00000000..468d7dc7
--- /dev/null
+++ b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/permissions/autogenerated/commands/set_screen_brightness.toml
@@ -0,0 +1,13 @@
+# Automatically generated - DO NOT EDIT!
+
+"$schema" = "../../schemas/schema.json"
+
+[[permission]]
+identifier = "allow-set-screen-brightness"
+description = "Enables the set_screen_brightness command without any pre-configured scope."
+commands.allow = ["set_screen_brightness"]
+
+[[permission]]
+identifier = "deny-set-screen-brightness"
+description = "Denies the set_screen_brightness command without any pre-configured scope."
+commands.deny = ["set_screen_brightness"]
diff --git a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/permissions/autogenerated/reference.md b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/permissions/autogenerated/reference.md
index 9dd17e8f..ea21b9b1 100644
--- a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/permissions/autogenerated/reference.md
+++ b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/permissions/autogenerated/reference.md
@@ -20,6 +20,8 @@ Default permissions for the plugin
- `allow-iap-restore-purchases`
- `allow-get-system-color-scheme`
- `allow-get-safe-area-insets`
+- `allow-get-screen-brightness`
+- `allow-set-screen-brightness`
- `allow-request-manage-storage-permission`
- `allow-checkPermissions`
- `allow-requestPermissions`
@@ -166,6 +168,32 @@ Denies the get_safe_area_insets command without any pre-configured scope.
|
+`native-bridge:allow-get-screen-brightness`
+
+ |
+
+
+Enables the get_screen_brightness command without any pre-configured scope.
+
+ |
+
+
+
+|
+
+`native-bridge:deny-get-screen-brightness`
+
+ |
+
+
+Denies the get_screen_brightness command without any pre-configured scope.
+
+ |
+
+
+
+|
+
`native-bridge:allow-get-status-bar-height`
|
@@ -478,6 +506,32 @@ Denies the request_manage_storage_permission command without any pre-configured
|
+`native-bridge:allow-set-screen-brightness`
+
+ |
+
+
+Enables the set_screen_brightness command without any pre-configured scope.
+
+ |
+
+
+
+|
+
+`native-bridge:deny-set-screen-brightness`
+
+ |
+
+
+Denies the set_screen_brightness command without any pre-configured scope.
+
+ |
+
+
+
+|
+
`native-bridge:allow-set-system-ui-visibility`
|
diff --git a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/permissions/default.toml b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/permissions/default.toml
index 0e3ff07a..949455a2 100644
--- a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/permissions/default.toml
+++ b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/permissions/default.toml
@@ -17,6 +17,8 @@ permissions = [
"allow-iap-restore-purchases",
"allow-get-system-color-scheme",
"allow-get-safe-area-insets",
+ "allow-get-screen-brightness",
+ "allow-set-screen-brightness",
"allow-request-manage-storage-permission",
"allow-checkPermissions",
"allow-requestPermissions",
diff --git a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/permissions/schemas/schema.json b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/permissions/schemas/schema.json
index d5588e4e..7624fcce 100644
--- a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/permissions/schemas/schema.json
+++ b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/permissions/schemas/schema.json
@@ -354,6 +354,18 @@
"const": "deny-get-safe-area-insets",
"markdownDescription": "Denies the get_safe_area_insets command without any pre-configured scope."
},
+ {
+ "description": "Enables the get_screen_brightness command without any pre-configured scope.",
+ "type": "string",
+ "const": "allow-get-screen-brightness",
+ "markdownDescription": "Enables the get_screen_brightness command without any pre-configured scope."
+ },
+ {
+ "description": "Denies the get_screen_brightness command without any pre-configured scope.",
+ "type": "string",
+ "const": "deny-get-screen-brightness",
+ "markdownDescription": "Denies the get_screen_brightness command without any pre-configured scope."
+ },
{
"description": "Enables the get_status_bar_height command without any pre-configured scope.",
"type": "string",
@@ -498,6 +510,18 @@
"const": "deny-request-manage-storage-permission",
"markdownDescription": "Denies the request_manage_storage_permission command without any pre-configured scope."
},
+ {
+ "description": "Enables the set_screen_brightness command without any pre-configured scope.",
+ "type": "string",
+ "const": "allow-set-screen-brightness",
+ "markdownDescription": "Enables the set_screen_brightness command without any pre-configured scope."
+ },
+ {
+ "description": "Denies the set_screen_brightness command without any pre-configured scope.",
+ "type": "string",
+ "const": "deny-set-screen-brightness",
+ "markdownDescription": "Denies the set_screen_brightness command without any pre-configured scope."
+ },
{
"description": "Enables the set_system_ui_visibility command without any pre-configured scope.",
"type": "string",
@@ -523,10 +547,10 @@
"markdownDescription": "Denies the use_background_audio command without any pre-configured scope."
},
{
- "description": "Default permissions for the plugin\n#### This default permission set includes:\n\n- `allow-auth-with-safari`\n- `allow-auth-with-custom-tab`\n- `allow-copy-uri-to-path`\n- `allow-use-background-audio`\n- `allow-install-package`\n- `allow-set-system-ui-visibility`\n- `allow-get-status-bar-height`\n- `allow-get-sys-fonts-list`\n- `allow-intercept-keys`\n- `allow-lock-screen-orientation`\n- `allow-iap-initialize`\n- `allow-iap-fetch-products`\n- `allow-iap-purchase-product`\n- `allow-iap-restore-purchases`\n- `allow-get-system-color-scheme`\n- `allow-get-safe-area-insets`\n- `allow-request-manage-storage-permission`\n- `allow-checkPermissions`\n- `allow-requestPermissions`",
+ "description": "Default permissions for the plugin\n#### This default permission set includes:\n\n- `allow-auth-with-safari`\n- `allow-auth-with-custom-tab`\n- `allow-copy-uri-to-path`\n- `allow-use-background-audio`\n- `allow-install-package`\n- `allow-set-system-ui-visibility`\n- `allow-get-status-bar-height`\n- `allow-get-sys-fonts-list`\n- `allow-intercept-keys`\n- `allow-lock-screen-orientation`\n- `allow-iap-initialize`\n- `allow-iap-fetch-products`\n- `allow-iap-purchase-product`\n- `allow-iap-restore-purchases`\n- `allow-get-system-color-scheme`\n- `allow-get-safe-area-insets`\n- `allow-get-screen-brightness`\n- `allow-set-screen-brightness`\n- `allow-request-manage-storage-permission`\n- `allow-checkPermissions`\n- `allow-requestPermissions`",
"type": "string",
"const": "default",
- "markdownDescription": "Default permissions for the plugin\n#### This default permission set includes:\n\n- `allow-auth-with-safari`\n- `allow-auth-with-custom-tab`\n- `allow-copy-uri-to-path`\n- `allow-use-background-audio`\n- `allow-install-package`\n- `allow-set-system-ui-visibility`\n- `allow-get-status-bar-height`\n- `allow-get-sys-fonts-list`\n- `allow-intercept-keys`\n- `allow-lock-screen-orientation`\n- `allow-iap-initialize`\n- `allow-iap-fetch-products`\n- `allow-iap-purchase-product`\n- `allow-iap-restore-purchases`\n- `allow-get-system-color-scheme`\n- `allow-get-safe-area-insets`\n- `allow-request-manage-storage-permission`\n- `allow-checkPermissions`\n- `allow-requestPermissions`"
+ "markdownDescription": "Default permissions for the plugin\n#### This default permission set includes:\n\n- `allow-auth-with-safari`\n- `allow-auth-with-custom-tab`\n- `allow-copy-uri-to-path`\n- `allow-use-background-audio`\n- `allow-install-package`\n- `allow-set-system-ui-visibility`\n- `allow-get-status-bar-height`\n- `allow-get-sys-fonts-list`\n- `allow-intercept-keys`\n- `allow-lock-screen-orientation`\n- `allow-iap-initialize`\n- `allow-iap-fetch-products`\n- `allow-iap-purchase-product`\n- `allow-iap-restore-purchases`\n- `allow-get-system-color-scheme`\n- `allow-get-safe-area-insets`\n- `allow-get-screen-brightness`\n- `allow-set-screen-brightness`\n- `allow-request-manage-storage-permission`\n- `allow-checkPermissions`\n- `allow-requestPermissions`"
}
]
}
diff --git a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/src/commands.rs b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/src/commands.rs
index 021c2130..655b12cb 100644
--- a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/src/commands.rs
+++ b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/src/commands.rs
@@ -127,6 +127,21 @@ pub(crate) async fn get_safe_area_insets(
app.native_bridge().get_safe_area_insets()
}
+#[command]
+pub(crate) async fn get_screen_brightness(
+ app: AppHandle,
+) -> Result {
+ app.native_bridge().get_screen_brightness()
+}
+
+#[command]
+pub(crate) async fn set_screen_brightness(
+ app: AppHandle,
+ payload: SetScreenBrightnessRequest,
+) -> Result {
+ app.native_bridge().set_screen_brightness(payload)
+}
+
#[command]
pub(crate) async fn request_manage_storage_permission(
app: AppHandle,
diff --git a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/src/desktop.rs b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/src/desktop.rs
index f20f0c87..15d51e99 100644
--- a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/src/desktop.rs
+++ b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/src/desktop.rs
@@ -107,6 +107,17 @@ impl NativeBridge {
Err(crate::Error::UnsupportedPlatformError)
}
+ pub fn get_screen_brightness(&self) -> crate::Result {
+ Err(crate::Error::UnsupportedPlatformError)
+ }
+
+ pub fn set_screen_brightness(
+ &self,
+ _payload: SetScreenBrightnessRequest,
+ ) -> crate::Result {
+ Err(crate::Error::UnsupportedPlatformError)
+ }
+
pub fn request_manage_storage_permission(
&self,
) -> crate::Result {
diff --git a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/src/lib.rs b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/src/lib.rs
index e8cf47ef..ae00264f 100644
--- a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/src/lib.rs
+++ b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/src/lib.rs
@@ -53,6 +53,8 @@ pub fn init() -> TauriPlugin {
commands::iap_restore_purchases,
commands::get_system_color_scheme,
commands::get_safe_area_insets,
+ commands::get_screen_brightness,
+ commands::set_screen_brightness,
commands::request_manage_storage_permission,
])
.setup(|app, api| {
diff --git a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/src/mobile.rs b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/src/mobile.rs
index 3f50da39..e93ee844 100644
--- a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/src/mobile.rs
+++ b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/src/mobile.rs
@@ -170,6 +170,25 @@ impl NativeBridge {
}
}
+impl NativeBridge {
+ pub fn get_screen_brightness(&self) -> crate::Result {
+ self.0
+ .run_mobile_plugin("get_screen_brightness", ())
+ .map_err(Into::into)
+ }
+}
+
+impl NativeBridge {
+ pub fn set_screen_brightness(
+ &self,
+ payload: SetScreenBrightnessRequest,
+ ) -> crate::Result {
+ self.0
+ .run_mobile_plugin("set_screen_brightness", payload)
+ .map_err(Into::into)
+ }
+}
+
impl NativeBridge {
pub fn request_manage_storage_permission(
&self,
diff --git a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/src/models.rs b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/src/models.rs
index d8b446b7..7649eef3 100644
--- a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/src/models.rs
+++ b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/src/models.rs
@@ -168,6 +168,25 @@ pub struct GetSafeAreaInsetsResponse {
pub right: f64,
}
+#[derive(Debug, Deserialize, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct GetScreenBrightnessResponse {
+ pub brightness: f64,
+}
+
+#[derive(Debug, Deserialize, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct SetScreenBrightnessRequest {
+ pub brightness: f64, // 0.0 to 1.0
+}
+
+#[derive(Debug, Deserialize, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct SetScreenBrightnessResponse {
+ pub success: bool,
+ pub error: Option,
+}
+
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RequestManageStoragePermissionResponse {
diff --git a/apps/readest-app/src/app/reader/components/footerbar/ColorPanel.tsx b/apps/readest-app/src/app/reader/components/footerbar/ColorPanel.tsx
new file mode 100644
index 00000000..57eed3f1
--- /dev/null
+++ b/apps/readest-app/src/app/reader/components/footerbar/ColorPanel.tsx
@@ -0,0 +1,157 @@
+import clsx from 'clsx';
+import React, { useCallback, useEffect, useMemo } from 'react';
+import { PiSun, PiMoon } from 'react-icons/pi';
+import { TbSunMoon } from 'react-icons/tb';
+import { useEnv } from '@/context/EnvContext';
+import { useThemeStore } from '@/store/themeStore';
+import { useTranslation } from '@/hooks/useTranslation';
+import { useSettingsStore } from '@/store/settingsStore';
+import { useDeviceControlStore } from '@/store/deviceStore';
+import { themes } from '@/styles/themes';
+import { debounce } from '@/utils/debounce';
+import Slider from '@/components/Slider';
+
+const SCREEN_BRIGHTNESS_LIMITS = {
+ MIN: 0,
+ MAX: 100,
+ DEFAULT: 50,
+} as const;
+
+interface ColorPanelProps {
+ actionTab: string;
+ bottomOffset: string;
+}
+
+export const ColorPanel: React.FC = ({ actionTab, bottomOffset }) => {
+ const _ = useTranslation();
+ const { envConfig, appService } = useEnv();
+ const { settings, setSettings, saveSettings } = useSettingsStore();
+ const { getScreenBrightness, setScreenBrightness } = useDeviceControlStore();
+ const { themeMode, themeColor, isDarkMode, setThemeMode, setThemeColor } = useThemeStore();
+
+ const [screenBrightnessValue, setScreenBrightnessValue] = React.useState(
+ settings.screenBrightness >= 0 ? settings.screenBrightness : SCREEN_BRIGHTNESS_LIMITS.DEFAULT,
+ );
+
+ useEffect(() => {
+ if (!appService?.isMobileApp) return;
+ if (settings.screenBrightness >= 0) return;
+
+ getScreenBrightness().then((brightness) => {
+ if (brightness >= 0.0 && brightness <= 1.0) {
+ const screenBrightness = Math.round(brightness * 100);
+ setScreenBrightnessValue(screenBrightness);
+ }
+ });
+ }, [appService, settings, setSettings, getScreenBrightness]);
+
+ const debouncedSetScreenBrightness = useMemo(
+ () =>
+ debounce(async (value: number) => {
+ settings.screenBrightness = value;
+ setSettings(settings);
+ saveSettings(envConfig, settings);
+ await setScreenBrightness(value / 100);
+ }, 100),
+ [envConfig, settings, setSettings, saveSettings, setScreenBrightness],
+ );
+
+ const handleScreenBrightnessChange = useCallback(
+ async (value: number) => {
+ if (!appService?.isMobileApp) return;
+
+ setScreenBrightnessValue(value);
+ debouncedSetScreenBrightness(value);
+ },
+ [appService, debouncedSetScreenBrightness],
+ );
+
+ const cycleThemeMode = () => {
+ const nextMode = themeMode === 'auto' ? 'light' : themeMode === 'light' ? 'dark' : 'auto';
+ setThemeMode(nextMode);
+ };
+
+ const classes = clsx(
+ 'footerbar-color-mobile bg-base-200 absolute flex w-full flex-col items-center gap-y-8 px-4 transition-all sm:hidden',
+ actionTab === 'color'
+ ? 'pointer-events-auto translate-y-0 pb-4 pt-8 ease-out'
+ : 'pointer-events-none invisible translate-y-full overflow-hidden pb-0 pt-0 ease-in',
+ );
+
+ return (
+
+ {appService?.hasScreenBrightness && (
+
}
+ maxIcon={
}
+ onChange={handleScreenBrightnessChange}
+ min={SCREEN_BRIGHTNESS_LIMITS.MIN}
+ max={SCREEN_BRIGHTNESS_LIMITS.MAX}
+ />
+ )}
+
+
+
+ {_('Color')}
+
+
+
+ {themes.map(({ name, label, colors }) => (
+
+ ))}
+
+
+
+
+ );
+};
diff --git a/apps/readest-app/src/app/reader/components/footerbar/DesktopFooterBar.tsx b/apps/readest-app/src/app/reader/components/footerbar/DesktopFooterBar.tsx
index 340804be..806e2f3f 100644
--- a/apps/readest-app/src/app/reader/components/footerbar/DesktopFooterBar.tsx
+++ b/apps/readest-app/src/app/reader/components/footerbar/DesktopFooterBar.tsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { useCallback, useEffect } from 'react';
import { FaHeadphones } from 'react-icons/fa6';
import { RiArrowLeftSLine, RiArrowRightSLine } from 'react-icons/ri';
import { RiArrowGoBackLine, RiArrowGoForwardLine } from 'react-icons/ri';
@@ -22,6 +22,25 @@ const DesktopFooterBar: React.FC = ({
const view = getView(bookKey);
const viewState = getViewState(bookKey);
const viewSettings = getViewSettings(bookKey);
+
+ const [progressValue, setProgressValue] = React.useState(
+ progressValid ? progressFraction * 100 : 0,
+ );
+
+ useEffect(() => {
+ if (progressValid) {
+ setProgressValue(progressFraction * 100);
+ }
+ }, [progressValid, progressFraction]);
+
+ const handleProgressChange = useCallback(
+ (value: number) => {
+ setProgressValue(value);
+ navigationHandlers.onProgressChange(value);
+ },
+ [navigationHandlers],
+ );
+
const isMobile = window.innerWidth < 640 || window.innerHeight < 640;
return (
@@ -78,8 +97,8 @@ const DesktopFooterBar: React.FC = ({
min={0}
max={100}
aria-label={_('Jump to Location')}
- value={progressValid ? progressFraction * 100 : 0}
- onChange={(e) => navigationHandlers.onProgressChange(parseInt(e.target.value, 10))}
+ value={progressValue}
+ onChange={(e) => handleProgressChange(parseInt(e.target.value, 10))}
/>
}
diff --git a/apps/readest-app/src/app/reader/components/footerbar/FontLayoutPanel.tsx b/apps/readest-app/src/app/reader/components/footerbar/FontLayoutPanel.tsx
index 0e73d99a..e421c719 100644
--- a/apps/readest-app/src/app/reader/components/footerbar/FontLayoutPanel.tsx
+++ b/apps/readest-app/src/app/reader/components/footerbar/FontLayoutPanel.tsx
@@ -30,14 +30,14 @@ const MARGIN_CONSTANTS = {
interface FontLayoutPanelProps {
bookKey: string;
actionTab: string;
- mobileBottomOffset: string;
+ bottomOffset: string;
marginIconSize: number;
}
export const FontLayoutPanel: React.FC = ({
bookKey,
actionTab,
- mobileBottomOffset,
+ bottomOffset,
marginIconSize,
}) => {
const _ = useTranslation();
@@ -98,7 +98,7 @@ export const FontLayoutPanel: React.FC = ({
);
return (
-
+
= ({
return (progressInfo.current + 1) / progressInfo.total;
}, [progressValid, progressInfo]);
- const handleProgressChange = useCallback(
- (value: number) => {
- view?.goToFraction(value / 100.0);
- },
+ const handleProgressChange = useMemo(
+ () =>
+ debounce((value: number) => {
+ view?.goToFraction(value / 100.0);
+ }, 100),
[view],
);
diff --git a/apps/readest-app/src/app/reader/components/footerbar/MobileFooterBar.tsx b/apps/readest-app/src/app/reader/components/footerbar/MobileFooterBar.tsx
index 36ed2ae3..1bb2c1d1 100644
--- a/apps/readest-app/src/app/reader/components/footerbar/MobileFooterBar.tsx
+++ b/apps/readest-app/src/app/reader/components/footerbar/MobileFooterBar.tsx
@@ -1,9 +1,10 @@
import React from 'react';
+import { useResponsiveSize } from '@/hooks/useResponsiveSize';
+import { FooterBarChildProps } from './types';
import { NavigationPanel } from './NavigationPanel';
import { FontLayoutPanel } from './FontLayoutPanel';
+import { ColorPanel } from './ColorPanel';
import { NavigationBar } from './NavigationBar';
-import { FooterBarChildProps } from './types';
-import { useResponsiveSize } from '@/hooks/useResponsiveSize';
const MobileFooterBar: React.FC = ({
bookKey,
@@ -22,8 +23,9 @@ const MobileFooterBar: React.FC = ({
return (
<>
+
= ({
/>
diff --git a/apps/readest-app/src/app/reader/components/footerbar/NavigationBar.tsx b/apps/readest-app/src/app/reader/components/footerbar/NavigationBar.tsx
index 9c0e95bb..d211280c 100644
--- a/apps/readest-app/src/app/reader/components/footerbar/NavigationBar.tsx
+++ b/apps/readest-app/src/app/reader/components/footerbar/NavigationBar.tsx
@@ -1,9 +1,9 @@
import clsx from 'clsx';
import React from 'react';
import { IoIosList as TOCIcon } from 'react-icons/io';
-import { PiNotePencil as NoteIcon } from 'react-icons/pi';
import { RxSlider as SliderIcon } from 'react-icons/rx';
import { RiFontFamily as FontIcon } from 'react-icons/ri';
+import { PiSun as ColorIcon } from 'react-icons/pi';
import { MdOutlineHeadphones as TTSIcon } from 'react-icons/md';
import { useReaderStore } from '@/store/readerStore';
import { useTranslation } from '@/hooks/useTranslation';
@@ -39,7 +39,11 @@ export const NavigationBar: React.FC = ({
icon={}
onClick={() => onSetActionTab('toc')}
/>
- } onClick={() => onSetActionTab('note')} />
+ }
+ onClick={() => onSetActionTab('color')}
+ />
}
diff --git a/apps/readest-app/src/app/reader/components/footerbar/NavigationPanel.tsx b/apps/readest-app/src/app/reader/components/footerbar/NavigationPanel.tsx
index edf2a30c..89396190 100644
--- a/apps/readest-app/src/app/reader/components/footerbar/NavigationPanel.tsx
+++ b/apps/readest-app/src/app/reader/components/footerbar/NavigationPanel.tsx
@@ -1,5 +1,5 @@
-import React from 'react';
import clsx from 'clsx';
+import React, { useCallback, useEffect } from 'react';
import { RiArrowLeftSLine, RiArrowRightSLine } from 'react-icons/ri';
import { RiArrowGoBackLine, RiArrowGoForwardLine } from 'react-icons/ri';
import { RiArrowLeftDoubleLine, RiArrowRightDoubleLine } from 'react-icons/ri';
@@ -30,6 +30,25 @@ export const NavigationPanel: React.FC = ({
sliderHeight,
}) => {
const _ = useTranslation();
+
+ const [progressValue, setProgressValue] = React.useState(
+ progressValid ? progressFraction * 100 : 0,
+ );
+
+ useEffect(() => {
+ if (progressValid) {
+ setProgressValue(progressFraction * 100);
+ }
+ }, [progressValid, progressFraction]);
+
+ const handleProgressChange = useCallback(
+ (value: number) => {
+ setProgressValue(value);
+ navigationHandlers.onProgressChange(value);
+ },
+ [navigationHandlers],
+ );
+
const classes = clsx(
'footerbar-progress-mobile bg-base-200 absolute flex w-full flex-col items-center gap-y-8 px-4 transition-all sm:hidden',
actionTab === 'progress'
@@ -43,9 +62,9 @@ export const NavigationPanel: React.FC = ({
diff --git a/apps/readest-app/src/components/Providers.tsx b/apps/readest-app/src/components/Providers.tsx
index 48fcffa9..a5cc14ad 100644
--- a/apps/readest-app/src/components/Providers.tsx
+++ b/apps/readest-app/src/components/Providers.tsx
@@ -9,6 +9,7 @@ import { CSPostHogProvider } from '@/context/PHContext';
import { SyncProvider } from '@/context/SyncContext';
import { initSystemThemeListener, loadDataTheme } from '@/store/themeStore';
import { useSettingsStore } from '@/store/settingsStore';
+import { useDeviceControlStore } from '@/store/deviceStore';
import { useDefaultIconSize } from '@/hooks/useResponsiveSize';
import { useSafeAreaInsets } from '@/hooks/useSafeAreaInsets';
import { getLocale } from '@/utils/misc';
@@ -16,6 +17,7 @@ import { getLocale } from '@/utils/misc';
const Providers = ({ children }: { children: React.ReactNode }) => {
const { appService } = useEnv();
const { applyUILanguage } = useSettingsStore();
+ const { setScreenBrightness } = useDeviceControlStore();
const iconSize = useDefaultIconSize();
useSafeAreaInsets(); // Initialize safe area insets
@@ -38,9 +40,13 @@ const Providers = ({ children }: { children: React.ReactNode }) => {
initSystemThemeListener(appService);
appService.loadSettings().then((settings) => {
applyUILanguage(settings.globalViewSettings?.uiLanguage);
+ const brightness = settings.screenBrightness;
+ if (appService.hasScreenBrightness && brightness >= 0) {
+ setScreenBrightness(brightness / 100);
+ }
});
}
- }, [appService, applyUILanguage]);
+ }, [appService, applyUILanguage, setScreenBrightness]);
// Make sure appService is available in all children components
if (!appService) return;
diff --git a/apps/readest-app/src/components/Slider.tsx b/apps/readest-app/src/components/Slider.tsx
index 1d6f53de..cee4406f 100644
--- a/apps/readest-app/src/components/Slider.tsx
+++ b/apps/readest-app/src/components/Slider.tsx
@@ -9,6 +9,8 @@ interface SliderProps {
heightPx?: number;
minLabel?: string;
maxLabel?: string;
+ minIcon?: React.ReactNode;
+ maxIcon?: React.ReactNode;
bubbleElement?: React.ReactNode;
bubbleLabel?: string;
className?: string;
@@ -27,6 +29,8 @@ const Slider: React.FC
= ({
heightPx = 40,
minLabel = '',
maxLabel = '',
+ minIcon,
+ maxIcon,
bubbleElement,
bubbleLabel = '',
className = '',
@@ -63,6 +67,7 @@ const Slider: React.FC = ({
}, [initialValue]);
const percentage = ((value - min) / (max - min)) * 100;
+ const visualPercentage = (percentage / 100) * 95;
return (
= ({
className='bg-base-300 absolute h-full rounded-full'
style={{
width:
- percentage > 0
- ? `max(calc(${percentage}% + ${heightPx / 2}px), ${heightPx}px)`
+ visualPercentage > 0
+ ? `max(calc(${visualPercentage}% + ${heightPx / 2}px), ${heightPx}px)`
: '0px',
[isRtl ? 'right' : 'left']: 0,
}}
>
{/* Min/Max labels */}
- {minLabel}
- {maxLabel}
+ {minIcon ? minIcon : {minLabel}}
+ {maxIcon ? maxIcon : {maxLabel}}
{/* Thumb bubble */}
= {
alwaysInForeground: false,
autoCheckUpdates: true,
screenWakeLock: false,
+ screenBrightness: -1, // -1~100, -1 for system default
openLastBooks: false,
lastOpenBooks: [],
autoImportBooksOnOpen: false,
diff --git a/apps/readest-app/src/services/nativeAppService.ts b/apps/readest-app/src/services/nativeAppService.ts
index eb6cb1dc..bb7dab5e 100644
--- a/apps/readest-app/src/services/nativeAppService.ts
+++ b/apps/readest-app/src/services/nativeAppService.ts
@@ -348,6 +348,7 @@ export class NativeAppService extends BaseAppService {
// orientation lock is not supported on iPad
override hasOrientationLock =
(OS_TYPE === 'ios' && getOSPlatform() === 'ios') || OS_TYPE === 'android';
+ override hasScreenBrightness = OS_TYPE === 'ios' || OS_TYPE === 'android';
// CustomizeRootDir has a blocker on macOS App Store builds due to Security Scoped Resource restrictions.
// See: https://github.com/tauri-apps/tauri/issues/3716
override canCustomizeRootDir = process.env['NEXT_PUBLIC_DIST_CHANNEL'] !== 'appstore';
diff --git a/apps/readest-app/src/store/deviceStore.ts b/apps/readest-app/src/store/deviceStore.ts
index 4ba11270..218b6ca7 100644
--- a/apps/readest-app/src/store/deviceStore.ts
+++ b/apps/readest-app/src/store/deviceStore.ts
@@ -1,5 +1,5 @@
import { create } from 'zustand';
-import { interceptKeys } from '@/utils/bridge';
+import { interceptKeys, getScreenBrightness, setScreenBrightness } from '@/utils/bridge';
import { eventDispatcher } from '@/utils/event';
declare global {
@@ -23,6 +23,8 @@ type DeviceControlState = {
backKeyIntercepted: boolean;
volumeKeysInterceptionCount: number;
backKeyInterceptionCount: number;
+ getScreenBrightness: () => Promise; // 0.0 to 1.0
+ setScreenBrightness: (brightness: number) => Promise; // brightness: 0.0 to 1.0
acquireVolumeKeyInterception: () => void;
releaseVolumeKeyInterception: () => void;
acquireBackKeyInterception: () => void;
@@ -74,4 +76,13 @@ export const useDeviceControlStore = create((set, get) => ({
set({ backKeyInterceptionCount: backKeyInterceptionCount - 1 });
}
},
+
+ getScreenBrightness: async () => {
+ const res = await getScreenBrightness();
+ return res.brightness;
+ },
+
+ setScreenBrightness: async (brightness: number) => {
+ await setScreenBrightness({ brightness });
+ },
}));
diff --git a/apps/readest-app/src/types/settings.ts b/apps/readest-app/src/types/settings.ts
index 71b4832a..d7771a20 100644
--- a/apps/readest-app/src/types/settings.ts
+++ b/apps/readest-app/src/types/settings.ts
@@ -46,6 +46,7 @@ export interface SystemSettings {
openBookInNewWindow: boolean;
autoCheckUpdates: boolean;
screenWakeLock: boolean;
+ screenBrightness: number;
alwaysShowStatusBar: boolean;
alwaysInForeground: boolean;
openLastBooks: boolean;
diff --git a/apps/readest-app/src/types/system.ts b/apps/readest-app/src/types/system.ts
index 8e4ead99..a71de455 100644
--- a/apps/readest-app/src/types/system.ts
+++ b/apps/readest-app/src/types/system.ts
@@ -51,6 +51,7 @@ export interface AppService {
hasHaptics: boolean;
hasUpdater: boolean;
hasOrientationLock: boolean;
+ hasScreenBrightness: boolean;
isMobile: boolean;
isAppDataSandbox: boolean;
isMobileApp: boolean;
diff --git a/apps/readest-app/src/utils/bridge.ts b/apps/readest-app/src/utils/bridge.ts
index 9606ecf9..40413ae9 100644
--- a/apps/readest-app/src/utils/bridge.ts
+++ b/apps/readest-app/src/utils/bridge.ts
@@ -65,6 +65,20 @@ export interface GetSafeAreaInsetsResponse {
error?: string;
}
+interface GetScreenBrightnessResponse {
+ brightness: number; // 0.0 to 1.0
+ error?: string;
+}
+
+interface SetScreenBrightnessRequest {
+ brightness: number; // 0.0 to 1.0
+}
+
+interface SetScreenBrightnessResponse {
+ success: boolean;
+ error?: string;
+}
+
export async function copyURIToPath(request: CopyURIRequest): Promise {
const result = await invoke('plugin:native-bridge|copy_uri_to_path', {
payload: request,
@@ -145,3 +159,22 @@ export async function getSafeAreaInsets(): Promise {
);
return result;
}
+
+export async function getScreenBrightness(): Promise {
+ const result = await invoke(
+ 'plugin:native-bridge|get_screen_brightness',
+ );
+ return result;
+}
+
+export async function setScreenBrightness(
+ request: SetScreenBrightnessRequest,
+): Promise {
+ const result = await invoke(
+ 'plugin:native-bridge|set_screen_brightness',
+ {
+ payload: request,
+ },
+ );
+ return result;
+}