@capgo/capacitor-screen-orientation 8.1.17 → 8.1.19

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.
package/README.md CHANGED
@@ -69,6 +69,16 @@ To detect physical device orientation using motion sensors on iOS, you need to a
69
69
  <string>This app uses motion sensors to detect the true physical orientation of your device.</string>
70
70
  ```
71
71
 
72
+ Locking the screen orientation only applies to the Capacitor view controller by default. To also apply the lock to presented view controllers (for example, ones shown by the Browser plugin), add this to your app's `AppDelegate.swift`:
73
+
74
+ ```swift
75
+ func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
76
+ return UIInterfaceOrientationMask(rawValue: (self.window!.rootViewController as! CAPBridgeViewController).supportedInterfaceOrientations.rawValue)
77
+ }
78
+ ```
79
+
80
+ Make sure `UISupportedInterfaceOrientations` in `Info.plist` includes every orientation you want to lock to (for example landscape left/right when locking to `landscape`).
81
+
72
82
  ## Usage
73
83
 
74
84
  ```typescript
@@ -17,7 +17,7 @@ import com.getcapacitor.annotation.CapacitorPlugin;
17
17
  @CapacitorPlugin(name = "CapacitorScreenOrientation")
18
18
  public class CapacitorScreenOrientationPlugin extends Plugin implements SensorEventListener {
19
19
 
20
- private final String pluginVersion = "8.1.17";
20
+ private final String pluginVersion = "8.1.19";
21
21
  private int currentOrientation;
22
22
  private SensorManager sensorManager;
23
23
  private Sensor accelerometer;
@@ -11,7 +11,7 @@ import UIKit
11
11
  */
12
12
  @objc(CapacitorScreenOrientationPlugin)
13
13
  public class CapacitorScreenOrientationPlugin: CAPPlugin, CAPBridgedPlugin {
14
- private let pluginVersion: String = "8.1.17"
14
+ private let pluginVersion: String = "8.1.19"
15
15
  public let identifier = "CapacitorScreenOrientationPlugin"
16
16
  public let jsName = "CapacitorScreenOrientation"
17
17
  public let pluginMethods: [CAPPluginMethod] = [
@@ -28,6 +28,8 @@ public class CapacitorScreenOrientationPlugin: CAPPlugin, CAPBridgedPlugin {
28
28
  private var currentDeviceOrientation: UIDeviceOrientation = .portrait
29
29
  private var isTrackingWithMotion = false
30
30
  private var lastNotifiedOrientation: String?
31
+ private var capViewController: CAPBridgeViewController?
32
+ private var defaultSupportedOrientations: [Int] = []
31
33
 
32
34
  override public func load() {
33
35
  // Listen for device orientation changes from system
@@ -40,6 +42,11 @@ public class CapacitorScreenOrientationPlugin: CAPPlugin, CAPBridgedPlugin {
40
42
 
41
43
  // Start monitoring device orientation
42
44
  UIDevice.current.beginGeneratingDeviceOrientationNotifications()
45
+
46
+ if let viewController = self.bridge?.viewController as? CAPBridgeViewController {
47
+ self.capViewController = viewController
48
+ self.defaultSupportedOrientations = viewController.supportedOrientations
49
+ }
43
50
  }
44
51
 
45
52
  deinit {
@@ -70,18 +77,43 @@ public class CapacitorScreenOrientationPlugin: CAPPlugin, CAPBridgedPlugin {
70
77
  return
71
78
  }
72
79
 
80
+ guard let mask = getOrientationMask(from: orientationString) else {
81
+ call.reject("Invalid orientation value: \(orientationString)")
82
+ return
83
+ }
84
+
73
85
  let bypassLock = call.getBool("bypassOrientationLock") ?? false
74
86
 
75
87
  DispatchQueue.main.async {
76
- // Lock the orientation at the app level
77
- if let mask = self.getOrientationMask(from: orientationString) {
78
- // Note: Actual implementation would need to communicate with AppDelegate
79
- // to set the supported interface orientations
80
- // For now, we'll just track the preference
81
- print("Locking orientation to: \(orientationString)")
88
+ if self.capViewController == nil,
89
+ let viewController = self.bridge?.viewController as? CAPBridgeViewController {
90
+ self.capViewController = viewController
91
+ if self.defaultSupportedOrientations.isEmpty {
92
+ self.defaultSupportedOrientations = viewController.supportedOrientations
93
+ }
94
+ }
95
+
96
+ self.capViewController?.supportedOrientations = self.orientationValues(from: mask)
97
+
98
+ if #available(iOS 16.0, *) {
99
+ guard let windowScene = self.currentWindowScene() else {
100
+ call.reject("No window scene available to lock orientation")
101
+ return
102
+ }
103
+
104
+ windowScene.keyWindow?.rootViewController?.setNeedsUpdateOfSupportedInterfaceOrientations()
105
+ self.capViewController?.setNeedsUpdateOfSupportedInterfaceOrientations()
106
+ windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: mask)) { error in
107
+ // Geometry update can fail when the requested orientation is already active
108
+ // or temporarily unavailable; the supportedOrientations mask still applies.
109
+ print("Screen orientation geometry update warning: \(error.localizedDescription)")
110
+ }
111
+ } else {
112
+ let orientationValue = self.preferredInterfaceOrientationValue(from: orientationString)
113
+ UIDevice.current.setValue(orientationValue, forKey: "orientation")
114
+ UINavigationController.attemptRotationToDeviceOrientation()
82
115
  }
83
116
 
84
- // Start motion tracking if bypass is requested
85
117
  if bypassLock {
86
118
  self.startMotionTracking()
87
119
  }
@@ -92,11 +124,35 @@ public class CapacitorScreenOrientationPlugin: CAPPlugin, CAPBridgedPlugin {
92
124
 
93
125
  @objc func unlock(_ call: CAPPluginCall) {
94
126
  DispatchQueue.main.async {
95
- // Stop motion tracking
96
127
  self.stopMotionTracking()
97
128
 
98
- // Unlock orientation at app level
99
- print("Unlocking orientation")
129
+ if self.capViewController == nil,
130
+ let viewController = self.bridge?.viewController as? CAPBridgeViewController {
131
+ self.capViewController = viewController
132
+ if self.defaultSupportedOrientations.isEmpty {
133
+ self.defaultSupportedOrientations = viewController.supportedOrientations
134
+ }
135
+ }
136
+
137
+ let restoredOrientations = self.defaultSupportedOrientations.isEmpty
138
+ ? self.orientationValues(from: .all)
139
+ : self.defaultSupportedOrientations
140
+ self.capViewController?.supportedOrientations = restoredOrientations
141
+
142
+ if #available(iOS 16.0, *) {
143
+ guard let windowScene = self.currentWindowScene() else {
144
+ call.reject("No window scene available to unlock orientation")
145
+ return
146
+ }
147
+
148
+ windowScene.keyWindow?.rootViewController?.setNeedsUpdateOfSupportedInterfaceOrientations()
149
+ self.capViewController?.setNeedsUpdateOfSupportedInterfaceOrientations()
150
+ windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: .all)) { error in
151
+ print("Screen orientation unlock geometry update warning: \(error.localizedDescription)")
152
+ }
153
+ } else {
154
+ UINavigationController.attemptRotationToDeviceOrientation()
155
+ }
100
156
 
101
157
  call.resolve()
102
158
  }
@@ -204,8 +260,19 @@ public class CapacitorScreenOrientationPlugin: CAPPlugin, CAPBridgedPlugin {
204
260
 
205
261
  // MARK: - Helper Methods
206
262
 
263
+ private func currentWindowScene() -> UIWindowScene? {
264
+ if let scene = self.capViewController?.view.window?.windowScene {
265
+ return scene
266
+ }
267
+
268
+ return UIApplication.shared.connectedScenes
269
+ .compactMap { $0 as? UIWindowScene }
270
+ .first { $0.activationState == .foregroundActive }
271
+ ?? UIApplication.shared.connectedScenes.first as? UIWindowScene
272
+ }
273
+
207
274
  private func getCurrentOrientationType() -> String {
208
- let interfaceOrientation = UIApplication.shared.windows.first?.windowScene?.interfaceOrientation ?? .portrait
275
+ let interfaceOrientation = currentWindowScene()?.interfaceOrientation ?? .portrait
209
276
  return mapInterfaceOrientationToString(interfaceOrientation)
210
277
  }
211
278
 
@@ -269,6 +336,40 @@ public class CapacitorScreenOrientationPlugin: CAPPlugin, CAPBridgedPlugin {
269
336
  return nil
270
337
  }
271
338
  }
339
+
340
+ private func preferredInterfaceOrientationValue(from orientationString: String) -> Int {
341
+ switch orientationString {
342
+ case "any":
343
+ return UIInterfaceOrientation.unknown.rawValue
344
+ case "landscape", "landscape-primary":
345
+ return UIInterfaceOrientation.landscapeLeft.rawValue
346
+ case "landscape-secondary":
347
+ return UIInterfaceOrientation.landscapeRight.rawValue
348
+ case "portrait-secondary":
349
+ return UIInterfaceOrientation.portraitUpsideDown.rawValue
350
+ default:
351
+ return UIInterfaceOrientation.portrait.rawValue
352
+ }
353
+ }
354
+
355
+ private func orientationValues(from mask: UIInterfaceOrientationMask) -> [Int] {
356
+ var values: [Int] = []
357
+
358
+ if mask.contains(.portrait) {
359
+ values.append(UIInterfaceOrientation.portrait.rawValue)
360
+ }
361
+ if mask.contains(.portraitUpsideDown) {
362
+ values.append(UIInterfaceOrientation.portraitUpsideDown.rawValue)
363
+ }
364
+ if mask.contains(.landscapeLeft) {
365
+ values.append(UIInterfaceOrientation.landscapeLeft.rawValue)
366
+ }
367
+ if mask.contains(.landscapeRight) {
368
+ values.append(UIInterfaceOrientation.landscapeRight.rawValue)
369
+ }
370
+
371
+ return values
372
+ }
272
373
  }
273
374
 
274
375
  // Helper extension
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/capacitor-screen-orientation",
3
- "version": "8.1.17",
3
+ "version": "8.1.19",
4
4
  "description": "Screen orientation plugin with support for bypassing orientation lock",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",
@@ -56,7 +56,7 @@
56
56
  "check:wiring": "node scripts/check-capacitor-plugin-wiring.mjs",
57
57
  "example:install": "cd example-app && bun install --frozen-lockfile",
58
58
  "example:build": "bun run build && cd example-app && bun install --frozen-lockfile && bun run build",
59
- "example:capgo:deploy": "bun run example:build && bun scripts/deploy-example-capgo.mjs"
59
+ "changelog:ai": "node scripts/generate-ai-changelog.mjs"
60
60
  },
61
61
  "devDependencies": {
62
62
  "@capacitor/android": "^8.0.0",