[CHORE] Refactor ServerItem (#2778)

* Updated ServerDropdown and ServerItem

* Added ServerItem stories

* Update ServerDropdown.js

* Updated ServerItem stories

* Updated ServerItem stories and ServerItem component

* Updated SelectServerView, ServerItem and ServerItem stories

* Updated ServerItem stories

* Updated ServerItem stories

* Update tests

Co-authored-by: Diego Mello <diegolmello@gmail.com>
This commit is contained in:
Gerzon Z 2021-01-20 16:43:59 -04:00 committed by GitHub
parent d83631d7f2
commit 8d1dd27271
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 1265 additions and 63 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,23 +1,33 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { View, Text } from 'react-native'; import { View, Text, Pressable } from 'react-native';
import FastImage from '@rocket.chat/react-native-fast-image'; import FastImage from '@rocket.chat/react-native-fast-image';
import Touch from '../../utils/touch';
import Check from '../../containers/Check'; import Check from '../../containers/Check';
import styles, { ROW_HEIGHT } from './styles'; import styles, { ROW_HEIGHT } from './styles';
import { themes } from '../../constants/colors'; import { themes } from '../../constants/colors';
import { isIOS } from '../../utils/deviceInfo';
import { withTheme } from '../../theme';
export { ROW_HEIGHT }; export { ROW_HEIGHT };
const defaultLogo = require('../../static/images/logo.png');
const ServerItem = React.memo(({ const ServerItem = React.memo(({
server, item, onPress, hasCheck, theme item, onPress, onLongPress, hasCheck, theme
}) => ( }) => (
<Touch <Pressable
onPress={onPress} onPress={onPress}
style={[styles.serverItem, { backgroundColor: themes[theme].backgroundColor }]} onLongPress={() => onLongPress?.()}
testID={`rooms-list-header-server-${ item.id }`} testID={`rooms-list-header-server-${ item.id }`}
theme={theme} android_ripple={{
color: themes[theme].bannerBackground
}}
style={({ pressed }) => ({
backgroundColor: isIOS && pressed
? themes[theme].bannerBackground
: themes[theme].backgroundColor
})}
> >
<View style={styles.serverItemContainer}> <View style={styles.serverItemContainer}>
{item.iconURL {item.iconURL
@ -27,33 +37,33 @@ const ServerItem = React.memo(({
uri: item.iconURL, uri: item.iconURL,
priority: FastImage.priority.high priority: FastImage.priority.high
}} }}
defaultSource={require('../../static/images/logo.png')} defaultSource={defaultLogo}
style={styles.serverIcon} style={styles.serverIcon}
onError={() => console.log('err_loading_server_icon')} onError={() => console.log('err_loading_server_icon')}
/> />
) )
: ( : (
<FastImage <FastImage
source={require('../../static/images/logo.png')} source={defaultLogo}
style={styles.serverIcon} style={styles.serverIcon}
/> />
) )
} }
<View style={styles.serverTextContainer}> <View style={styles.serverTextContainer}>
<Text style={[styles.serverName, { color: themes[theme].titleText }]}>{item.name || item.id}</Text> <Text numberOfLines={1} style={[styles.serverName, { color: themes[theme].titleText }]}>{item.name || item.id}</Text>
<Text style={[styles.serverUrl, { color: themes[theme].auxiliaryText }]}>{item.id}</Text> <Text numberOfLines={1} style={[styles.serverUrl, { color: themes[theme].auxiliaryText }]}>{item.id}</Text>
</View> </View>
{item.id === server && hasCheck ? <Check theme={theme} /> : null} {hasCheck ? <Check theme={theme} /> : null}
</View> </View>
</Touch> </Pressable>
)); ));
ServerItem.propTypes = { ServerItem.propTypes = {
onPress: PropTypes.func.isRequired,
item: PropTypes.object.isRequired, item: PropTypes.object.isRequired,
onPress: PropTypes.func.isRequired,
onLongPress: PropTypes.func,
hasCheck: PropTypes.bool, hasCheck: PropTypes.bool,
server: PropTypes.string,
theme: PropTypes.string theme: PropTypes.string
}; };
export default ServerItem; export default withTheme(ServerItem);

View File

