Skip to content

getOrientationAsync after upgrade to SDK37 does not return a ScreenOrientationInfo object, instead it return orientationId #7706

@kopax

Description

@kopax

I am upgrading from SDK36 to 37 and found this breaking change:

  • Removed Orientation.PORTRAIT and Orientation.LANDSCAPE from ScreenOrientation in favor of their more specific versions. (#6760 by @lukmccall)

I was able to accomplish my upgrade to the end, but I am reporting an issue in the doc since getOrientationAsync does not return a ScreenOrientationInfo object anymore, but instead it return the orientationId.

This error happen on iOS/Android/Web.

I was using them:

import React, { cloneElement } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { compose } from 'redux';
import { createStructuredSelector } from 'reselect';
import {
  addOrientationChangeListener,
  removeOrientationChangeListener,
  getOrientationAsync,
  Orientation,
} from 'expo-screen-orientation';
import omit from 'lodash.omit';

import withDimensions from '../dimensions/withDimensions';
import { orientationChange as orientationChangeAction } from '../reducers/app/layoutReducer/actions';
import { selectOrientation } from '../reducers/app/layoutReducer/selectors';

class ConnectedOrientationProvider extends React.Component {
  constructor(props) {
    super(props);
    this.onOrientationChange = this.onOrientationChange.bind(this);
  }

  // eslint-disable-next-line camelcase
  UNSAFE_componentWillMount() {
    this.subscription = addOrientationChangeListener(this.onOrientationChange);
  }

  async componentDidMount() {
    await this.detectOrientation();
  }

  componentWillUnmount() {
    removeOrientationChangeListener(this.subscription);
  }

  onOrientationChange({ orientationInfo: { orientation } }) {
    this.setOrientation(orientation);
  }

  setOrientation(orientation) {
    const { orientationChange } = this.props;
    orientationChange(this.fixOrientation(orientation));
  }

  fixOrientation(orientation) {
    let newOrientation = orientation;
    /** fix for android having too much orientations */
    newOrientation = newOrientation.split('_')[0]; // eslint-disable-line prefer-destructuring
    /** fix for safari (See https://github.com/expo/expo/issues/6949) */
    if (newOrientation === Orientation.UNKNOWN) {
      const { dimensions: { width, height } } = this.props;
      newOrientation = width > height ? Orientation.LANDSCAPE : Orientation.PORTRAIT;
    }
    return newOrientation;
  }

  async detectOrientation() {
    const { orientation } = await getOrientationAsync();
    this.setOrientation(orientation);
  }

  render() {
    const { children, ...rest } = omit(this.props, ['orientationChange', 'orientation', 'dimensions']);
    return cloneElement(children, rest);
  }
}

ConnectedOrientationProvider.propTypes = {
  orientationChange: PropTypes.func.isRequired,
  dimensions: PropTypes.shape({
    width: PropTypes.number,
    height: PropTypes.number,
  }).isRequired,
};

const mapStateToProps = createStructuredSelector({
  orientation: selectOrientation,
});

const mapDispatchToProps = (dispatch) => ({
  orientationChange: (orientation) => dispatch(orientationChangeAction(orientation)),
});


export default compose(
  withDimensions,
  connect(mapStateToProps, mapDispatchToProps),
)(ConnectedOrientationProvider);

Now the detectOrientation always return undefined on the web.

I have fixed it with:

const orientationId = await getOrientationAsync();

This will return 3 (while I was expecting to have a ScreenOrientationInfo object as described in the doc here : https://docs.expo.io/versions/latest/sdk/screen-orientation/#screenorientationscreenorientationinfo)

I am able to fix my class with Orientation[orientationId]

Related

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions