From 6dde0f243284b926cad4fb6f4e36a1683637ae1b Mon Sep 17 00:00:00 2001
From: Diego Mello <diegolmello@gmail.com>
Date: Mon, 29 Oct 2018 10:53:32 -0300
Subject: [PATCH] Fetch avatar initials from server (#512)

---
 .../__snapshots__/Storyshots.test.js.snap     | 156 ++++--------------
 app/constants/colors.js                       |   1 -
 app/containers/Avatar.js                      | 135 ++-------------
 app/utils/avatarInitialsAndColor.js           |  16 --
 app/views/ProfileView/index.js                |   2 +-
 storybook/stories/Channels/DirectMessage.js   |  19 ++-
 6 files changed, 56 insertions(+), 273 deletions(-)
 delete mode 100644 app/utils/avatarInitialsAndColor.js

diff --git a/__tests__/__snapshots__/Storyshots.test.js.snap b/__tests__/__snapshots__/Storyshots.test.js.snap
index a2aff47d3..54fbac5f7 100644
--- a/__tests__/__snapshots__/Storyshots.test.js.snap
+++ b/__tests__/__snapshots__/Storyshots.test.js.snap
@@ -7,11 +7,6 @@ exports[`Storyshots Avatar avatar 1`] = `
       style={
         Array [
           Object {
-            "alignItems": "center",
-            "justifyContent": "center",
-          },
-          Object {
-            "backgroundColor": "#3F51B5",
             "borderRadius": 4,
             "height": 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
         style={
           Array [
             Object {
               "overflow": "hidden",
             },
-            Array [
-              Object {
-                "position": "absolute",
-              },
-              Object {
-                "borderRadius": 4,
-                "height": 25,
-                "width": 25,
-              },
-            ],
+            Object {
+              "borderRadius": 4,
+              "height": 25,
+              "width": 25,
+            },
           ]
         }
       >
@@ -59,8 +33,9 @@ exports[`Storyshots Avatar avatar 1`] = `
           resizeMode="cover"
           source={
             Object {
+              "cache": "web",
               "priority": "high",
-              "uri": "baseUrl/avatar/test",
+              "uri": "baseUrl/avatar/test?format=png&size=50",
             }
           }
           style={
@@ -79,11 +54,6 @@ exports[`Storyshots Avatar avatar 1`] = `
       style={
         Array [
           Object {
-            "alignItems": "center",
-            "justifyContent": "center",
-          },
-          Object {
-            "backgroundColor": "#9C27B0",
             "borderRadius": 4,
             "height": 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
         style={
           Array [
             Object {
               "overflow": "hidden",
             },
-            Array [
-              Object {
-                "position": "absolute",
-              },
-              Object {
-                "borderRadius": 4,
-                "height": 40,
-                "width": 40,
-              },
-            ],
+            Object {
+              "borderRadius": 4,
+              "height": 40,
+              "width": 40,
+            },
           ]
         }
       >
@@ -131,8 +80,9 @@ exports[`Storyshots Avatar avatar 1`] = `
           resizeMode="cover"
           source={
             Object {
+              "cache": "web",
               "priority": "high",
-              "uri": "baseUrl/avatar/aa",
+              "uri": "baseUrl/avatar/aa?format=png&size=50",
             }
           }
           style={
@@ -151,11 +101,6 @@ exports[`Storyshots Avatar avatar 1`] = `
       style={
         Array [
           Object {
-            "alignItems": "center",
-            "justifyContent": "center",
-          },
-          Object {
-            "backgroundColor": "#9C27B0",
             "borderRadius": 4,
             "height": 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
         style={
           Array [
             Object {
               "overflow": "hidden",
             },
-            Array [
-              Object {
-                "position": "absolute",
-              },
-              Object {
-                "borderRadius": 4,
-                "height": 30,
-                "width": 30,
-              },
-            ],
+            Object {
+              "borderRadius": 4,
+              "height": 30,
+              "width": 30,
+            },
           ]
         }
       >
@@ -203,8 +127,9 @@ exports[`Storyshots Avatar avatar 1`] = `
           resizeMode="cover"
           source={
             Object {
+              "cache": "web",
               "priority": "high",
-              "uri": "baseUrl/avatar/bb",
+              "uri": "baseUrl/avatar/bb?format=png&size=50",
             }
           }
           style={
@@ -223,11 +148,6 @@ exports[`Storyshots Avatar avatar 1`] = `
       style={
         Array [
           Object {
-            "alignItems": "center",
-            "justifyContent": "center",
-          },
-          Object {
-            "backgroundColor": "#3F51B5",
             "borderRadius": 2,
             "height": 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
         style={
           Array [
             Object {
               "overflow": "hidden",
             },
-            Array [
-              Object {
-                "position": "absolute",
-              },
-              Object {
-                "borderRadius": 2,
-                "height": 25,
-                "width": 25,
-              },
-            ],
+            Object {
+              "borderRadius": 2,
+              "height": 25,
+              "width": 25,
+            },
           ]
         }
       >
@@ -275,8 +174,9 @@ exports[`Storyshots Avatar avatar 1`] = `
           resizeMode="cover"
           source={
             Object {
+              "cache": "web",
               "priority": "high",
-              "uri": "baseUrl/avatar/test",
+              "uri": "baseUrl/avatar/test?format=png&size=50",
             }
           }
           style={
diff --git a/app/constants/colors.js b/app/constants/colors.js
index 5a6037428..e7545ccae 100644
--- a/app/constants/colors.js
+++ b/app/constants/colors.js
@@ -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_BUTTON_PRIMARY = '#2D6AEA';
 export const COLOR_TEXT = '#292E35';
diff --git a/app/containers/Avatar.js b/app/containers/Avatar.js
index a8327927a..74b2d4c1a 100644
--- a/app/containers/Avatar.js
+++ b/app/containers/Avatar.js
@@ -1,24 +1,7 @@
 import React from 'react';
 import PropTypes from 'prop-types';
-import {
-	StyleSheet, Text, View, ViewPropTypes
-} from 'react-native';
+import { View, ViewPropTypes } from 'react-native';
 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 {
 	static propTypes = {
@@ -29,91 +12,20 @@ export default class Avatar extends React.PureComponent {
 		size: PropTypes.number,
 		borderRadius: PropTypes.number,
 		type: PropTypes.string,
-		children: PropTypes.object,
-		forceInitials: PropTypes.bool
+		children: PropTypes.object
 	}
 
 	static defaultProps = {
 		text: '',
 		size: 25,
 		type: 'd',
-		borderRadius: 4,
-		forceInitials: false
+		borderRadius: 4
 	}
 
-	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() {
-		const { showInitials } = this.state;
 		const {
-			text, size, baseUrl, borderRadius, style, avatar, type, forceInitials, children
+			text, size, baseUrl, borderRadius, style, avatar, type, children
 		} = 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 = {
 			width: size,
@@ -121,34 +33,21 @@ export default class Avatar extends React.PureComponent {
 			borderRadius
 		};
 
-		let image;
-
-		if (type === 'd' && !forceInitials) {
-			const uri = avatar || `${ baseUrl }/avatar/${ text }`;
-			image = uri ? (
-				<FastImage
-					style={[styles.avatar, avatarStyle]}
-					source={{
-						uri,
-						priority: FastImage.priority.high
-					}}
-				/>
-			) : null;
-		}
+		const room = type === 'd' ? text : `@${ text }`;
+		const uri = avatar || `${ baseUrl }/avatar/${ room }?format=png&size=${ size === 100 ? 100 : 50 }`;
+		const image = (
+			<FastImage
+				style={avatarStyle}
+				source={{
+					uri,
+					priority: FastImage.priority.high,
+					cache: 'web'
+				}}
+			/>
+		);
 
 		return (
-			<View style={[styles.iconContainer, iconContainerStyle, style]}>
-				{showInitials
-					? (
-						<Text
-							style={[styles.avatarInitials, avatarInitialsStyle]}
-							allowFontScaling={false}
-						>
-							{initials}
-						</Text>
-					)
-					: null
-				}
+			<View style={[avatarStyle, style]}>
 				{image}
 				{children}
 			</View>
diff --git a/app/utils/avatarInitialsAndColor.js b/app/utils/avatarInitialsAndColor.js
deleted file mode 100644
index 0724d9a8a..000000000
--- a/app/utils/avatarInitialsAndColor.js
+++ /dev/null
@@ -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 };
-}
diff --git a/app/views/ProfileView/index.js b/app/views/ProfileView/index.js
index 4a28514b9..7170714a3 100644
--- a/app/views/ProfileView/index.js
+++ b/app/views/ProfileView/index.js
@@ -295,7 +295,7 @@ export default class ProfileView extends LoggedView {
 		return (
 			<View style={styles.avatarButtons}>
 				{this.renderAvatarButton({
-					child: <Avatar text={user.username} size={50} baseUrl={baseUrl} forceInitials />,
+					child: <Avatar text={`@${ user.username }`} size={50} baseUrl={baseUrl} />,
 					onPress: () => this.resetAvatar(),
 					key: 'profile-view-reset-avatar'
 				})}
diff --git a/storybook/stories/Channels/DirectMessage.js b/storybook/stories/Channels/DirectMessage.js
index 14c19e948..f341a4851 100644
--- a/storybook/stories/Channels/DirectMessage.js
+++ b/storybook/stories/Channels/DirectMessage.js
@@ -3,7 +3,8 @@ import { ScrollView } from 'react-native';
 
 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 (
 	<ScrollView>
@@ -11,7 +12,7 @@ export default (
 			type='d'
 			name='rocket.cat'
 			_updatedAt={date}
-			baseUrl='https://demo.rocket.chat'
+			baseUrl={baseUrl}
 		/>
 		<RoomItem
 			type='d'
@@ -19,14 +20,14 @@ export default (
 			alert
 			_updatedAt={date}
 			name='rocket.cat'
-			baseUrl='https://demo.rocket.chat'
+			baseUrl={baseUrl}
 		/>
 		<RoomItem
 			type='d'
 			unread={1}
 			_updatedAt={date}
 			name='rocket.cat'
-			baseUrl='https://demo.rocket.chat'
+			baseUrl={baseUrl}
 		/>
 		<RoomItem
 			type='d'
@@ -34,14 +35,14 @@ export default (
 			alert
 			_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"
-			baseUrl='https://demo.rocket.chat'
+			baseUrl={baseUrl}
 		/>
 		<RoomItem
 			type='d'
 			unread={99}
 			_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"
-			baseUrl='https://demo.rocket.chat'
+			baseUrl={baseUrl}
 		/>
 		<RoomItem
 			type='d'
@@ -49,7 +50,7 @@ export default (
 			userMentions={0}
 			_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"
-			baseUrl='https://demo.rocket.chat'
+			baseUrl={baseUrl}
 		/>
 		<RoomItem
 			type='d'
@@ -57,7 +58,7 @@ export default (
 			userMentions={0}
 			_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"
-			baseUrl='https://demo.rocket.chat'
+			baseUrl={baseUrl}
 		/>
 		<RoomItem
 			type='d'
@@ -65,7 +66,7 @@ export default (
 			userMentions={1}
 			_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"
-			baseUrl='https://demo.rocket.chat'
+			baseUrl={baseUrl}
 		/>
 		<RoomItem
 			type='d'
-- 
GitLab