expo-screen-orientation 6.0.3 → 6.0.5

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/CHANGELOG.md CHANGED
@@ -10,6 +10,19 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 6.0.5 — 2023-07-25
14
+
15
+ ### 🐛 Bug fixes
16
+
17
+ - Fix addOrientationChangeListener not working on iPadOS. ([#23656](https://github.com/expo/expo/pull/23656) by [@behenate](https://github.com/behenate))
18
+
19
+ ## 6.0.4 — 2023-07-23
20
+
21
+ ### 🐛 Bug fixes
22
+
23
+ - [iOS] Fix event emitter sending events with no registered listeners. ([#23462](https://github.com/expo/expo/pull/23462) by [@behenate](https://github.com/behenate))
24
+ - [iOS] Fix config plugin deleting the orientations key from `Info.plist` when the initial orientation value is set to `DEFAULT`. ([#23637](https://github.com/expo/expo/pull/23637) by [@behenate](https://github.com/behenate))
25
+
13
26
  ## 6.0.3 — 2023-07-12
14
27
 
15
28
  ### 🐛 Bug fixes
@@ -3,7 +3,7 @@ apply plugin: 'kotlin-android'
3
3
  apply plugin: 'maven-publish'
4
4
 
5
5
  group = 'host.exp.exponent'
6
- version = '6.0.3'
6
+ version = '6.0.5'
7
7
 
8
8
  buildscript {
9
9
  def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
@@ -67,7 +67,7 @@ android {
67
67
  minSdkVersion safeExtGet("minSdkVersion", 21)
68
68
  targetSdkVersion safeExtGet("targetSdkVersion", 33)
69
69
  versionCode 7
70
- versionName '6.0.3'
70
+ versionName '6.0.5'
71
71
  }
72
72
  lintOptions {
73
73
  abortOnError false
@@ -4,7 +4,7 @@ public class ScreenOrientationModule: Module, ScreenOrientationController {
4
4
  static let didUpdateDimensionsEvent = "expoDidUpdateDimensions"
5
5
 
6
6
  let screenOrientationRegistry = ScreenOrientationRegistry.shared
7
- var eventEmitter: EXEventEmitterService?
7
+ var shouldEmitEvents = false
8
8
 
9
9
  public func definition() -> ModuleDefinition {
10
10
  Name("ExpoScreenOrientation")
@@ -82,12 +82,20 @@ public class ScreenOrientationModule: Module, ScreenOrientationController {
82
82
  OnDestroy {
83
83
  screenOrientationRegistry.unregisterController(self)
84
84
  }
85
+
86
+ OnStartObserving {
87
+ shouldEmitEvents = true
88
+ }
89
+
90
+ OnStopObserving {
91
+ shouldEmitEvents = false
92
+ }
85
93
  }
86
94
 
87
95
  // MARK: - ScreenOrientationController
88
96
 
89
97
  public func screenOrientationDidChange(_ orientation: UIInterfaceOrientation) {
90
- guard let currentTraitCollection = screenOrientationRegistry.currentTraitCollection else {
98
+ guard let currentTraitCollection = screenOrientationRegistry.currentTraitCollection, shouldEmitEvents else {
91
99
  return
92
100
  }
93
101
 
@@ -17,6 +17,7 @@ public class ScreenOrientationRegistry: NSObject, UIApplicationDelegate {
17
17
  public var currentScreenOrientation: UIInterfaceOrientation
18
18
  var orientationControllers: [ScreenOrientationController] = []
19
19
  var controllerInterfaceMasks: [ObjectIdentifier: UIInterfaceOrientationMask] = [:]
20
+ @objc
20
21
  public weak var currentTraitCollection: UITraitCollection?
21
22
  var lastOrientationMask: UIInterfaceOrientationMask
22
23
  var rootViewController: UIViewController? {
@@ -45,13 +46,6 @@ public class ScreenOrientationRegistry: NSObject, UIApplicationDelegate {
45
46
 
46
47
  super.init()
47
48
 
48
- NotificationCenter.default.addObserver(
49
- self,
50
- selector: #selector(self.handleDeviceOrientationChange(notification:)),
51
- name: UIDevice.orientationDidChangeNotification,
52
- object: UIDevice.current
53
- )
54
-
55
49
  // This is most likely already executed on the main thread, but we need to be sure
56
50
  RCTExecuteOnMainQueue {
57
51
  UIDevice.current.beginGeneratingDeviceOrientationNotifications()
@@ -79,7 +73,8 @@ public class ScreenOrientationRegistry: NSObject, UIApplicationDelegate {
79
73
  /**
80
74
  Rotates the view to currentScreenOrientation or default orientation from the orientationMask.
81
75
  */
82
- func enforceDesiredDeviceOrientation(withOrientationMask orientationMask: UIInterfaceOrientationMask) {
76
+ @objc
77
+ public func enforceDesiredDeviceOrientation(withOrientationMask orientationMask: UIInterfaceOrientationMask) {
83
78
  var newOrientation = orientationMask.defaultOrientation()
84
79
 
85
80
  if orientationMask.contains(currentScreenOrientation) {
@@ -142,56 +137,19 @@ public class ScreenOrientationRegistry: NSObject, UIApplicationDelegate {
142
137
 
143
138
  // MARK: - Events
144
139
 
145
- /**
146
- Called when the OS sends an OrientationDidChange notification.
147
- */
148
- @objc
149
- func handleDeviceOrientationChange(notification: Notification) {
150
- let newScreenOrientation = UIDevice.current.orientation.toInterfaceOrientation()
151
-
152
- interfaceOrientationDidChange(newScreenOrientation)
153
- }
154
-
155
- /**
156
- Called when the device is physically rotated. Checks if screen orientation should be changed after user rotated the device.
157
- */
158
- func interfaceOrientationDidChange(_ newScreenOrientation: UIInterfaceOrientation) {
159
- if currentScreenOrientation == newScreenOrientation || newScreenOrientation == .unknown {
160
- return
161
- }
162
-
163
- if currentOrientationMask.contains(newScreenOrientation) {
164
- // when changing orientation without changing dimensions traitCollectionDidChange isn't triggered so the event has to be called manually
165
- if (newScreenOrientation.isPortrait && currentScreenOrientation.isPortrait)
166
- || (newScreenOrientation.isLandscape && currentScreenOrientation.isLandscape) {
167
- screenOrientationDidChange(newScreenOrientation)
168
- return
169
- }
170
-
171
- // on iPads, traitCollectionDidChange isn't triggered at all, so we have to call screenOrientationDidChange manually
172
- if isPad()
173
- && (newScreenOrientation.isPortrait && currentScreenOrientation.isLandscape
174
- || newScreenOrientation.isLandscape && currentScreenOrientation.isPortrait) {
175
- screenOrientationDidChange(newScreenOrientation)
176
- }
177
- }
178
- }
179
-
180
140
  /**
181
141
  Called by ScreenOrientationViewController when the dimensions of the view change.
182
142
  Also used for Expo Go in EXAppViewController.
183
143
  */
184
144
  @objc
185
- public func traitCollectionDidChange(to traitCollection: UITraitCollection) {
186
- currentTraitCollection = traitCollection
187
-
145
+ public func viewDidTransition(toOrientation orientation: UIInterfaceOrientation) {
188
146
  let currentDeviceOrientation = UIDevice.current.orientation.toInterfaceOrientation()
189
147
  let currentOrientationMask = self.rootViewController?.supportedInterfaceOrientations ?? []
190
148
 
191
149
  var newScreenOrientation = UIInterfaceOrientation.unknown
192
150
 
193
151
  // We need to deduce what is the new screen orientaiton based on currentOrientationMask and new dimensions of the view
194
- if traitCollection.isPortrait() {
152
+ if orientation.isPortrait {
195
153
  // From trait collection, we know that screen is in portrait or upside down orientation.
196
154
  let portraitMask = currentOrientationMask.intersection([.portrait, .portraitUpsideDown])
197
155
 
@@ -208,7 +166,7 @@ public class ScreenOrientationRegistry: NSObject, UIApplicationDelegate {
208
166
  // from device orientation.
209
167
  newScreenOrientation = currentDeviceOrientation
210
168
  }
211
- } else if traitCollection.isLandscape() {
169
+ } else if orientation.isLandscape {
212
170
  // From trait collection, we know that screen is in landscape left or right orientation.
213
171
  let landscapeMask = currentOrientationMask.intersection(.landscape)
214
172
 
@@ -232,6 +190,11 @@ public class ScreenOrientationRegistry: NSObject, UIApplicationDelegate {
232
190
  screenOrientationDidChange(newScreenOrientation)
233
191
  }
234
192
 
193
+ @objc
194
+ public func traitCollectionDidChange(to traitCollection: UITraitCollection) {
195
+ currentTraitCollection = traitCollection
196
+ }
197
+
235
198
  /**
236
199
  Called at the end of the screen orientation change. Notifies the controllers about the orientation change.
237
200
  */
@@ -7,10 +7,20 @@ let ipadSupportedOrientationsKey = "UISupportedInterfaceOrientations~ipad"
7
7
  class ScreenOrientationViewController: UIViewController {
8
8
  let screenOrientationRegistry = ScreenOrientationRegistry.shared
9
9
  private var defaultOrientationMask: UIInterfaceOrientationMask
10
+ private var previousInterfaceOrientation: UIInterfaceOrientation = .unknown
11
+ private var windowInterfaceOrientation: UIInterfaceOrientation? {
12
+ return UIApplication.shared.windows.first?.windowScene?.interfaceOrientation
13
+ }
10
14
 
11
15
  init(defaultOrientationMask: UIInterfaceOrientationMask = doesDeviceHaveNotch ? .allButUpsideDown : .all) {
12
16
  self.defaultOrientationMask = defaultOrientationMask
13
17
  super.init(nibName: nil, bundle: nil)
18
+
19
+ // For iPads traitCollectionDidChange will not be called (it's always in the same size class). It is necessary
20
+ // to init it in here, so it's possible to return it in the didUpdateDimensionsEvent of the module
21
+ if self.screenOrientationRegistry.currentTraitCollection == nil {
22
+ self.screenOrientationRegistry.traitCollectionDidChange(to: self.traitCollection)
23
+ }
14
24
  }
15
25
 
16
26
  convenience init(defaultScreenOrientationFromPlist: Void) {
@@ -57,11 +67,23 @@ class ScreenOrientationViewController: UIViewController {
57
67
 
58
68
  override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
59
69
  super.traitCollectionDidChange(previousTraitCollection)
70
+ screenOrientationRegistry.traitCollectionDidChange(to: traitCollection)
71
+ }
60
72
 
61
- if traitCollection.verticalSizeClass != previousTraitCollection?.verticalSizeClass ||
62
- traitCollection.horizontalSizeClass != previousTraitCollection?.horizontalSizeClass {
63
- screenOrientationRegistry.traitCollectionDidChange(to: traitCollection)
64
- }
73
+ override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
74
+ super.viewWillTransition(to: size, with: coordinator)
75
+
76
+ // Update after the transition ends, this ensures that the trait collection passed to didUpdateDimensionsEvent is already updated
77
+ coordinator.animate(alongsideTransition: { [weak self] _ in
78
+ guard let self = self, let windowInterfaceOrientation = self.windowInterfaceOrientation else {
79
+ return
80
+ }
81
+
82
+ if windowInterfaceOrientation != self.previousInterfaceOrientation {
83
+ self.screenOrientationRegistry.viewDidTransition(toOrientation: windowInterfaceOrientation)
84
+ }
85
+ self.previousInterfaceOrientation = windowInterfaceOrientation
86
+ })
65
87
  }
66
88
 
67
89
  private func shouldUseRNScreenOrientation() -> Bool {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-screen-orientation",
3
- "version": "6.0.3",
3
+ "version": "6.0.5",
4
4
  "description": "Expo universal module for managing device's screen orientation",
5
5
  "main": "build/ScreenOrientation.js",
6
6
  "types": "build/ScreenOrientation.d.ts",
@@ -41,5 +41,5 @@
41
41
  "peerDependencies": {
42
42
  "expo": "*"
43
43
  },
44
- "gitHead": "8fdc53c90c52242a80ea511ee3073d9ab950bc68"
44
+ "gitHead": "8c85313e05e38401d06dcac1addd8a0659ae37a3"
45
45
  }
@@ -15,7 +15,6 @@ type OrientationMasks = keyof typeof OrientationLock;
15
15
  interface ExpoConfigWithInitialOrientation extends ExpoConfig {
16
16
  initialOrientation?: OrientationMasks;
17
17
  }
18
- export declare function getInitialOrientation(config: Pick<ExpoConfigWithInitialOrientation, 'initialOrientation'>): OrientationMasks;
19
18
  export declare function setInitialOrientation(config: Pick<ExpoConfigWithInitialOrientation, 'initialOrientation'>, infoPlist: InfoPlist): InfoPlist;
20
19
  declare const _default: ConfigPlugin<void | {
21
20
  initialOrientation?: "DEFAULT" | "ALL" | "PORTRAIT" | "PORTRAIT_UP" | "PORTRAIT_DOWN" | "LANDSCAPE" | "LANDSCAPE_LEFT" | "LANDSCAPE_RIGHT" | undefined;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.setInitialOrientation = exports.getInitialOrientation = exports.INITIAL_ORIENTATION_KEY = void 0;
6
+ exports.setInitialOrientation = exports.INITIAL_ORIENTATION_KEY = void 0;
7
7
  const assert_1 = __importDefault(require("assert"));
8
8
  const config_plugins_1 = require("expo/config-plugins");
9
9
  const pkg = require('expo-screen-orientation/package.json');
@@ -19,7 +19,7 @@ const OrientationLock = {
19
19
  LANDSCAPE_LEFT: 'UIInterfaceOrientationMaskLandscapeLeft',
20
20
  LANDSCAPE_RIGHT: 'UIInterfaceOrientationMaskLandscapeRight',
21
21
  };
22
- const withScreenOrientationViewController = (config, { initialOrientation = 'DEFAULT' } = {}) => {
22
+ const withScreenOrientationViewController = (config, { initialOrientation } = {}) => {
23
23
  config = (0, config_plugins_1.withInfoPlist)(config, (config) => {
24
24
  const extendedConfig = {
25
25
  ...config,
@@ -30,19 +30,14 @@ const withScreenOrientationViewController = (config, { initialOrientation = 'DEF
30
30
  });
31
31
  return config;
32
32
  };
33
- function getInitialOrientation(config) {
34
- return config.initialOrientation ?? 'DEFAULT';
35
- }
36
- exports.getInitialOrientation = getInitialOrientation;
37
33
  function setInitialOrientation(config, infoPlist) {
38
- const initialOrientation = getInitialOrientation(config);
39
- (0, assert_1.default)(initialOrientation in OrientationLock, `Invalid initial orientation "${initialOrientation}" expected one of: ${Object.keys(OrientationLock).join(', ')}`);
40
- if (initialOrientation === 'DEFAULT') {
34
+ const initialOrientation = config.initialOrientation;
35
+ if (!initialOrientation) {
41
36
  delete infoPlist[exports.INITIAL_ORIENTATION_KEY];
37
+ return infoPlist;
42
38
  }
43
- else {
44
- infoPlist[exports.INITIAL_ORIENTATION_KEY] = OrientationLock[initialOrientation];
45
- }
39
+ (0, assert_1.default)(initialOrientation in OrientationLock, `Invalid initial orientation "${initialOrientation}" expected one of: ${Object.keys(OrientationLock).join(', ')}`);
40
+ infoPlist[exports.INITIAL_ORIENTATION_KEY] = OrientationLock[initialOrientation];
46
41
  return infoPlist;
47
42
  }
48
43
  exports.setInitialOrientation = setInitialOrientation;
@@ -29,7 +29,7 @@ const withScreenOrientationViewController: ConfigPlugin<
29
29
  {
30
30
  initialOrientation?: keyof typeof OrientationLock;
31
31
  } | void
32
- > = (config, { initialOrientation = 'DEFAULT' } = {}) => {
32
+ > = (config, { initialOrientation } = {}) => {
33
33
  config = withInfoPlist(config, (config) => {
34
34
  const extendedConfig = {
35
35
  ...config,
@@ -41,17 +41,16 @@ const withScreenOrientationViewController: ConfigPlugin<
41
41
  return config;
42
42
  };
43
43
 
44
- export function getInitialOrientation(
45
- config: Pick<ExpoConfigWithInitialOrientation, 'initialOrientation'>
46
- ): OrientationMasks {
47
- return config.initialOrientation ?? 'DEFAULT';
48
- }
49
-
50
44
  export function setInitialOrientation(
51
45
  config: Pick<ExpoConfigWithInitialOrientation, 'initialOrientation'>,
52
46
  infoPlist: InfoPlist
53
47
  ): InfoPlist {
54
- const initialOrientation = getInitialOrientation(config);
48
+ const initialOrientation = config.initialOrientation;
49
+
50
+ if (!initialOrientation) {
51
+ delete infoPlist[INITIAL_ORIENTATION_KEY];
52
+ return infoPlist;
53
+ }
55
54
 
56
55
  assert(
57
56
  initialOrientation in OrientationLock,
@@ -60,11 +59,8 @@ export function setInitialOrientation(
60
59
  ).join(', ')}`
61
60
  );
62
61
 
63
- if (initialOrientation === 'DEFAULT') {
64
- delete infoPlist[INITIAL_ORIENTATION_KEY];
65
- } else {
66
- infoPlist[INITIAL_ORIENTATION_KEY] = OrientationLock[initialOrientation];
67
- }
62
+ infoPlist[INITIAL_ORIENTATION_KEY] = OrientationLock[initialOrientation];
63
+
68
64
  return infoPlist;
69
65
  }
70
66