Fetch avatar initials from server (#512)

This commit is contained in:
Diego Mello 2018-10-29 10:53:32 -03:00 committed by GitHub
parent 11e94b9017
commit 6dde0f2432
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 56 additions and 273 deletions

View File

@ -7,11 +7,6 @@ exports[`Storyshots Avatar avatar 1`] = `
style={ style={
Array [ Array [
Object { Object {
"alignItems": "center",
"justifyContent": "center",
},
Object {
"backgroundColor": "#3F51B5",
"borderRadius": 4, "borderRadius": 4,
"height": 25, "height": 25,
"width": 25, "width": 25,
@ -20,38 +15,17 @@ exports[`Storyshots Avatar avatar 1`] = `
] ]
} }
> >
<Text
allowFontScaling={false}
style={
Array [
Object {
"color": "#ffffff",
},
Object {
"fontSize": 15.625,
"fontWeight": "800",
},
]
}
>
T
</Text>
<View <View
style={ style={
Array [ Array [
Object { Object {
"overflow": "hidden", "overflow": "hidden",
}, },
Array [
Object {
"position": "absolute",
},
Object { Object {
"borderRadius": 4, "borderRadius": 4,
"height": 25, "height": 25,
"width": 25, "width": 25,
}, },
],
] ]
} }
> >
@ -59,8 +33,9 @@ exports[`Storyshots Avatar avatar 1`] = `
resizeMode="cover" resizeMode="cover"
source={ source={
Object { Object {
"cache": "web",
"priority": "high", "priority": "high",
"uri": "baseUrl/avatar/test", "uri": "baseUrl/avatar/test?format=png&size=50",
} }
} }
style={ style={
@ -79,11 +54,6 @@ exports[`Storyshots Avatar avatar 1`] = `
style={ style={
Array [ Array [
Object { Object {
"alignItems": "center",
"justifyContent": "center",
},
Object {
"backgroundColor": "#9C27B0",
"borderRadius": 4, "borderRadius": 4,
"height": 40, "height": 40,
"width": 40, "width": 40,
@ -92,38 +62,17 @@ exports[`Storyshots Avatar avatar 1`] = `
] ]
} }
> >
<Text
allowFontScaling={false}
style={
Array [
Object {
"color": "#ffffff",
},
Object {
"fontSize": 25,
"fontWeight": "800",
},
]
}
>
A
</Text>
<View <View
style={ style={
Array [ Array [
Object { Object {
"overflow": "hidden", "overflow": "hidden",
}, },
Array [
Object {
"position": "absolute",
},
Object { Object {
"borderRadius": 4, "borderRadius": 4,
"height": 40, "height": 40,
"width": 40, "width": 40,
}, },
],
] ]
} }
> >
@ -131,8 +80,9 @@ exports[`Storyshots Avatar avatar 1`] = `
resizeMode="cover" resizeMode="cover"
source={ source={
Object { Object {
"cache": "web",
"priority": "high", "priority": "high",
"uri": "baseUrl/avatar/aa", "uri": "baseUrl/avatar/aa?format=png&size=50",
} }
} }
style={ style={
@ -151,11 +101,6 @@ exports[`Storyshots Avatar avatar 1`] = `
style={ style={
Array [ Array [
Object { Object {
"alignItems": "center",
"justifyContent": "center",
},
Object {
"backgroundColor": "#9C27B0",
"borderRadius": 4, "borderRadius": 4,
"height": 30, "height": 30,
"width": 30, "width": 30,
@ -164,38 +109,17 @@ exports[`Storyshots Avatar avatar 1`] = `
] ]
} }
> >
<Text
allowFontScaling={false}
style={
Array [
Object {
"color": "#ffffff",
},
Object {
"fontSize": 18.75,
"fontWeight": "800",
},
]
}
>
B
</Text>
<View <View
style={ style={
Array [ Array [
Object { Object {
"overflow": "hidden", "overflow": "hidden",
}, },
Array [
Object {
"position": "absolute",
},
Object { Object {
"borderRadius": 4, "borderRadius": 4,
"height": 30, "height": 30,
"width": 30, "width": 30,
}, },
],
] ]
} }
> >
@ -203,8 +127,9 @@ exports[`Storyshots Avatar avatar 1`] = `
resizeMode="cover" resizeMode="cover"
source={ source={
Object { Object {
"cache": "web",
"priority": "high", "priority": "high",
"uri": "baseUrl/avatar/bb", "uri": "baseUrl/avatar/bb?format=png&size=50",
} }
} }
style={ style={
@ -223,11 +148,6 @@ exports[`Storyshots Avatar avatar 1`] = `
style={ style={
Array [ Array [
Object { Object {
"alignItems": "center",
"justifyContent": "center",
},
Object {
"backgroundColor": "#3F51B5",
"borderRadius": 2, "borderRadius": 2,
"height": 25, "height": 25,
"width": 25, "width": 25,
@ -236,38 +156,17 @@ exports[`Storyshots Avatar avatar 1`] = `
] ]
} }
> >
<Text
allowFontScaling={false}
style={
Array [
Object {
"color": "#ffffff",
},
Object {
"fontSize": 15.625,
"fontWeight": "800",
},
]
}
>
T
</Text>
<View <View
style={ style={
Array [ Array [
Object { Object {
"overflow": "hidden", "overflow": "hidden",
}, },
Array [
Object {
"position": "absolute",
},
Object { Object {
"borderRadius": 2, "borderRadius": 2,
"height": 25, "height": 25,
"width": 25, "width": 25,
}, },
],
] ]
} }
> >
@ -275,8 +174,9 @@ exports[`Storyshots Avatar avatar 1`] = `
resizeMode="cover" resizeMode="cover"
source={ source={
Object { Object {
"cache": "web",
"priority": "high", "priority": "high",
"uri": "baseUrl/avatar/test", "uri": "baseUrl/avatar/test?format=png&size=50",
} }
} }
style={ style={

View File

@ -1,4 +1,3 @@
export const AVATAR_COLORS = ['#F44336', '#E91E63', '#9C27B0', '#673AB7', '#3F51B5', '#2196F3', '#03A9F4', '#00BCD4', '#009688', '#4CAF50', '#8BC34A', '#CDDC39', '#FFC107', '#FF9800', '#FF5722', '#795548', '#9E9E9E', '#607D8B'];
export const COLOR_DANGER = '#f5455c'; export const COLOR_DANGER = '#f5455c';
export const COLOR_BUTTON_PRIMARY = '#2D6AEA'; export const COLOR_BUTTON_PRIMARY = '#2D6AEA';
export const COLOR_TEXT = '#292E35'; export const COLOR_TEXT = '#292E35';

View File

@ -1,24 +1,7 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { import { View, ViewPropTypes } from 'react-native';
StyleSheet, Text, View, ViewPropTypes
} from 'react-native';
import FastImage from 'react-native-fast-image'; import FastImage from 'react-native-fast-image';
import avatarInitialsAndColor from '../utils/avatarInitialsAndColor';
const styles = StyleSheet.create({
iconContainer: {
// overflow: 'hidden',
justifyContent: 'center',
alignItems: 'center'
},
avatar: {
position: 'absolute'
},
avatarInitials: {
color: '#ffffff'
}
});
export default class Avatar extends React.PureComponent { export default class Avatar extends React.PureComponent {
static propTypes = { static propTypes = {
@ -29,91 +12,20 @@ export default class Avatar extends React.PureComponent {
size: PropTypes.number, size: PropTypes.number,
borderRadius: PropTypes.number, borderRadius: PropTypes.number,
type: PropTypes.string, type: PropTypes.string,
children: PropTypes.object, children: PropTypes.object
forceInitials: PropTypes.bool
} }
static defaultProps = { static defaultProps = {
text: '', text: '',
size: 25, size: 25,
type: 'd', type: 'd',
borderRadius: 4, borderRadius: 4
forceInitials: false
} }
state = { showInitials: true };
// componentDidMount() {
// const { text, type } = this.props;
// if (type === 'd') {
// this.users = this.userQuery(text);
// this.users.addListener(this.update);
// this.update();
// }
// }
// componentWillReceiveProps(nextProps) {
// if (nextProps.text !== this.props.text && nextProps.type === 'd') {
// if (this.users) {
// this.users.removeAllListeners();
// }
// this.users = this.userQuery(nextProps.text);
// this.users.addListener(this.update);
// this.update();
// }
// }
// componentWillUnmount() {
// if (this.users) {
// this.users.removeAllListeners();
// }
// }
// get avatarVersion() {
// // return (this.state.user && this.state.user.avatarVersion) || 0;
// return 0;
// }
/** FIXME: Workaround
* While we don't have containers/components structure, this is breaking tests.
* In that case, avatar would be a component, it would receive an `avatarVersion` param
* and we would have a avatar container in charge of making queries.
* Also, it would make possible to write unit tests like these.
*/
// userQuery = (username) => {
// if (database && database.databases && database.databases.activeDB) {
// return database.objects('users').filtered('username = $0', username);
// }
// return {
// addListener: () => {},
// removeAllListeners: () => {}
// };
// }
// update = () => {
// if (this.users.length) {
// this.setState({ user: this.users[0] });
// }
// }
render() { render() {
const { showInitials } = this.state;
const { const {
text, size, baseUrl, borderRadius, style, avatar, type, forceInitials, children text, size, baseUrl, borderRadius, style, avatar, type, children
} = this.props; } = this.props;
const { initials, color } = avatarInitialsAndColor(`${ text }`);
const iconContainerStyle = {
backgroundColor: color,
width: size,
height: size,
borderRadius
};
const avatarInitialsStyle = {
fontSize: size / 1.6,
fontWeight: '800'
};
const avatarStyle = { const avatarStyle = {
width: size, width: size,
@ -121,34 +33,21 @@ export default class Avatar extends React.PureComponent {
borderRadius borderRadius
}; };
let image; const room = type === 'd' ? text : `@${ text }`;
const uri = avatar || `${ baseUrl }/avatar/${ room }?format=png&size=${ size === 100 ? 100 : 50 }`;
if (type === 'd' && !forceInitials) { const image = (
const uri = avatar || `${ baseUrl }/avatar/${ text }`;
image = uri ? (
<FastImage <FastImage
style={[styles.avatar, avatarStyle]} style={avatarStyle}
source={{ source={{
uri, uri,
priority: FastImage.priority.high priority: FastImage.priority.high,
cache: 'web'
}} }}
/> />
) : null; );
}
return ( return (
<View style={[styles.iconContainer, iconContainerStyle, style]}> <View style={[avatarStyle, style]}>
{showInitials
? (
<Text
style={[styles.avatarInitials, avatarInitialsStyle]}
allowFontScaling={false}
>
{initials}
</Text>
)
: null
}
{image} {image}
{children} {children}
</View> </View>

View File

@ -1,16 +0,0 @@
import { AVATAR_COLORS } from '../constants/colors';
export default function(username = '') {
if (username === '') {
return {
initials: '',
colors: 'transparent'
};
}
const position = username.length % AVATAR_COLORS.length;
const color = AVATAR_COLORS[position];
const initials = username.replace(/[^A-Za-z0-9]/g, '').substr(0, 1).toUpperCase();
return { initials, color };
}

View File

@ -295,7 +295,7 @@ export default class ProfileView extends LoggedView {
return ( return (
<View style={styles.avatarButtons}> <View style={styles.avatarButtons}>
{this.renderAvatarButton({ {this.renderAvatarButton({
child: <Avatar text={user.username} size={50} baseUrl={baseUrl} forceInitials />, child: <Avatar text={`@${ user.username }`} size={50} baseUrl={baseUrl} />,
onPress: () => this.resetAvatar(), onPress: () => this.resetAvatar(),
key: 'profile-view-reset-avatar' key: 'profile-view-reset-avatar'
})} })}

View File

@ -3,7 +3,8 @@ import { ScrollView } from 'react-native';
import RoomItem from '../../../app/presentation/RoomItem'; import RoomItem from '../../../app/presentation/RoomItem';
const date = new Date(2017, 10, 10, 10); const date = '2017-10-10T10:00:00Z';
const baseUrl = 'https://open.rocket.chat';
export default ( export default (
<ScrollView> <ScrollView>
@ -11,7 +12,7 @@ export default (
type='d' type='d'
name='rocket.cat' name='rocket.cat'
_updatedAt={date} _updatedAt={date}
baseUrl='https://demo.rocket.chat' baseUrl={baseUrl}
/> />
<RoomItem <RoomItem
type='d' type='d'
@ -19,14 +20,14 @@ export default (
alert alert
_updatedAt={date} _updatedAt={date}
name='rocket.cat' name='rocket.cat'
baseUrl='https://demo.rocket.chat' baseUrl={baseUrl}
/> />
<RoomItem <RoomItem
type='d' type='d'
unread={1} unread={1}
_updatedAt={date} _updatedAt={date}
name='rocket.cat' name='rocket.cat'
baseUrl='https://demo.rocket.chat' baseUrl={baseUrl}
/> />
<RoomItem <RoomItem
type='d' type='d'
@ -34,14 +35,14 @@ export default (
alert alert
_updatedAt={date} _updatedAt={date}
name="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries" name="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries"
baseUrl='https://demo.rocket.chat' baseUrl={baseUrl}
/> />
<RoomItem <RoomItem
type='d' type='d'
unread={99} unread={99}
_updatedAt={date} _updatedAt={date}
name="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries" name="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries"
baseUrl='https://demo.rocket.chat' baseUrl={baseUrl}
/> />
<RoomItem <RoomItem
type='d' type='d'
@ -49,7 +50,7 @@ export default (
userMentions={0} userMentions={0}
_updatedAt={date} _updatedAt={date}
name="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries" name="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries"
baseUrl='https://demo.rocket.chat' baseUrl={baseUrl}
/> />
<RoomItem <RoomItem
type='d' type='d'
@ -57,7 +58,7 @@ export default (
userMentions={0} userMentions={0}
_updatedAt={date} _updatedAt={date}
name="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries" name="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries"
baseUrl='https://demo.rocket.chat' baseUrl={baseUrl}
/> />
<RoomItem <RoomItem
type='d' type='d'
@ -65,7 +66,7 @@ export default (
userMentions={1} userMentions={1}
_updatedAt={date} _updatedAt={date}
name="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries" name="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries"
baseUrl='https://demo.rocket.chat' baseUrl={baseUrl}
/> />
<RoomItem <RoomItem
type='d' type='d'