Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 144 additions & 0 deletions app/containers/ConnectionBadge.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import React, { Component } from 'react';
import {
Text, StyleSheet, ActivityIndicator, Animated, TouchableWithoutFeedback, Easing
} from 'react-native';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';

import I18n from '../i18n';

const styles = StyleSheet.create({
container: {
width: '100%',
position: 'absolute',
top: 0,
height: 41,
backgroundColor: '#F7F8FA',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
elevation: 4
},
text: {
color: '#fff',
fontSize: 15,
fontWeight: 'normal'
},
textConnecting: {
color: '#9EA2A8'
},
containerConnected: {
backgroundColor: '#2de0a5'
},
containerOffline: {
backgroundColor: '#f5455c'
},
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.state = {
visible: false
};
this.animatedValue = new Animated.Value(0);
}

componentDidMount() {
const { connecting, disconnected } = this.props;
if (connecting || disconnected) {
this.animate(1);
}
}

componentDidUpdate(prevProps) {
const { visible } = this.state;
const { connecting, connected, disconnected } = this.props;

if ((connecting && connecting !== prevProps.connecting) || (disconnected && disconnected !== prevProps.disconnected)) {
if (!visible) {
this.animate(1);
}
} else if (connected && connected !== prevProps.connected) {
if (visible) {
setTimeout(() => {
this.animate(0);
}, 1000);
}
}
}

animate = (toValue) => {
Animated.timing(
this.animatedValue,
{
toValue,
duration: ANIMATION_DURATION,
easing: Easing.ease,
useNativeDriver: true
},
).start(() => this.setState({ visible: toValue === 1 }));
}

show = () => {
this.animate(1);
}

hide = () => {
this.animate(0);
}

render() {
const { connecting, connected } = this.props;

const translateY = this.animatedValue.interpolate({
inputRange: [0, 1],
outputRange: [-41, 0]
});

if (connecting) {
return (
<TouchableWithoutFeedback onPress={this.hide}>
<Animated.View style={[styles.container, { transform: [{ translateY }] }]}>
<ActivityIndicator color='#9EA2A8' style={styles.activityIndicator} />
<Text style={[styles.text, styles.textConnecting]}>{I18n.t('Connecting')}</Text>
</Animated.View>
</TouchableWithoutFeedback>
);
} else if (connected) {
return (
<TouchableWithoutFeedback onPress={this.hide}>
<Animated.View style={[styles.container, styles.containerConnected, { transform: [{ translateY }] }]}>
<Text style={styles.text}>{I18n.t('Connected')}</Text>
</Animated.View>
</TouchableWithoutFeedback>
);
}

return (
<TouchableWithoutFeedback onPress={this.hide}>
<Animated.View style={[styles.container, styles.containerOffline, { transform: [{ translateY }] }]}>
<Text style={styles.text}>{I18n.t('Offline')}</Text>
</Animated.View>
</TouchableWithoutFeedback>
);
}
}

export default ConnectionBadge;
4 changes: 2 additions & 2 deletions app/i18n/locales/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ export default {
Colaborative: 'Colaborative',
Connect: 'Connect',
Connect_to_a_server: 'Connect to a server',
Connected_to: 'Connected to',
Connecting: 'Connecting',
Connected: 'Connected',
Connecting: 'Connecting...',
Copied_to_clipboard: 'Copied to clipboard!',
Copy_Message: 'Copy Message',
Copy_Permalink: 'Copy Permalink',
Expand Down
4 changes: 2 additions & 2 deletions app/i18n/locales/pt-BR.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ export default {
Colaborative: 'Colaborativo',
Connect: 'Conectar',
Connect_to_a_server: 'Conectar a um servidor',
Connected_to: 'Conectado a',
Connecting: 'Conectando',
Connected: 'Conectado',
Connecting: 'Conectando...',
Copied_to_clipboard: 'Copiado para a área de transferência!',
Copy_Message: 'Copiar Mensagem',
Copy_Permalink: 'Copiar Link-Permanente',
Expand Down
2 changes: 2 additions & 0 deletions app/views/RoomView/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import I18n from '../../i18n';
import debounce from '../../utils/debounce';
import { iconsMap } from '../../Icons';
import store from '../../lib/createStore';
import ConnectionBadge from '../../containers/ConnectionBadge';

let RoomActionsView = null;

Expand Down Expand Up @@ -388,6 +389,7 @@ export default class RoomView extends LoggedView {
{showErrorActions ? <MessageErrorActions /> : null}
<ReactionPicker onEmojiSelected={this.onReactionPress} />
<UploadProgress rid={this.rid} />
<ConnectionBadge />
</SafeAreaView>
);
}
Expand Down
6 changes: 4 additions & 2 deletions app/views/RoomsListView/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { isEqual } from 'lodash';
import { Navigation } from 'react-native-navigation';

import SearchBox from '../../containers/SearchBox';
import ConnectionBadge from '../../containers/ConnectionBadge';
import database from '../../lib/realm';
import RocketChat from '../../lib/rocketchat';
import RoomItem from '../../presentation/RoomItem';
Expand Down Expand Up @@ -91,8 +92,8 @@ export default class RoomsListView extends LoggedView {
groupByType: PropTypes.bool,
showFavorites: PropTypes.bool,
showUnread: PropTypes.bool,
toggleSortDropdown: PropTypes.func,
useRealName: PropTypes.bool
useRealName: PropTypes.bool,
toggleSortDropdown: PropTypes.func
}

constructor(props) {
Expand Down Expand Up @@ -565,6 +566,7 @@ export default class RoomsListView extends LoggedView {
: null
}
{showServerDropdown ? <ServerDropdown navigator={navigator} /> : null}
<ConnectionBadge />
</SafeAreaView>
);
}
Expand Down
9 changes: 7 additions & 2 deletions app/views/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Platform } from 'react-native';
import { Navigation } from 'react-native-navigation';
import { Provider } from 'react-redux';
import { gestureHandlerRootHOC } from 'react-native-gesture-handler';

import OnboardingView from './OnboardingView';
import ProfileView from './ProfileView';
import RoomsListHeaderView from './RoomsListView/Header';
import RoomsListSearchView from './RoomsListView/Search';
import RoomsListView from './RoomsListView';
import RoomView from './RoomView';
import SettingsView from './SettingsView';
Expand All @@ -15,7 +15,12 @@ export const registerScreens = (store) => {
Navigation.registerComponent('OnboardingView', () => OnboardingView, store, Provider);
Navigation.registerComponent('ProfileView', () => ProfileView, store, Provider);
Navigation.registerComponent('RoomsListHeaderView', () => RoomsListHeaderView, store, Provider);
Navigation.registerComponent('RoomsListSearchView', () => RoomsListSearchView, store, Provider);

if (Platform.OS === 'android') {
const RoomsListSearchView = require('./RoomsListView/Search');
Navigation.registerComponent('RoomsListSearchView', () => RoomsListSearchView, store, Provider);
}

Navigation.registerComponent('RoomsListView', () => gestureHandlerRootHOC(RoomsListView), store, Provider);
Navigation.registerComponent('RoomView', () => gestureHandlerRootHOC(RoomView), store, Provider);
Navigation.registerComponent('SettingsView', () => SettingsView, store, Provider);
Expand Down