Remove connection badge (#862)
* Connecting indicator on RoomsListView header * Connecting indicator on RoomView header * Remove ConnectionBadge * Show updating on RoomView load messages
This commit is contained in:
parent
44f3b7f1a9
commit
94e32368dd
|
@ -1,140 +0,0 @@
|
|||
import React, { Component } from 'react';
|
||||
import {
|
||||
Text, StyleSheet, ActivityIndicator, Animated, Easing
|
||||
} from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import I18n from '../i18n';
|
||||
import debounce from '../utils/debounce';
|
||||
import sharedStyles from '../views/Styles';
|
||||
import {
|
||||
COLOR_BACKGROUND_CONTAINER, COLOR_DANGER, COLOR_SUCCESS, COLOR_WHITE, COLOR_TEXT_DESCRIPTION
|
||||
} from '../constants/colors';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
width: '100%',
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
height: 41,
|
||||
backgroundColor: COLOR_BACKGROUND_CONTAINER,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
elevation: 4
|
||||
},
|
||||
text: {
|
||||
color: COLOR_WHITE,
|
||||
fontSize: 15,
|
||||
...sharedStyles.textRegular
|
||||
},
|
||||
textConnecting: {
|
||||
...sharedStyles.textColorDescription
|
||||
},
|
||||
containerConnected: {
|
||||
backgroundColor: COLOR_SUCCESS
|
||||
},
|
||||
containerOffline: {
|
||||
backgroundColor: COLOR_DANGER
|
||||
},
|
||||
activityIndicator: {
|
||||
marginRight: 15
|
||||
}
|
||||
});
|
||||
|
||||
const ANIMATION_DURATION = 300;
|
||||
|
||||
@connect(state => ({
|
||||
connecting: state.meteor.connecting,
|
||||
connected: state.meteor.connected,
|
||||
disconnected: !state.meteor.connecting && !state.meteor.connected
|
||||
}))
|
||||
class ConnectionBadge extends Component {
|
||||
static propTypes = {
|
||||
connecting: PropTypes.bool,
|
||||
connected: PropTypes.bool,
|
||||
disconnected: PropTypes.bool
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.animatedValue = new Animated.Value(0);
|
||||
if (props.connecting) {
|
||||
this.show();
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
const { connected, disconnected } = this.props;
|
||||
this.show(connected || disconnected);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.timeout) {
|
||||
clearTimeout(this.timeout);
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react/sort-comp
|
||||
animate = debounce((toValue, autoHide) => {
|
||||
Animated.timing(
|
||||
this.animatedValue,
|
||||
{
|
||||
toValue,
|
||||
duration: ANIMATION_DURATION,
|
||||
easing: Easing.ease,
|
||||
useNativeDriver: true
|
||||
},
|
||||
).start(() => {
|
||||
if (toValue === 1 && autoHide) {
|
||||
if (this.timeout) {
|
||||
clearTimeout(this.timeout);
|
||||
}
|
||||
this.timeout = setTimeout(() => {
|
||||
this.hide();
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
}, 300);
|
||||
|
||||
show = (autoHide) => {
|
||||
this.animate(1, autoHide);
|
||||
}
|
||||
|
||||
hide = () => {
|
||||
this.animate(0);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { connecting, connected } = this.props;
|
||||
|
||||
const translateY = this.animatedValue.interpolate({
|
||||
inputRange: [0, 1],
|
||||
outputRange: [-42, 0]
|
||||
});
|
||||
|
||||
if (connecting) {
|
||||
return (
|
||||
<Animated.View style={[styles.container, { transform: [{ translateY }] }]}>
|
||||
<ActivityIndicator color={COLOR_TEXT_DESCRIPTION} style={styles.activityIndicator} />
|
||||
<Text style={[styles.text, styles.textConnecting]}>{I18n.t('Connecting')}</Text>
|
||||
</Animated.View>
|
||||
);
|
||||
} else if (connected) {
|
||||
return (
|
||||
<Animated.View style={[styles.container, styles.containerConnected, { transform: [{ translateY }] }]}>
|
||||
<Text style={styles.text}>{I18n.t('Connected')}</Text>
|
||||
</Animated.View>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Animated.View style={[styles.container, styles.containerOffline, { transform: [{ translateY }] }]}>
|
||||
<Text style={styles.text}>{I18n.t('Offline')}</Text>
|
||||
</Animated.View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ConnectionBadge;
|
|
@ -65,8 +65,34 @@ Typing.propTypes = {
|
|||
usersTyping: PropTypes.array
|
||||
};
|
||||
|
||||
const HeaderTitle = React.memo(({
|
||||
title, scale, connecting, isFetching
|
||||
}) => {
|
||||
if (connecting) {
|
||||
title = I18n.t('Connecting');
|
||||
}
|
||||
if (isFetching) {
|
||||
title = I18n.t('Updating');
|
||||
}
|
||||
return (
|
||||
<Text
|
||||
style={[styles.title, { fontSize: TITLE_SIZE * scale }]}
|
||||
numberOfLines={1}
|
||||
testID={`room-view-title-${ title }`}
|
||||
>{title}
|
||||
</Text>
|
||||
);
|
||||
});
|
||||
|
||||
HeaderTitle.propTypes = {
|
||||
title: PropTypes.string,
|
||||
scale: PropTypes.number,
|
||||
connecting: PropTypes.bool,
|
||||
isFetching: PropTypes.bool
|
||||
};
|
||||
|
||||
const Header = React.memo(({
|
||||
title, type, status, usersTyping, width, height, prid, tmid, widthOffset
|
||||
title, type, status, usersTyping, width, height, prid, tmid, widthOffset, connecting, isFetching
|
||||
}) => {
|
||||
const portrait = height > width;
|
||||
let scale = 1;
|
||||
|
@ -93,7 +119,15 @@ const Header = React.memo(({
|
|||
contentContainerStyle={styles.scroll}
|
||||
>
|
||||
<Icon type={prid ? 'discussion' : type} status={status} />
|
||||
<Text style={[styles.title, { fontSize: TITLE_SIZE * scale }]} numberOfLines={1} testID={`room-view-title-${ title }`}>{title}</Text>
|
||||
<HeaderTitle
|
||||
prid={prid}
|
||||
type={type}
|
||||
status={status}
|
||||
title={title}
|
||||
scale={scale}
|
||||
connecting={connecting}
|
||||
isFetching={isFetching}
|
||||
/>
|
||||
</ScrollView>
|
||||
</View>
|
||||
{type === 'thread' ? null : <Typing usersTyping={usersTyping} />}
|
||||
|
@ -110,7 +144,9 @@ Header.propTypes = {
|
|||
tmid: PropTypes.string,
|
||||
status: PropTypes.string,
|
||||
usersTyping: PropTypes.array,
|
||||
widthOffset: PropTypes.number
|
||||
widthOffset: PropTypes.number,
|
||||
connecting: PropTypes.bool,
|
||||
isFetching: PropTypes.bool
|
||||
};
|
||||
|
||||
Header.defaultProps = {
|
||||
|
|
|
@ -26,6 +26,7 @@ import RightButtons from './RightButtons';
|
|||
}
|
||||
|
||||
return {
|
||||
connecting: state.meteor.connecting,
|
||||
userId,
|
||||
isLoggedUser,
|
||||
status
|
||||
|
@ -40,6 +41,8 @@ export default class RoomHeaderView extends Component {
|
|||
rid: PropTypes.string,
|
||||
window: PropTypes.object,
|
||||
status: PropTypes.string,
|
||||
connecting: PropTypes.bool,
|
||||
isFetching: PropTypes.bool,
|
||||
widthOffset: PropTypes.number,
|
||||
isLoggedUser: PropTypes.bool,
|
||||
userId: PropTypes.string
|
||||
|
@ -63,7 +66,7 @@ export default class RoomHeaderView extends Component {
|
|||
shouldComponentUpdate(nextProps, nextState) {
|
||||
const { usersTyping, user } = this.state;
|
||||
const {
|
||||
type, title, status, window
|
||||
type, title, status, window, connecting, isFetching
|
||||
} = this.props;
|
||||
if (nextProps.type !== type) {
|
||||
return true;
|
||||
|
@ -74,6 +77,12 @@ export default class RoomHeaderView extends Component {
|
|||
if (nextProps.status !== status) {
|
||||
return true;
|
||||
}
|
||||
if (nextProps.connecting !== connecting) {
|
||||
return true;
|
||||
}
|
||||
if (nextProps.isFetching !== isFetching) {
|
||||
return true;
|
||||
}
|
||||
if (nextProps.window.width !== window.width) {
|
||||
return true;
|
||||
}
|
||||
|
@ -102,7 +111,7 @@ export default class RoomHeaderView extends Component {
|
|||
render() {
|
||||
const { usersTyping, user } = this.state;
|
||||
const {
|
||||
window, title, type, prid, tmid, widthOffset, isLoggedUser, status: userStatus
|
||||
window, title, type, prid, tmid, widthOffset, isLoggedUser, status: userStatus, connecting, isFetching
|
||||
} = this.props;
|
||||
let status = 'offline';
|
||||
|
||||
|
@ -125,6 +134,8 @@ export default class RoomHeaderView extends Component {
|
|||
height={window.height}
|
||||
usersTyping={usersTyping}
|
||||
widthOffset={widthOffset}
|
||||
connecting={connecting}
|
||||
isFetching={isFetching}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@ import log from '../../utils/log';
|
|||
import { isIOS } from '../../utils/deviceInfo';
|
||||
import EventEmitter from '../../utils/events';
|
||||
import I18n from '../../i18n';
|
||||
import ConnectionBadge from '../../containers/ConnectionBadge';
|
||||
import RoomHeaderView, { RightButtons } from './Header';
|
||||
import StatusBar from '../../containers/StatusBar';
|
||||
import Separator from './Separator';
|
||||
|
@ -67,10 +66,19 @@ export default class RoomView extends LoggedView {
|
|||
const title = navigation.getParam('name');
|
||||
const t = navigation.getParam('t');
|
||||
const tmid = navigation.getParam('tmid');
|
||||
const isFetching = navigation.getParam('isFetching', false);
|
||||
return {
|
||||
headerTitleContainerStyle: styles.headerTitleContainerStyle,
|
||||
headerTitle: (
|
||||
<RoomHeaderView rid={rid} prid={prid} tmid={tmid} title={title} type={t} widthOffset={tmid ? 95 : 130} />
|
||||
<RoomHeaderView
|
||||
rid={rid}
|
||||
prid={prid}
|
||||
tmid={tmid}
|
||||
title={title}
|
||||
type={t}
|
||||
widthOffset={tmid ? 95 : 130}
|
||||
isFetching={isFetching}
|
||||
/>
|
||||
),
|
||||
headerRight: <RightButtons rid={rid} tmid={tmid} t={t} navigation={navigation} />
|
||||
};
|
||||
|
@ -312,14 +320,18 @@ export default class RoomView extends LoggedView {
|
|||
return ((room.prid || useRealName) && room.fname) || room.name;
|
||||
}
|
||||
|
||||
getMessages = () => {
|
||||
getMessages = async() => {
|
||||
const { room } = this.state;
|
||||
const { navigation } = this.props;
|
||||
try {
|
||||
navigation.setParams({ isFetching: true });
|
||||
if (room.lastOpen) {
|
||||
return RocketChat.loadMissedMessages(room);
|
||||
await RocketChat.loadMissedMessages(room);
|
||||
} else {
|
||||
return RocketChat.loadMessagesForRoom(room);
|
||||
await RocketChat.loadMessagesForRoom(room);
|
||||
}
|
||||
navigation.setParams({ isFetching: false });
|
||||
return Promise.resolve();
|
||||
} catch (e) {
|
||||
console.log('TCL: getMessages -> e', e);
|
||||
log('getMessages', e);
|
||||
|
@ -519,7 +531,6 @@ export default class RoomView extends LoggedView {
|
|||
{this.renderActions()}
|
||||
<ReactionPicker onEmojiSelected={this.onReactionPress} />
|
||||
<UploadProgress rid={this.rid} />
|
||||
<ConnectionBadge />
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -42,8 +42,8 @@ const styles = StyleSheet.create({
|
|||
}
|
||||
});
|
||||
|
||||
const Header = ({
|
||||
isFetching, serverName, showServerDropdown, setSearchInputRef, showSearchHeader, onSearchChangeText, onPress
|
||||
const Header = React.memo(({
|
||||
connecting, isFetching, serverName, showServerDropdown, setSearchInputRef, showSearchHeader, onSearchChangeText, onPress
|
||||
}) => {
|
||||
if (showSearchHeader) {
|
||||
return (
|
||||
|
@ -61,6 +61,7 @@ const Header = ({
|
|||
return (
|
||||
<View style={styles.container}>
|
||||
<TouchableOpacity onPress={onPress} testID='rooms-list-header-server-dropdown-button'>
|
||||
{connecting ? <Text style={styles.updating}>{I18n.t('Connecting')}</Text> : null}
|
||||
{isFetching ? <Text style={styles.updating}>{I18n.t('Updating')}</Text> : null}
|
||||
<View style={styles.button}>
|
||||
<Text style={[styles.server, isFetching && styles.serverSmall]}>{serverName}</Text>
|
||||
|
@ -69,7 +70,7 @@ const Header = ({
|
|||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
Header.propTypes = {
|
||||
showServerDropdown: PropTypes.bool.isRequired,
|
||||
|
@ -77,6 +78,7 @@ Header.propTypes = {
|
|||
onPress: PropTypes.func.isRequired,
|
||||
onSearchChangeText: PropTypes.func.isRequired,
|
||||
setSearchInputRef: PropTypes.func.isRequired,
|
||||
connecting: PropTypes.bool,
|
||||
isFetching: PropTypes.bool,
|
||||
serverName: PropTypes.string
|
||||
};
|
||||
|
|
|
@ -39,15 +39,18 @@ const styles = StyleSheet.create({
|
|||
}
|
||||
});
|
||||
|
||||
const HeaderTitle = ({ isFetching }) => {
|
||||
const HeaderTitle = React.memo(({ connecting, isFetching }) => {
|
||||
if (connecting) {
|
||||
return <Text style={styles.title}>{I18n.t('Connecting')}</Text>;
|
||||
}
|
||||
if (isFetching) {
|
||||
return <Text style={styles.title}>{I18n.t('Updating')}</Text>;
|
||||
}
|
||||
return <Text style={styles.title}>{I18n.t('Messages')}</Text>;
|
||||
};
|
||||
});
|
||||
|
||||
const Header = ({
|
||||
isFetching, serverName, showServerDropdown, onPress
|
||||
const Header = React.memo(({
|
||||
connecting, isFetching, serverName, showServerDropdown, onPress
|
||||
}) => (
|
||||
<View style={styles.container}>
|
||||
<TouchableOpacity
|
||||
|
@ -55,16 +58,17 @@ const Header = ({
|
|||
testID='rooms-list-header-server-dropdown-button'
|
||||
style={styles.container}
|
||||
>
|
||||
<HeaderTitle isFetching={isFetching} />
|
||||
<HeaderTitle connecting={connecting} isFetching={isFetching} />
|
||||
<View style={styles.button}>
|
||||
<Text style={styles.server}>{serverName}</Text>
|
||||
<Image style={[styles.disclosure, showServerDropdown && styles.upsideDown]} source={{ uri: 'disclosure_indicator_server' }} />
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
));
|
||||
|
||||
Header.propTypes = {
|
||||
connecting: PropTypes.bool,
|
||||
isFetching: PropTypes.bool,
|
||||
serverName: PropTypes.string,
|
||||
showServerDropdown: PropTypes.bool.isRequired,
|
||||
|
@ -76,6 +80,7 @@ Header.defaultProps = {
|
|||
};
|
||||
|
||||
HeaderTitle.propTypes = {
|
||||
connecting: PropTypes.bool,
|
||||
isFetching: PropTypes.bool
|
||||
};
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import Header from './Header';
|
|||
showServerDropdown: state.rooms.showServerDropdown,
|
||||
showSortDropdown: state.rooms.showSortDropdown,
|
||||
showSearchHeader: state.rooms.showSearchHeader,
|
||||
connecting: state.meteor.connecting,
|
||||
isFetching: state.rooms.isFetching,
|
||||
serverName: state.settings.Site_Name
|
||||
}), dispatch => ({
|
||||
|
@ -25,6 +26,7 @@ export default class RoomsListHeaderView extends PureComponent {
|
|||
showSortDropdown: PropTypes.bool,
|
||||
showSearchHeader: PropTypes.bool,
|
||||
serverName: PropTypes.string,
|
||||
connecting: PropTypes.bool,
|
||||
isFetching: PropTypes.bool,
|
||||
open: PropTypes.func,
|
||||
close: PropTypes.func,
|
||||
|
@ -68,13 +70,15 @@ export default class RoomsListHeaderView extends PureComponent {
|
|||
|
||||
render() {
|
||||
const {
|
||||
serverName, showServerDropdown, showSearchHeader, isFetching
|
||||
serverName, showServerDropdown, showSearchHeader, connecting, isFetching
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<Header
|
||||
serverName={serverName}
|
||||
showServerDropdown={showServerDropdown}
|
||||
showSearchHeader={showSearchHeader}
|
||||
connecting={connecting}
|
||||
isFetching={isFetching}
|
||||
setSearchInputRef={this.setSearchInputRef}
|
||||
onPress={this.onPress}
|
||||
|
|
|
@ -8,7 +8,6 @@ import { isEqual } from 'lodash';
|
|||
import { SafeAreaView, NavigationEvents } from 'react-navigation';
|
||||
import Orientation from 'react-native-orientation-locker';
|
||||
|
||||
import ConnectionBadge from '../../containers/ConnectionBadge';
|
||||
import database, { safeAddListener } from '../../lib/realm';
|
||||
import RocketChat from '../../lib/rocketchat';
|
||||
import RoomItem, { ROW_HEIGHT } from '../../presentation/RoomItem';
|
||||
|
@ -559,7 +558,6 @@ export default class RoomsListView extends LoggedView {
|
|||
: null
|
||||
}
|
||||
{showServerDropdown ? <ServerDropdown /> : null}
|
||||
<ConnectionBadge />
|
||||
<NavigationEvents
|
||||
onDidFocus={() => BackHandler.addEventListener('hardwareBackPress', this.handleBackPress)}
|
||||
onWillBlur={() => BackHandler.removeEventListener('hardwareBackPress', this.handleBackPress)}
|
||||
|
|
Loading…
Reference in New Issue