diff --git a/apps/readest-app/public/locales/ar/translation.json b/apps/readest-app/public/locales/ar/translation.json index 55481451..a5711837 100644 --- a/apps/readest-app/public/locales/ar/translation.json +++ b/apps/readest-app/public/locales/ar/translation.json @@ -299,5 +299,9 @@ "Link Color": "لون الرابط", "Volume Keys for Page Flip": "مفاتيح الصوت لتقليب الصفحات", "Clicks for Page Flip": "نقرات لتقليب الصفحات", - "Swap Clicks Area": "تبديل منطقة النقرات" + "Swap Clicks Area": "تبديل منطقة النقرات", + "Screen": "الشاشة", + "Orientation": "الاتجاه", + "Portrait": "العمودي", + "Landscape": "الأفقي" } diff --git a/apps/readest-app/public/locales/de/translation.json b/apps/readest-app/public/locales/de/translation.json index 8f628284..44fb19d9 100644 --- a/apps/readest-app/public/locales/de/translation.json +++ b/apps/readest-app/public/locales/de/translation.json @@ -299,5 +299,9 @@ "Link Color": "Linkfarbe", "Volume Keys for Page Flip": "Volumen-Tasten für Seitenwechsel", "Clicks for Page Flip": "Tippen zum Blättern", - "Swap Clicks Area": "Tippbereiche tauschen" + "Swap Clicks Area": "Tippbereiche tauschen", + "Screen": "Bildschirm", + "Orientation": "Orientierung", + "Portrait": "Hochformat", + "Landscape": "Querformat" } diff --git a/apps/readest-app/public/locales/el/translation.json b/apps/readest-app/public/locales/el/translation.json index 992aa705..97bed9ab 100644 --- a/apps/readest-app/public/locales/el/translation.json +++ b/apps/readest-app/public/locales/el/translation.json @@ -299,5 +299,9 @@ "Link Color": "Χρώμα συνδέσμου", "Volume Keys for Page Flip": "Πλήκτρα έντασης για ανατροπή σελίδας", "Clicks for Page Flip": "Κλικ για ανατροπή σελίδας", - "Swap Clicks Area": "Ανταλλαγή περιοχής κλικ" + "Swap Clicks Area": "Ανταλλαγή περιοχής κλικ", + "Screen": "Οθόνη", + "Orientation": "Προσανατολισμός", + "Portrait": "Πορτραίτο", + "Landscape": "Τοπίο" } diff --git a/apps/readest-app/public/locales/es/translation.json b/apps/readest-app/public/locales/es/translation.json index 9494e7c8..63a918cf 100644 --- a/apps/readest-app/public/locales/es/translation.json +++ b/apps/readest-app/public/locales/es/translation.json @@ -299,5 +299,9 @@ "Link Color": "Color del enlace", "Volume Keys for Page Flip": "Botones de volumen para pasar página", "Clicks for Page Flip": "Toques para pasar página", - "Swap Clicks Area": "Invertir zonas de toque" + "Swap Clicks Area": "Invertir zonas de toque", + "Screen": "Pantalla", + "Orientation": "Orientación", + "Portrait": "Vertical", + "Landscape": "Horizontal" } diff --git a/apps/readest-app/public/locales/fr/translation.json b/apps/readest-app/public/locales/fr/translation.json index 7f7c055e..7df07499 100644 --- a/apps/readest-app/public/locales/fr/translation.json +++ b/apps/readest-app/public/locales/fr/translation.json @@ -299,5 +299,9 @@ "Link Color": "Couleur du lien", "Volume Keys for Page Flip": "Boutons volume pour tourner la page", "Clicks for Page Flip": "Taps pour tourner la page", - "Swap Clicks Area": "Inverser zones de tap" + "Swap Clicks Area": "Inverser zones de tap", + "Screen": "Écran", + "Orientation": "Orientation", + "Portrait": "Portrait", + "Landscape": "Paysage" } diff --git a/apps/readest-app/public/locales/hi/translation.json b/apps/readest-app/public/locales/hi/translation.json index f62a0cee..7a34a275 100644 --- a/apps/readest-app/public/locales/hi/translation.json +++ b/apps/readest-app/public/locales/hi/translation.json @@ -299,5 +299,9 @@ "Link Color": "लिंक रंग", "Volume Keys for Page Flip": "पृष्ठ फ़्लिप के लिए वॉल्यूम कुंजियाँ", "Clicks for Page Flip": "पृष्ठ फ़्लिप के लिए क्लिक करें", - "Swap Clicks Area": "क्लिक क्षेत्र स्वैप करें" + "Swap Clicks Area": "क्लिक क्षेत्र स्वैप करें", + "Screen": "स्क्रीन", + "Orientation": "अवयव", + "Portrait": "पोर्ट्रेट", + "Landscape": "लैंडस्केप" } diff --git a/apps/readest-app/public/locales/id/translation.json b/apps/readest-app/public/locales/id/translation.json index b2192324..46f6db5d 100644 --- a/apps/readest-app/public/locales/id/translation.json +++ b/apps/readest-app/public/locales/id/translation.json @@ -299,5 +299,9 @@ "Link Color": "Warna Tautan", "Volume Keys for Page Flip": "Volume Keys untuk Pembalikan Halaman", "Clicks for Page Flip": "Klik untuk Pembalikan Halaman", - "Swap Clicks Area": "Area Klik Tukar" + "Swap Clicks Area": "Area Klik Tukar", + "Screen": "Screen", + "Orientation": "Orientasi", + "Portrait": "Potret", + "Landscape": "Lanskap" } diff --git a/apps/readest-app/public/locales/it/translation.json b/apps/readest-app/public/locales/it/translation.json index 3b6e4bc0..fddd0049 100644 --- a/apps/readest-app/public/locales/it/translation.json +++ b/apps/readest-app/public/locales/it/translation.json @@ -299,5 +299,9 @@ "Link Color": "Colore link", "Volume Keys for Page Flip": "Tasti volume per girare pagina", "Clicks for Page Flip": "Clic per girare pagina", - "Swap Clicks Area": "Inverti area dei clic" + "Swap Clicks Area": "Inverti area dei clic", + "Screen": "Schermo", + "Orientation": "Orientamento", + "Portrait": "Ritratto", + "Landscape": "Paesaggio" } diff --git a/apps/readest-app/public/locales/ja/translation.json b/apps/readest-app/public/locales/ja/translation.json index b81641eb..5e2c4fdd 100644 --- a/apps/readest-app/public/locales/ja/translation.json +++ b/apps/readest-app/public/locales/ja/translation.json @@ -299,5 +299,9 @@ "Link Color": "リンクカラー", "Volume Keys for Page Flip": "音量キーでページめくり", "Clicks for Page Flip": "タップでページめくり", - "Swap Clicks Area": "タップ領域を入れ替え" + "Swap Clicks Area": "タップ領域を入れ替え", + "Screen": "画面", + "Orientation": "向き", + "Portrait": "縦", + "Landscape": "横" } diff --git a/apps/readest-app/public/locales/ko/translation.json b/apps/readest-app/public/locales/ko/translation.json index d7b1df42..e8d01765 100644 --- a/apps/readest-app/public/locales/ko/translation.json +++ b/apps/readest-app/public/locales/ko/translation.json @@ -299,5 +299,9 @@ "Link Color": "링크 색상", "Volume Keys for Page Flip": "페이지 넘김을 위한 볼륨 키", "Clicks for Page Flip": "페이지 넘김을 위한 클릭", - "Swap Clicks Area": "클릭 영역 교환" + "Swap Clicks Area": "클릭 영역 교환", + "Screen": "화면", + "Orientation": "방향", + "Portrait": "세로", + "Landscape": "가로" } diff --git a/apps/readest-app/public/locales/pl/translation.json b/apps/readest-app/public/locales/pl/translation.json index 564ced4e..611fcd69 100644 --- a/apps/readest-app/public/locales/pl/translation.json +++ b/apps/readest-app/public/locales/pl/translation.json @@ -299,5 +299,9 @@ "Link Color": "Kolor linku", "Volume Keys for Page Flip": "Klucze głośności do przewracania stron", "Clicks for Page Flip": "Kliknięcia do przewracania stron", - "Swap Clicks Area": "Zamień obszar kliknięcia" + "Swap Clicks Area": "Zamień obszar kliknięcia", + "Screen": "Ekran", + "Orientation": "Orientacja", + "Portrait": "Portret", + "Landscape": "Krajobraz" } diff --git a/apps/readest-app/public/locales/pt/translation.json b/apps/readest-app/public/locales/pt/translation.json index b079fe6d..e0cfdd45 100644 --- a/apps/readest-app/public/locales/pt/translation.json +++ b/apps/readest-app/public/locales/pt/translation.json @@ -299,5 +299,9 @@ "Link Color": "Cor do Link", "Volume Keys for Page Flip": "Teclas de Volume para Virar Página", "Clicks for Page Flip": "Cliques para Virar Página", - "Swap Clicks Area": "Trocar Área de Cliques" + "Swap Clicks Area": "Trocar Área de Cliques", + "Screen": "Tela", + "Orientation": "Orientação", + "Portrait": "Retrato", + "Landscape": "Paisagem" } diff --git a/apps/readest-app/public/locales/ru/translation.json b/apps/readest-app/public/locales/ru/translation.json index e36b0b88..1d28a37d 100644 --- a/apps/readest-app/public/locales/ru/translation.json +++ b/apps/readest-app/public/locales/ru/translation.json @@ -299,5 +299,9 @@ "Link Color": "Цвет ссылки", "Volume Keys for Page Flip": "Клавиши громкости для перелистывания страниц", "Clicks for Page Flip": "Клики для перелистывания страниц", - "Swap Clicks Area": "Переключить область кликов" + "Swap Clicks Area": "Переключить область кликов", + "Screen": "Экран", + "Orientation": "Ориентация", + "Portrait": "Портрет", + "Landscape": "Ландшафт" } diff --git a/apps/readest-app/public/locales/tr/translation.json b/apps/readest-app/public/locales/tr/translation.json index d0d72bae..703874f2 100644 --- a/apps/readest-app/public/locales/tr/translation.json +++ b/apps/readest-app/public/locales/tr/translation.json @@ -299,5 +299,9 @@ "Link Color": "Bağlantı Rengi", "Volume Keys for Page Flip": "Sayfa Çevirme için Ses Seviyesi Tuşları", "Clicks for Page Flip": "Sayfa Çevirme için Tıklamalar", - "Swap Clicks Area": "Tıklama Alanını Değiştir" + "Swap Clicks Area": "Tıklama Alanını Değiştir", + "Screen": "Ekran", + "Orientation": "Yönlendirme", + "Portrait": "Portre", + "Landscape": "Yatay" } diff --git a/apps/readest-app/public/locales/uk/translation.json b/apps/readest-app/public/locales/uk/translation.json index e3cf54f7..29a82a91 100644 --- a/apps/readest-app/public/locales/uk/translation.json +++ b/apps/readest-app/public/locales/uk/translation.json @@ -299,5 +299,9 @@ "Link Color": "Колір посилання", "Volume Keys for Page Flip": "Клавіші гучності для перевороту сторінки", "Clicks for Page Flip": "Клацання для перевороту сторінки", - "Swap Clicks Area": "Змінити область клацання" + "Swap Clicks Area": "Змінити область клацання", + "Screen": "Екран", + "Orientation": "Орієнтація", + "Portrait": "Портрет", + "Landscape": "Ландшафт" } diff --git a/apps/readest-app/public/locales/vi/translation.json b/apps/readest-app/public/locales/vi/translation.json index fe7c2ad5..0e8d6b46 100644 --- a/apps/readest-app/public/locales/vi/translation.json +++ b/apps/readest-app/public/locales/vi/translation.json @@ -299,5 +299,9 @@ "Link Color": "Màu liên kết", "Volume Keys for Page Flip": "Phím âm lượng để lật trang", "Clicks for Page Flip": "Nhấp để lật trang", - "Swap Clicks Area": "Đổi khu vực nhấp" + "Swap Clicks Area": "Đổi khu vực nhấp", + "Screen": "Màn hình", + "Orientation": "Định hướng", + "Portrait": "Chân dung", + "Landscape": "Phong cảnh" } diff --git a/apps/readest-app/public/locales/zh-CN/translation.json b/apps/readest-app/public/locales/zh-CN/translation.json index 2cba2fb5..26066b24 100644 --- a/apps/readest-app/public/locales/zh-CN/translation.json +++ b/apps/readest-app/public/locales/zh-CN/translation.json @@ -299,5 +299,9 @@ "Link Color": "链接颜色", "Volume Keys for Page Flip": "音量键翻页", "Clicks for Page Flip": "点击翻页", - "Swap Clicks Area": "交换点击区域" + "Swap Clicks Area": "交换点击区域", + "Screen": "屏幕", + "Orientation": "屏幕方向", + "Portrait": "竖屏", + "Landscape": "横屏" } diff --git a/apps/readest-app/public/locales/zh-TW/translation.json b/apps/readest-app/public/locales/zh-TW/translation.json index 22ba5f52..3c6eec6c 100644 --- a/apps/readest-app/public/locales/zh-TW/translation.json +++ b/apps/readest-app/public/locales/zh-TW/translation.json @@ -299,5 +299,9 @@ "Link Color": "連結顏色", "Volume Keys for Page Flip": "音量鍵翻頁", "Clicks for Page Flip": "點擊翻頁", - "Swap Clicks Area": "交換點擊區域" + "Swap Clicks Area": "交換點擊區域", + "Screen": "螢幕", + "Orientation": "螢幕方向", + "Portrait": "豎屏", + "Landscape": "橫屏" } 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 48e5a288..f9d5469d 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 @@ -12,6 +12,7 @@ import android.view.WindowManager import android.view.WindowInsetsController import android.graphics.Color import android.webkit.WebView +import android.content.pm.ActivityInfo import android.graphics.fonts.SystemFonts import android.graphics.fonts.Font import androidx.core.view.WindowCompat @@ -56,6 +57,11 @@ class InterceptKeysRequestArgs { var backKey: Boolean? = null } +@InvokeArg +class LockScreenOrientationRequestArgs { + var orientation: String? = null +} + interface KeyDownInterceptor { fun interceptVolumeKeys(enabled: Boolean) fun interceptBackKey(enabled: Boolean) @@ -326,4 +332,20 @@ class NativeBridgePlugin(private val activity: Activity): Plugin(activity) { } invoke.resolve() } + + @Command + fun lock_screen_orientation(invoke: Invoke) { + val args = invoke.parseArgs(LockScreenOrientationRequestArgs::class.java) + val orientation = args.orientation ?: "auto" + when (orientation) { + "portrait" -> activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT + "landscape" -> activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE + "auto" -> activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR + else -> { + invoke.reject("Invalid orientation mode") + return + } + } + invoke.resolve() + } } 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 02502b11..590f0be2 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 @@ -8,6 +8,7 @@ const COMMANDS: &[&str] = &[ "get_status_bar_height", "get_sys_fonts_list", "intercept_keys", + "lock_screen_orientation", ]; fn main() { 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 13a13ea1..5f92c4e4 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 @@ -44,6 +44,10 @@ class InterceptKeysRequestArgs: Decodable { let volumeKeys: Bool? } +class LockScreenOrientationRequestArgs: Decodable { + let orientation: String? +} + class VolumeKeyHandler: NSObject { private var audioSession: AVAudioSession? private var originalVolume: Float = 0.0 @@ -150,6 +154,9 @@ class VolumeKeyHandler: NSObject { class NativeBridgePlugin: Plugin { private var webView: WKWebView? private var authSession: ASWebAuthenticationSession? + private var isOrientationLocked = false + private var currentOrientationMask: UIInterfaceOrientationMask = .all + private var orientationObserver: NSObjectProtocol? @objc public override func load(webview: WKWebView) { self.webView = webview @@ -174,6 +181,10 @@ class NativeBridgePlugin: Plugin { if volumeKeyHandler != nil { activateVolumeKeyInterception() } + + if orientationObserver != nil { + self.setupOrientationObserver() + } } @objc func appDidEnterBackground() { @@ -338,6 +349,75 @@ class NativeBridgePlugin: Plugin { invoke.reject(error.localizedDescription) } } + + @objc public func lock_screen_orientation(_ invoke: Invoke) throws { + guard let args = try? invoke.parseArgs(LockScreenOrientationRequestArgs.self) else { + return invoke.reject("Invalid arguments") + } + + DispatchQueue.main.async { + UIDevice.current.beginGeneratingDeviceOrientationNotifications() + let orientation = args.orientation ?? "auto" + switch orientation.lowercased() { + case "portrait": + self.isOrientationLocked = true + self.currentOrientationMask = .portrait + self.forceOrientation(.portrait) + self.setupOrientationObserver() + case "landscape": + self.isOrientationLocked = true + self.currentOrientationMask = .landscape + self.forceOrientation(.landscapeRight) + self.setupOrientationObserver() + case "auto": + self.isOrientationLocked = false + self.currentOrientationMask = .all + default: + invoke.reject("Invalid orientation mode") + return + } + + invoke.resolve() + } + } + + private func forceOrientation(_ orientation: UIInterfaceOrientation) { + if #available(iOS 16.0, *) { + if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene { + let orientationMask: UIInterfaceOrientationMask = + orientation.isPortrait ? .portrait : .landscape + + for window in windowScene.windows { + if let rootVC = window.rootViewController { + rootVC.setNeedsUpdateOfSupportedInterfaceOrientations() + } + } + + windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: orientationMask)) { error in + print("Orientation update error: \(error.localizedDescription)") + } + } + } else { + UIDevice.current.setValue(orientation.rawValue, forKey: "orientation") + UIViewController.attemptRotationToDeviceOrientation() + } + } + + private func setupOrientationObserver() { + orientationObserver = NotificationCenter.default.addObserver( + forName: UIDevice.orientationDidChangeNotification, + object: nil, + queue: .main + ) { [weak self] _ in + guard let self = self, self.isOrientationLocked else { return } + + if self.currentOrientationMask == .portrait { + self.forceOrientation(.portrait) + } else if self.currentOrientationMask == .landscape { + self.forceOrientation(.landscapeRight) + } + } + } } @_cdecl("init_plugin_native_bridge") diff --git a/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/permissions/autogenerated/commands/lock_screen_orientation.toml b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/permissions/autogenerated/commands/lock_screen_orientation.toml new file mode 100644 index 00000000..ddf675ff --- /dev/null +++ b/apps/readest-app/src-tauri/plugins/tauri-plugin-native-bridge/permissions/autogenerated/commands/lock_screen_orientation.toml @@ -0,0 +1,13 @@ +# Automatically generated - DO NOT EDIT! + +"$schema" = "../../schemas/schema.json" + +[[permission]] +identifier = "allow-lock-screen-orientation" +description = "Enables the lock_screen_orientation command without any pre-configured scope." +commands.allow = ["lock_screen_orientation"] + +[[permission]] +identifier = "deny-lock-screen-orientation" +description = "Denies the lock_screen_orientation command without any pre-configured scope." +commands.deny = ["lock_screen_orientation"] 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 389f441d..1ce8c04b 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 @@ -13,6 +13,7 @@ Default permissions for the plugin - `allow-get-status-bar-height` - `allow-get-sys-fonts-list` - `allow-intercept-keys` +- `allow-lock-screen-orientation` ## Permission Table @@ -208,6 +209,32 @@ Denies the intercept_keys command without any pre-configured scope.