Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CHORE] Create DimensionsContext #2098

Merged
18 changes: 7 additions & 11 deletions app/containers/ActionSheet/ActionSheet.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@ import Animated, {
Easing
} from 'react-native-reanimated';
import * as Haptics from 'expo-haptics';
import {
useDimensions,
useBackHandler,
useDeviceOrientation
} from '@react-native-community/hooks';
import { useBackHandler } from '@react-native-community/hooks';

import { Item } from './Item';
import { Handle } from './Handle';
Expand All @@ -33,6 +29,7 @@ import styles, { ITEM_HEIGHT } from './styles';
import { isTablet, isIOS } from '../../utils/deviceInfo';
import Separator from '../Separator';
import I18n from '../../i18n';
import { useOrientation, useDimensions } from '../../dimensions';

const getItemLayout = (data, index) => ({ length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index });

Expand All @@ -52,10 +49,9 @@ const ActionSheet = React.memo(forwardRef(({ children, theme }, ref) => {
const bottomSheetRef = useRef();
const [data, setData] = useState({});
const [isVisible, setVisible] = useState(false);
const orientation = useDeviceOrientation();
const { height } = useDimensions().window;
const { height } = useDimensions();
const { isLandscape } = useOrientation();
const insets = useSafeAreaInsets();
const { landscape } = orientation;

const maxSnap = Math.max(
(
Expand All @@ -81,7 +77,7 @@ const ActionSheet = React.memo(forwardRef(({ children, theme }, ref) => {
* we'll provide more one snap
* that point 50% of the whole screen
*/
const snaps = (height - maxSnap > height * 0.6) && !landscape ? [maxSnap, height * 0.5, height] : [maxSnap, height];
const snaps = (height - maxSnap > height * 0.6) && !isLandscape ? [maxSnap, height * 0.5, height] : [maxSnap, height];
const openedSnapIndex = snaps.length > 2 ? 1 : 0;
const closedSnapIndex = snaps.length - 1;

Expand Down Expand Up @@ -120,7 +116,7 @@ const ActionSheet = React.memo(forwardRef(({ children, theme }, ref) => {
// Hides action sheet when orientation changes
useEffect(() => {
setVisible(false);
}, [orientation.landscape]);
}, [isLandscape]);

useImperativeHandle(ref, () => ({
showActionSheet: show,
Expand Down Expand Up @@ -186,7 +182,7 @@ const ActionSheet = React.memo(forwardRef(({ children, theme }, ref) => {
containerStyle={[
styles.container,
{ backgroundColor: themes[theme].focusedBackground },
(landscape || isTablet) && styles.bottomSheet
(isLandscape || isTablet) && styles.bottomSheet
]}
animationConfig={ANIMATION_CONFIG}
// FlatList props
Expand Down
4 changes: 1 addition & 3 deletions app/containers/EmojiPicker/EmojiCategory.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Text, TouchableOpacity, FlatList } from 'react-native';
import { responsive } from 'react-native-responsive-ui';

import shortnameToUnicode from '../../utils/shortnameToUnicode';
import styles from './styles';
Expand All @@ -25,7 +24,6 @@ class EmojiCategory extends React.Component {
static propTypes = {
baseUrl: PropTypes.string.isRequired,
emojis: PropTypes.any,
window: PropTypes.any,
onEmojiSelected: PropTypes.func,
emojisPerRow: PropTypes.number,
width: PropTypes.number
Expand Down Expand Up @@ -73,4 +71,4 @@ class EmojiCategory extends React.Component {
}
}

export default responsive(EmojiCategory);
export default EmojiCategory;
6 changes: 3 additions & 3 deletions app/containers/InAppNotification/NotifierComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import Touchable from 'react-native-platform-touchable';
import { connect } from 'react-redux';
import { Notifier } from 'react-native-notifier';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useDeviceOrientation } from '@react-native-community/hooks';

import Avatar from '../Avatar';
import { CustomIcon } from '../../lib/Icons';
Expand All @@ -16,6 +15,7 @@ import { getUserSelector } from '../../selectors/login';
import { ROW_HEIGHT } from '../../presentation/RoomItem';
import { goRoom } from '../../utils/goRoom';
import Navigation from '../../lib/Navigation';
import { useOrientation } from '../../dimensions';

const AVATAR_SIZE = 48;
const BUTTON_HIT_SLOP = {
Expand Down Expand Up @@ -70,7 +70,7 @@ const NotifierComponent = React.memo(({
}) => {
const { theme } = useTheme();
const insets = useSafeAreaInsets();
const { landscape } = useDeviceOrientation();
const { isLandscape } = useOrientation();

const { id: userId, token } = user;
const { text, payload } = notification;
Expand Down Expand Up @@ -98,7 +98,7 @@ const NotifierComponent = React.memo(({
return (
<View style={[
styles.container,
(isMasterDetail || landscape) && styles.small,
(isMasterDetail || isLandscape) && styles.small,
{
backgroundColor: themes[theme].focusedBackground,
borderColor: themes[theme].separatorColor,
Expand Down
5 changes: 3 additions & 2 deletions app/containers/MessageActions/Header.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect, useState, useCallback } from 'react';
import PropTypes from 'prop-types';
import {
View, Text, FlatList, StyleSheet, Dimensions
View, Text, FlatList, StyleSheet
} from 'react-native';

import { withTheme } from '../../theme';
Expand All @@ -11,6 +11,7 @@ import shortnameToUnicode from '../../utils/shortnameToUnicode';
import CustomEmoji from '../EmojiPicker/CustomEmoji';
import database from '../../lib/database';
import { Button } from '../ActionSheet';
import { useDimensions } from '../../dimensions';

export const HEADER_HEIGHT = 36;

Expand Down Expand Up @@ -86,14 +87,14 @@ const Header = React.memo(({
handleReaction, server, message, theme
}) => {
const [items, setItems] = useState([]);
const { width, height } = useDimensions();

const setEmojis = async() => {
try {
const db = database.active;
const freqEmojiCollection = db.collections.get('frequently_used_emojis');
let freqEmojis = await freqEmojiCollection.query().fetch();

const { width, height } = Dimensions.get('window');
const isLandscape = width > height;
const size = isLandscape ? width / 2 : width;
const quantity = (size / 50) - 1;
Expand Down
12 changes: 6 additions & 6 deletions app/containers/MessageBox/UploadModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
} from 'react-native';
import PropTypes from 'prop-types';
import Modal from 'react-native-modal';
import { responsive } from 'react-native-responsive-ui';
import equal from 'deep-equal';

import TextInput from '../TextInput';
Expand All @@ -15,6 +14,7 @@ import { isIOS } from '../../utils/deviceInfo';
import { themes } from '../../constants/colors';
import { CustomIcon } from '../../lib/Icons';
import { withTheme } from '../../theme';
import { withDimensions } from '../../dimensions';

const styles = StyleSheet.create({
modal: {
Expand Down Expand Up @@ -88,7 +88,7 @@ class UploadModal extends Component {
file: PropTypes.object,
close: PropTypes.func,
submit: PropTypes.func,
window: PropTypes.object,
width: PropTypes.number,
theme: PropTypes.string,
isMasterDetail: PropTypes.bool
}
Expand All @@ -112,7 +112,7 @@ class UploadModal extends Component {

shouldComponentUpdate(nextProps, nextState) {
const { name, description, file } = this.state;
const { window, isVisible, theme } = this.props;
const { width, isVisible, theme } = this.props;

if (nextState.name !== name) {
return true;
Expand All @@ -126,7 +126,7 @@ class UploadModal extends Component {
if (nextProps.isVisible !== isVisible) {
return true;
}
if (nextProps.window.width !== window.width) {
if (nextProps.width !== width) {
return true;
}
if (!equal(nextState.file, file)) {
Expand Down Expand Up @@ -204,7 +204,7 @@ class UploadModal extends Component {

render() {
const {
window: { width }, isVisible, close, isMasterDetail, theme
width, isVisible, close, isMasterDetail, theme
} = this.props;
const { name, description } = this.state;
return (
Expand Down Expand Up @@ -246,4 +246,4 @@ class UploadModal extends Component {
}
}

export default responsive(withTheme(UploadModal));
export default withDimensions(withTheme(UploadModal));
14 changes: 9 additions & 5 deletions app/containers/message/Audio.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import {
View, StyleSheet, Text, Easing, Dimensions
View, StyleSheet, Text, Easing
} from 'react-native';
import { Audio } from 'expo-av';
import Slider from '@react-native-community/slider';
Expand All @@ -17,6 +17,7 @@ import { themes } from '../../constants/colors';
import { isAndroid, isIOS } from '../../utils/deviceInfo';
import MessageContext from './Context';
import ActivityIndicator from '../ActivityIndicator';
import { withDimensions } from '../../dimensions';

const mode = {
allowsRecordingIOS: false,
Expand Down Expand Up @@ -97,7 +98,8 @@ class MessageAudio extends React.Component {
static propTypes = {
file: PropTypes.object.isRequired,
theme: PropTypes.string,
getCustomEmoji: PropTypes.func
getCustomEmoji: PropTypes.func,
scale: PropTypes.number
}

constructor(props) {
Expand Down Expand Up @@ -243,7 +245,9 @@ class MessageAudio extends React.Component {
const {
loading, paused, currentTime, duration
} = this.state;
const { file, getCustomEmoji, theme } = this.props;
const {
file, getCustomEmoji, theme, scale
} = this.props;
const { description } = file;
const { baseUrl, user } = this.context;

Expand Down Expand Up @@ -271,7 +275,7 @@ class MessageAudio extends React.Component {
minimumTrackTintColor={themes[theme].tintColor}
maximumTrackTintColor={themes[theme].auxiliaryText}
onValueChange={this.onValueChange}
thumbImage={isIOS && { uri: 'audio_thumb', scale: Dimensions.get('window').scale }}
thumbImage={isIOS && { uri: 'audio_thumb', scale }}
/>
<Text style={[styles.duration, { color: themes[theme].auxiliaryText }]}>{this.duration}</Text>
</View>
Expand All @@ -281,4 +285,4 @@ class MessageAudio extends React.Component {
}
}

export default MessageAudio;
export default withDimensions(MessageAudio);
26 changes: 26 additions & 0 deletions app/dimensions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import { Dimensions } from 'react-native';
import hoistNonReactStatics from 'hoist-non-react-statics';

export const DimensionsContext = React.createContext(Dimensions.get('window'));

export function withDimensions(Component) {
const DimensionsComponent = props => (
<DimensionsContext.Consumer>
{contexts => <Component {...props} {...contexts} />}
</DimensionsContext.Consumer>
);
hoistNonReactStatics(DimensionsComponent, Component);
return DimensionsComponent;
}

export const useDimensions = () => React.useContext(DimensionsContext);

export const useOrientation = () => {
const { width, height } = React.useContext(DimensionsContext);
const isPortrait = height > width;
return {
isPortrait,
isLandscape: !isPortrait
};
};
49 changes: 36 additions & 13 deletions app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { initializePushNotifications, onNotification } from './notifications/pus
import store from './lib/createStore';
import { loggerConfig, analytics } from './utils/log';
import { ThemeContext } from './theme';
import { DimensionsContext } from './dimensions';
import RocketChat, { THEME_PREFERENCES_KEY } from './lib/rocketchat';
import { MIN_WIDTH_MASTER_DETAIL_LAYOUT } from './constants/tablet';
import {
Expand All @@ -34,6 +35,7 @@ import ChangePasscodeView from './views/ChangePasscodeView';
import Toast from './containers/Toast';
import InAppNotification from './containers/InAppNotification';
import { ActionSheetProvider } from './containers/ActionSheet';
import debounce from './utils/debounce';


RNScreens.enableScreens();
Expand All @@ -57,12 +59,16 @@ export default class Root extends React.Component {
super(props);
this.init();
this.initCrashReport();
const { width, height, scale } = Dimensions.get('window');
this.state = {
theme: defaultTheme(),
themePreferences: {
currentTheme: supportSystemTheme() ? 'automatic' : 'light',
darkLevel: 'dark'
}
},
width,
height,
scale
};
if (isTablet) {
this.initTablet();
Expand Down Expand Up @@ -118,9 +124,11 @@ export default class Root extends React.Component {
store.dispatch(setMasterDetailAction(isMasterDetail));
};

onDimensionsChange = ({ window: { width } }) => {
// Dimensions update fires twice
onDimensionsChange = debounce(({ window: { width, height, scale } }) => {
this.setDimensions({ width, height, scale });
this.setMasterDetail(width);
}
})

setTheme = (newTheme = {}) => {
// change theme state
Expand All @@ -131,8 +139,12 @@ export default class Root extends React.Component {
});
}

setDimensions = ({ width, height, scale }) => {
this.setState({ width, height, scale });
}

initTablet = () => {
const { width } = Dimensions.get('window');
const { width } = this.state;
this.setMasterDetail(width);
this.onKeyCommands = KeyCommandsEmitter.addListener(
'onKeyCommand',
Expand All @@ -154,7 +166,9 @@ export default class Root extends React.Component {
}

render() {
const { themePreferences, theme } = this.state;
const {
themePreferences, theme, width, height, scale
} = this.state;
return (
<SafeAreaProvider initialMetrics={initialWindowMetrics}>
<AppearanceProvider>
Expand All @@ -166,14 +180,23 @@ export default class Root extends React.Component {
setTheme: this.setTheme
}}
>
<ActionSheetProvider>
<AppContainer />
<TwoFactor />
<ScreenLockedView />
<ChangePasscodeView />
<InAppNotification />
<Toast />
</ActionSheetProvider>
<DimensionsContext.Provider
value={{
width,
height,
scale,
setDimensions: this.setDimensions
}}
>
<ActionSheetProvider>
<AppContainer />
<TwoFactor />
<ScreenLockedView />
<ChangePasscodeView />
<InAppNotification />
<Toast />
</ActionSheetProvider>
</DimensionsContext.Provider>
</ThemeContext.Provider>
</Provider>
</AppearanceProvider>
Expand Down
Loading