@ -5,10 +5,6 @@ import sharedStyles from '../../views/Styles';
export const ROW_HEIGHT = 56; export const ROW_HEIGHT = 56;
export default StyleSheet.create({ export default StyleSheet.create({
serverItem: {
height: ROW_HEIGHT,
justifyContent: 'center'
},
serverItemContainer: { serverItemContainer: {
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center' alignItems: 'center'
@ -16,20 +12,22 @@ export default StyleSheet.create({
serverIcon: { serverIcon: {
width: 44, width: 44,
height: 44, height: 44,
marginHorizontal: 15, margin: 12,
borderRadius: 4 borderRadius: 4,
resizeMode: 'contain'
}, },
serverTextContainer: { serverTextContainer: {
flex: 1, flex: 1,
flexDirection: 'column', flexDirection: 'column',
justifyContent: 'center' justifyContent: 'center',
paddingRight: 18
}, },
serverName: { serverName: {
fontSize: 18, fontSize: 18,
...sharedStyles.textSemibold ...sharedStyles.textSemibold
}, },
serverUrl: { serverUrl: {
fontSize: 15, fontSize: 16,
...sharedStyles.textRegular ...sharedStyles.textRegular
} }
}); });

View File

@ -1,6 +1,6 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { import {
View, Text, Animated, Easing, TouchableWithoutFeedback, TouchableOpacity, FlatList, Image, Pressable View, Text, Animated, Easing, TouchableWithoutFeedback, TouchableOpacity, FlatList
} from 'react-native'; } from 'react-native';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { connect, batch } from 'react-redux'; import { connect, batch } from 'react-redux';
@ -14,12 +14,12 @@ import styles from './styles';
import RocketChat from '../../lib/rocketchat'; import RocketChat from '../../lib/rocketchat';
import I18n from '../../i18n'; import I18n from '../../i18n';
import EventEmitter from '../../utils/events'; import EventEmitter from '../../utils/events';
import Check from '../../containers/Check'; import ServerItem from '../../presentation/ServerItem';
import database from '../../lib/database'; import database from '../../lib/database';
import { themes } from '../../constants/colors'; import { themes } from '../../constants/colors';
import { withTheme } from '../../theme'; import { withTheme } from '../../theme';
import { KEY_COMMAND, handleCommandSelectServer } from '../../commands'; import { KEY_COMMAND, handleCommandSelectServer } from '../../commands';
import { isTablet, isIOS } from '../../utils/deviceInfo'; import { isTablet } from '../../utils/deviceInfo';
import { localAuthenticate } from '../../utils/localAuthentication'; import { localAuthenticate } from '../../utils/localAuthentication';
import { showConfirmationAlert } from '../../utils/info'; import { showConfirmationAlert } from '../../utils/info';
import { logEvent, events } from '../../utils/log'; import { logEvent, events } from '../../utils/log';
@ -202,43 +202,13 @@ class ServerDropdown extends Component {
const { server, theme } = this.props; const { server, theme } = this.props;
return ( return (
<Pressable <ServerItem
item={item}
onPress={() => this.select(item.id)} onPress={() => this.select(item.id)}
onLongPress={() => (item.id === server || this.remove(item.id))} onLongPress={() => (item.id === server || this.remove(item.id))}
testID={`rooms-list-header-server-${ item.id }`} hasCheck={item.id === server}
android_ripple={{ theme={theme}
color: themes[theme].bannerBackground />
}}
style={({ pressed }) => ({
backgroundColor: isIOS && pressed
? themes[theme].bannerBackground
: 'transparent'
})}
>
<View style={styles.serverItemContainer}>
{item.iconURL
? (
<Image
source={{ uri: item.iconURL }}
defaultSource={require('../../static/images/logo.png')}
style={styles.serverIcon}
onError={() => console.warn('error loading serverIcon')}
/>
)
: (
<Image
source={require('../../static/images/logo.png')}
style={styles.serverIcon}
/>
)
}
<View style={styles.serverTextContainer}>
<Text style={[styles.serverName, { color: themes[theme].titleText }]} numberOfLines={1}>{item.name || item.id}</Text>
<Text style={[styles.serverUrl, { color: themes[theme].auxiliaryText }]} numberOfLines={1}>{item.id}</Text>
</View>
{item.id === server ? <Check theme={theme} /> : null}
</View>
</Pressable>
); );
} }

View File

@ -65,10 +65,9 @@ class SelectServerView extends React.Component {
const { server, theme } = this.props; const { server, theme } = this.props;
return ( return (
<ServerItem <ServerItem
server={server}
onPress={() => this.select(item.id)} onPress={() => this.select(item.id)}
item={item} item={item}
hasCheck hasCheck={item.id === server}
theme={theme} theme={theme}
/> />
); );

View File

@ -0,0 +1,73 @@
/* eslint-disable import/no-extraneous-dependencies, import/no-unresolved, import/extensions, react/prop-types */
import React from 'react';
import { storiesOf } from '@storybook/react-native';
import ServerItemComponent from '../../app/presentation/ServerItem';
import { ThemeContext } from '../../app/theme';
const stories = storiesOf('ServerItem', module);
const themes = {
light: 'light',
dark: 'dark',
black: 'black'
};
const item = {
name: 'Rocket.Chat',
id: 'https://open.rocket.chat/',
iconURL: 'https://open.rocket.chat/images/logo/android-chrome-512x512.png'
};
const ServerItem = props => (
<ServerItemComponent
item={item}
hasCheck={false}
{...props}
/>
);
stories.add('content', () => (
<>
<ServerItem
hasCheck
/>
<ServerItem
item={{
...item,
name: 'Super Long Server Name in Rocket.Chat',
id: 'https://superlongservername.tologintoasuperlongservername/'
}}
/>
<ServerItem
item={{
id: 'https://stable.rocket.chat/'
}}
/>
</>
));
stories.add('touchable', () => (
<>
<ServerItem onLongPress={() => alert('Long Press')} onPress={() => alert('Press')} />
<ServerItem onPress={() => alert('Press')} />
<ServerItem onLongPress={() => alert('Long Press')} />
</>
));
const ThemeStory = ({ theme }) => (
<ThemeContext.Provider value={theme}>
<ServerItem
theme={theme}
hasCheck
/>
</ThemeContext.Provider>
);
stories.add('themes', () => (
<>
<ThemeStory theme={themes.light} />
<ThemeStory theme={themes.dark} />
<ThemeStory theme={themes.black} />
</>
));

View File

@ -6,6 +6,7 @@ import { storiesOf } from '@storybook/react-native';
import RoomItem from './RoomItem'; import RoomItem from './RoomItem';
import './List'; import './List';
import './ServerItem';
import Message from './Message'; import Message from './Message';
import UiKitMessage from './UiKitMessage'; import UiKitMessage from './UiKitMessage';
import UiKitModal from './UiKitModal'; import UiKitModal from './UiKitModal';