[CHORE] Create DimensionsContext (#2098)
Signed-off-by: Ezequiel De Oliveira <ezequiel1de1oliveira@gmail.com> Co-authored-by: Diego Mello <diegolmello@gmail.com>
This commit is contained in:
parent
2632ef50f5
commit
36b37eb747
|
@ -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';
|
||||
|
@ -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 });
|
||||
|
||||
|
@ -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(
|
||||
(
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
|
|
@ -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';
|
||||
|
@ -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
|
||||
|
@ -73,4 +71,4 @@ class EmojiCategory extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
export default responsive(EmojiCategory);
|
||||
export default EmojiCategory;
|
||||
|
|
|
@ -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';
|
||||
|
@ -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 = {
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
|
|
@ -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';
|
||||
|
@ -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;
|
||||
|
||||
|
@ -86,6 +87,7 @@ const Header = React.memo(({
|
|||
handleReaction, server, message, theme
|
||||
}) => {
|
||||
const [items, setItems] = useState([]);
|
||||
const { width, height } = useDimensions();
|
||||
|
||||
const setEmojis = async() => {
|
||||
try {
|
||||
|
@ -93,7 +95,6 @@ const Header = React.memo(({
|
|||
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;
|
||||
|
|
|
@ -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';
|
||||
|
@ -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: {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)) {
|
||||
|
@ -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 (
|
||||
|
@ -246,4 +246,4 @@ class UploadModal extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
export default responsive(withTheme(UploadModal));
|
||||
export default withDimensions(withTheme(UploadModal));
|
||||
|
|
|
@ -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';
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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>
|
||||
|
@ -281,4 +285,4 @@ class MessageAudio extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
export default MessageAudio;
|
||||
export default withDimensions(MessageAudio);
|
||||
|
|
|
@ -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
app/index.js
49
app/index.js
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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',
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, { Component } from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
|
@ -8,7 +8,7 @@ import {
|
|||
} from 'react-native-gesture-handler';
|
||||
import FastImage from 'react-native-fast-image';
|
||||
import Animated, { Easing } from 'react-native-reanimated';
|
||||
import { ResponsiveComponent } from 'react-native-responsive-ui';
|
||||
import { withDimensions } from '../../dimensions';
|
||||
|
||||
const AnimatedFastImage = Animated.createAnimatedComponent(FastImage);
|
||||
|
||||
|
@ -264,13 +264,10 @@ const HEIGHT = 300;
|
|||
|
||||
// it was picked from https://github.com/software-mansion/react-native-reanimated/tree/master/Example/imageViewer
|
||||
// and changed to use FastImage animated component
|
||||
class ImageViewer extends ResponsiveComponent {
|
||||
pinchRef = React.createRef();
|
||||
|
||||
panRef = React.createRef();
|
||||
|
||||
class ImageViewer extends Component {
|
||||
static propTypes = {
|
||||
uri: PropTypes.string
|
||||
uri: PropTypes.string,
|
||||
width: PropTypes.number
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
|
@ -382,9 +379,12 @@ class ImageViewer extends ResponsiveComponent {
|
|||
);
|
||||
}
|
||||
|
||||
pinchRef = React.createRef();
|
||||
|
||||
panRef = React.createRef();
|
||||
|
||||
render() {
|
||||
const { uri, ...props } = this.props;
|
||||
const { width } = this.state.window;
|
||||
const { uri, width, ...props } = this.props;
|
||||
|
||||
// The below two animated values makes it so that scale appears to be done
|
||||
// from the top left corner of the image view instead of its center. This
|
||||
|
@ -439,4 +439,4 @@ class ImageViewer extends ResponsiveComponent {
|
|||
}
|
||||
}
|
||||
|
||||
export default ImageViewer;
|
||||
export default withDimensions(ImageViewer);
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { responsive } from 'react-native-responsive-ui';
|
||||
import equal from 'deep-equal';
|
||||
|
||||
import Header from './Header';
|
||||
import RightButtons from './RightButtons';
|
||||
import { withTheme } from '../../../theme';
|
||||
import RoomHeaderLeft from './RoomHeaderLeft';
|
||||
import { withDimensions } from '../../../dimensions';
|
||||
|
||||
class RoomHeaderView extends Component {
|
||||
static propTypes = {
|
||||
|
@ -17,19 +17,20 @@ class RoomHeaderView extends Component {
|
|||
prid: PropTypes.string,
|
||||
tmid: PropTypes.string,
|
||||
usersTyping: PropTypes.string,
|
||||
window: PropTypes.object,
|
||||
status: PropTypes.string,
|
||||
statusText: PropTypes.string,
|
||||
connecting: PropTypes.bool,
|
||||
theme: PropTypes.string,
|
||||
roomUserId: PropTypes.string,
|
||||
widthOffset: PropTypes.number,
|
||||
goRoomActionsView: PropTypes.func
|
||||
goRoomActionsView: PropTypes.func,
|
||||
width: PropTypes.number,
|
||||
height: PropTypes.number
|
||||
};
|
||||
|
||||
shouldComponentUpdate(nextProps) {
|
||||
const {
|
||||
type, title, subtitle, status, statusText, window, connecting, goRoomActionsView, usersTyping, theme
|
||||
type, title, subtitle, status, statusText, connecting, goRoomActionsView, usersTyping, theme, width, height
|
||||
} = this.props;
|
||||
if (nextProps.theme !== theme) {
|
||||
return true;
|
||||
|
@ -52,10 +53,10 @@ class RoomHeaderView extends Component {
|
|||
if (nextProps.connecting !== connecting) {
|
||||
return true;
|
||||
}
|
||||
if (nextProps.window.width !== window.width) {
|
||||
if (nextProps.width !== width) {
|
||||
return true;
|
||||
}
|
||||
if (nextProps.window.height !== window.height) {
|
||||
if (nextProps.height !== height) {
|
||||
return true;
|
||||
}
|
||||
if (!equal(nextProps.usersTyping, usersTyping)) {
|
||||
|
@ -64,12 +65,18 @@ class RoomHeaderView extends Component {
|
|||
if (nextProps.goRoomActionsView !== goRoomActionsView) {
|
||||
return true;
|
||||
}
|
||||
if (nextProps.width !== width) {
|
||||
return true;
|
||||
}
|
||||
if (nextProps.height !== height) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
window, title, subtitle, type, prid, tmid, widthOffset, status = 'offline', statusText, connecting, usersTyping, goRoomActionsView, roomUserId, theme
|
||||
title, subtitle, type, prid, tmid, widthOffset, status = 'offline', statusText, connecting, usersTyping, goRoomActionsView, roomUserId, theme, width, height
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
|
@ -80,8 +87,8 @@ class RoomHeaderView extends Component {
|
|||
subtitle={type === 'd' ? statusText : subtitle}
|
||||
type={type}
|
||||
status={status}
|
||||
width={window.width}
|
||||
height={window.height}
|
||||
width={width}
|
||||
height={height}
|
||||
theme={theme}
|
||||
usersTyping={usersTyping}
|
||||
widthOffset={widthOffset}
|
||||
|
@ -114,6 +121,6 @@ const mapStateToProps = (state, ownProps) => {
|
|||
};
|
||||
};
|
||||
|
||||
export default responsive(connect(mapStateToProps)(withTheme(RoomHeaderView)));
|
||||
export default connect(mapStateToProps)(withDimensions(withTheme(RoomHeaderView)));
|
||||
|
||||
export { RightButtons, RoomHeaderLeft };
|
||||
|
|
|
@ -3,7 +3,6 @@ import PropTypes from 'prop-types';
|
|||
import { View } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import Modal from 'react-native-modal';
|
||||
import { responsive } from 'react-native-responsive-ui';
|
||||
|
||||
import EmojiPicker from '../../containers/EmojiPicker';
|
||||
import styles from './styles';
|
||||
|
@ -15,17 +14,18 @@ const maxSize = 400;
|
|||
class ReactionPicker extends React.Component {
|
||||
static propTypes = {
|
||||
baseUrl: PropTypes.string.isRequired,
|
||||
window: PropTypes.any,
|
||||
message: PropTypes.object,
|
||||
show: PropTypes.bool,
|
||||
isMasterDetail: PropTypes.bool,
|
||||
reactionClose: PropTypes.func,
|
||||
onEmojiSelected: PropTypes.func
|
||||
onEmojiSelected: PropTypes.func,
|
||||
width: PropTypes.number,
|
||||
height: PropTypes.number
|
||||
};
|
||||
|
||||
shouldComponentUpdate(nextProps) {
|
||||
const { show, window } = this.props;
|
||||
return nextProps.show !== show || window.width !== nextProps.window.width;
|
||||
const { show, width, height } = this.props;
|
||||
return nextProps.show !== show || width !== nextProps.width || height !== nextProps.height;
|
||||
}
|
||||
|
||||
onEmojiSelected = (emoji, shortname) => {
|
||||
|
@ -38,7 +38,7 @@ class ReactionPicker extends React.Component {
|
|||
|
||||
render() {
|
||||
const {
|
||||
window: { width, height }, show, baseUrl, reactionClose, isMasterDetail
|
||||
width, height, show, baseUrl, reactionClose, isMasterDetail
|
||||
} = this.props;
|
||||
|
||||
let widthStyle = width - margin;
|
||||
|
@ -87,4 +87,4 @@ const mapStateToProps = state => ({
|
|||
isMasterDetail: state.app.isMasterDetail
|
||||
});
|
||||
|
||||
export default responsive(connect(mapStateToProps)(ReactionPicker));
|
||||
export default connect(mapStateToProps)(ReactionPicker);
|
||||
|
|
|
@ -3,7 +3,6 @@ import {
|
|||
View, Text, StyleSheet, TouchableOpacity, ScrollView
|
||||
} from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import { responsive } from 'react-native-responsive-ui';
|
||||
import { Q } from '@nozbe/watermelondb';
|
||||
|
||||
import database from '../../lib/database';
|
||||
|
@ -56,7 +55,7 @@ const styles = StyleSheet.create({
|
|||
|
||||
class UploadProgress extends Component {
|
||||
static propTypes = {
|
||||
window: PropTypes.object,
|
||||
width: PropTypes.number,
|
||||
rid: PropTypes.string,
|
||||
theme: PropTypes.string,
|
||||
user: PropTypes.shape({
|
||||
|
@ -167,7 +166,7 @@ class UploadProgress extends Component {
|
|||
}
|
||||
|
||||
renderItemContent = (item) => {
|
||||
const { window, theme } = this.props;
|
||||
const { width, theme } = this.props;
|
||||
|
||||
if (!item.error) {
|
||||
return (
|
||||
|
@ -179,7 +178,7 @@ class UploadProgress extends Component {
|
|||
</Text>
|
||||
<CustomIcon name='Cross' size={20} color={themes[theme].auxiliaryText} onPress={() => this.cancelUpload(item)} />
|
||||
</View>,
|
||||
<View key='progress' style={[styles.progress, { width: (window.width * item.progress) / 100, backgroundColor: themes[theme].tintColor }]} />
|
||||
<View key='progress' style={[styles.progress, { width: (width * item.progress) / 100, backgroundColor: themes[theme].tintColor }]} />
|
||||
]
|
||||
);
|
||||
}
|
||||
|
@ -228,4 +227,4 @@ class UploadProgress extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
export default responsive(withTheme(UploadProgress));
|
||||
export default withTheme(UploadProgress);
|
||||
|
|
|
@ -52,6 +52,7 @@ import { CONTAINER_TYPES } from '../../lib/methods/actions';
|
|||
import Banner from './Banner';
|
||||
import Navigation from '../../lib/Navigation';
|
||||
import SafeAreaView from '../../containers/SafeAreaView';
|
||||
import { withDimensions } from '../../dimensions';
|
||||
|
||||
const stateAttrsUpdate = [
|
||||
'joined',
|
||||
|
@ -88,7 +89,9 @@ class RoomView extends React.Component {
|
|||
customEmojis: PropTypes.object,
|
||||
isMasterDetail: PropTypes.bool,
|
||||
theme: PropTypes.string,
|
||||
replyBroadcast: PropTypes.func
|
||||
replyBroadcast: PropTypes.func,
|
||||
width: PropTypes.number,
|
||||
height: PropTypes.number
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
|
@ -963,7 +966,7 @@ class RoomView extends React.Component {
|
|||
room, reactionsModalVisible, selectedMessage, loading, reacting
|
||||
} = this.state;
|
||||
const {
|
||||
user, baseUrl, theme, navigation, Hide_System_Messages
|
||||
user, baseUrl, theme, navigation, Hide_System_Messages, width, height
|
||||
} = this.props;
|
||||
const {
|
||||
rid, t, sysMes, bannerClosed, announcement
|
||||
|
@ -1004,8 +1007,10 @@ class RoomView extends React.Component {
|
|||
message={selectedMessage}
|
||||
onEmojiSelected={this.onReactionPress}
|
||||
reactionClose={this.onReactionClose}
|
||||
width={width}
|
||||
height={height}
|
||||
/>
|
||||
<UploadProgress rid={this.rid} user={user} baseUrl={baseUrl} />
|
||||
<UploadProgress rid={this.rid} user={user} baseUrl={baseUrl} width={width} />
|
||||
<ReactionsModal
|
||||
message={selectedMessage}
|
||||
isVisible={reactionsModalVisible}
|
||||
|
@ -1037,4 +1042,4 @@ const mapDispatchToProps = dispatch => ({
|
|||
replyBroadcast: message => dispatch(replyBroadcastAction(message))
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(withTheme(RoomView));
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(withDimensions(withTheme(RoomView)));
|
||||
|
|
|
@ -6,7 +6,6 @@ import {
|
|||
BackHandler,
|
||||
Text,
|
||||
Keyboard,
|
||||
Dimensions,
|
||||
RefreshControl
|
||||
} from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
@ -61,6 +60,7 @@ import { getUserSelector } from '../../selectors/login';
|
|||
import { goRoom } from '../../utils/goRoom';
|
||||
import SafeAreaView from '../../containers/SafeAreaView';
|
||||
import Header from '../../containers/Header';
|
||||
import { withDimensions } from '../../dimensions';
|
||||
|
||||
const SCROLL_OFFSET = 56;
|
||||
const INITIAL_NUM_TO_RENDER = isTablet ? 20 : 12;
|
||||
|
@ -128,7 +128,8 @@ class RoomsListView extends React.Component {
|
|||
useRealName: PropTypes.bool,
|
||||
connected: PropTypes.bool,
|
||||
isMasterDetail: PropTypes.bool,
|
||||
rooms: PropTypes.array
|
||||
rooms: PropTypes.array,
|
||||
width: PropTypes.number
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
|
@ -138,14 +139,12 @@ class RoomsListView extends React.Component {
|
|||
|
||||
this.gotSubscriptions = false;
|
||||
this.animated = false;
|
||||
const { width } = Dimensions.get('window');
|
||||
this.state = {
|
||||
searching: false,
|
||||
search: [],
|
||||
loading: true,
|
||||
allChats: [],
|
||||
chats: [],
|
||||
width,
|
||||
item: {}
|
||||
};
|
||||
this.setHeader();
|
||||
|
@ -157,7 +156,6 @@ class RoomsListView extends React.Component {
|
|||
if (isTablet) {
|
||||
EventEmitter.addEventListener(KEY_COMMAND, this.handleCommands);
|
||||
}
|
||||
Dimensions.addEventListener('change', this.onDimensionsChange);
|
||||
this.unsubscribeFocus = navigation.addListener('focus', () => {
|
||||
Orientation.unlockAllOrientations();
|
||||
this.animated = true;
|
||||
|
@ -228,14 +226,13 @@ class RoomsListView extends React.Component {
|
|||
|
||||
const {
|
||||
loading,
|
||||
width,
|
||||
search
|
||||
} = this.state;
|
||||
const { rooms } = this.props;
|
||||
const { rooms, width } = this.props;
|
||||
if (nextState.loading !== loading) {
|
||||
return true;
|
||||
}
|
||||
if (nextState.width !== width) {
|
||||
if (nextProps.width !== width) {
|
||||
return true;
|
||||
}
|
||||
if (!isEqual(nextState.search, search)) {
|
||||
|
@ -302,7 +299,6 @@ class RoomsListView extends React.Component {
|
|||
if (isTablet) {
|
||||
EventEmitter.removeListener(KEY_COMMAND, this.handleCommands);
|
||||
}
|
||||
Dimensions.removeEventListener('change', this.onDimensionsChange);
|
||||
console.countReset(`${ this.constructor.name }.render calls`);
|
||||
}
|
||||
|
||||
|
@ -352,9 +348,6 @@ class RoomsListView extends React.Component {
|
|||
navigation.setOptions(options);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react/sort-comp
|
||||
onDimensionsChange = ({ window: { width } }) => this.setState({ width });
|
||||
|
||||
internalSetState = (...args) => {
|
||||
if (this.animated) {
|
||||
animateNextTransition();
|
||||
|
@ -783,7 +776,7 @@ class RoomsListView extends React.Component {
|
|||
return this.renderSectionHeader(item.rid);
|
||||
}
|
||||
|
||||
const { width, item: currentItem } = this.state;
|
||||
const { item: currentItem } = this.state;
|
||||
const {
|
||||
user: {
|
||||
id: userId,
|
||||
|
@ -794,7 +787,8 @@ class RoomsListView extends React.Component {
|
|||
StoreLastMessage,
|
||||
useRealName,
|
||||
theme,
|
||||
isMasterDetail
|
||||
isMasterDetail,
|
||||
width
|
||||
} = this.props;
|
||||
const id = this.getUidDirectMessage(item);
|
||||
const isGroupChat = RocketChat.isGroupChat(item);
|
||||
|
@ -945,4 +939,4 @@ const mapDispatchToProps = dispatch => ({
|
|||
closeServerDropdown: () => dispatch(closeServerDropdownAction())
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(withTheme(RoomsListView));
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(withDimensions(withTheme(RoomsListView)));
|
||||
|
|
|
@ -91,7 +91,6 @@
|
|||
"react-native-progress": "4.1.2",
|
||||
"react-native-prompt-android": "^1.1.0",
|
||||
"react-native-reanimated": "^1.8.0",
|
||||
"react-native-responsive-ui": "^1.1.1",
|
||||
"react-native-safe-area-context": "^3.0.2",
|
||||
"react-native-screens": "^2.7.0",
|
||||
"react-native-scroll-bottom-sheet": "0.6.1",
|
||||
|
|
|
@ -11944,13 +11944,6 @@ react-native-reanimated@^1.8.0:
|
|||
dependencies:
|
||||
fbjs "^1.0.0"
|
||||
|
||||
react-native-responsive-ui@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/react-native-responsive-ui/-/react-native-responsive-ui-1.1.1.tgz#eb41839d4f3951ff025660185c36a9a9ce33759f"
|
||||
integrity sha1-60GDnU85Uf8CVmAYXDapqc4zdZ8=
|
||||
dependencies:
|
||||
lodash "^4.17.4"
|
||||
|
||||
react-native-safe-area-context@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-3.0.2.tgz#95dd7e56bc89bcc4f3f7bb5fada30c98420328b2"
|
||||
|
|
Loading…
Reference in New Issue