|
@@ -3,27 +3,23 @@ import { Image, View } from 'react-native';
|
3
|
3
|
|
4
|
4
|
import { Platform } from '../../react';
|
5
|
5
|
|
6
|
|
-
|
7
|
6
|
/**
|
8
|
7
|
* The default avatar to be used, in case the requested URI is not available
|
9
|
|
- * or fails to be loaded.
|
10
|
|
- *
|
11
|
|
- * This is an inline version of images/avatar2.png.
|
|
8
|
+ * or fails to load. It is an inline version of images/avatar2.png.
|
12
|
9
|
*
|
13
|
10
|
* @type {string}
|
14
|
11
|
*/
|
15
|
12
|
const DEFAULT_AVATAR = require('./defaultAvatar.png');
|
16
|
13
|
|
17
|
14
|
/**
|
18
|
|
- * The amount of time to wait when the avatar URI is undefined before we start
|
19
|
|
- * showing a default locally generated one. Note that since we have no URI, we
|
20
|
|
- * have nothing we can cache, so the color will be random.
|
|
15
|
+ * The number of milliseconds to wait when the avatar URI is undefined before we
|
|
16
|
+ * start showing a default locally generated one. Note that since we have no
|
|
17
|
+ * URI, we have nothing we can cache, so the color will be random.
|
21
|
18
|
*
|
22
|
19
|
* @type {number}
|
23
|
20
|
*/
|
24
|
21
|
const UNDEFINED_AVATAR_TIMEOUT = 1000;
|
25
|
22
|
|
26
|
|
-
|
27
|
23
|
/**
|
28
|
24
|
* Implements an Image component wrapper, which returns a default image if the
|
29
|
25
|
* requested one fails to load. The default image background is chosen by
|
|
@@ -86,15 +82,18 @@ export default class AvatarImage extends Component {
|
86
|
82
|
* @returns {void}
|
87
|
83
|
*/
|
88
|
84
|
componentWillReceiveProps(nextProps) {
|
89
|
|
- const prevURI = this.props.source && this.props.source.uri;
|
90
|
|
- const nextURI = nextProps.source && nextProps.source.uri;
|
|
85
|
+ const prevSource = this.props.source;
|
|
86
|
+ const prevURI = prevSource && prevSource.uri;
|
|
87
|
+ const nextSource = nextProps.source;
|
|
88
|
+ const nextURI = nextSource && nextSource.uri;
|
91
|
89
|
|
92
|
90
|
if (typeof prevURI === 'undefined') {
|
93
|
91
|
clearTimeout(this._timeout);
|
94
|
92
|
if (typeof nextURI === 'undefined') {
|
95
|
|
- this._timeout = setTimeout(() => {
|
96
|
|
- this.setState({ showDefault: true });
|
97
|
|
- }, UNDEFINED_AVATAR_TIMEOUT);
|
|
93
|
+ this._timeout
|
|
94
|
+ = setTimeout(
|
|
95
|
+ () => this.setState({ showDefault: true }),
|
|
96
|
+ UNDEFINED_AVATAR_TIMEOUT);
|
98
|
97
|
} else {
|
99
|
98
|
this.setState({ showDefault: nextProps.forceDefault });
|
100
|
99
|
}
|
|
@@ -115,8 +114,8 @@ export default class AvatarImage extends Component {
|
115
|
114
|
* Computes a hash over the URI and returns a HSL background color. We use
|
116
|
115
|
* 75% as lightness, for nice pastel style colors.
|
117
|
116
|
*
|
118
|
|
- * @returns {string} - The HSL CSS property.
|
119
|
117
|
* @private
|
|
118
|
+ * @returns {string} - The HSL CSS property.
|
120
|
119
|
*/
|
121
|
120
|
_getBackgroundColor() {
|
122
|
121
|
const uri = this.props.source.uri;
|
|
@@ -157,9 +156,15 @@ export default class AvatarImage extends Component {
|
157
|
156
|
* @inheritdoc
|
158
|
157
|
*/
|
159
|
158
|
render() {
|
160
|
|
- // eslint-disable-next-line no-unused-vars
|
161
|
|
- const { forceDefault, source, style, ...props } = this.props;
|
162
|
159
|
const { failed, showDefault } = this.state;
|
|
160
|
+ const {
|
|
161
|
+ // The following is/are forked in state:
|
|
162
|
+ forceDefault, // eslint-disable-line no-unused-vars
|
|
163
|
+
|
|
164
|
+ source,
|
|
165
|
+ style,
|
|
166
|
+ ...props
|
|
167
|
+ } = this.props;
|
163
|
168
|
|
164
|
169
|
if (failed || showDefault) {
|
165
|
170
|
const coloredBackground = {
|
|
@@ -168,19 +173,22 @@ export default class AvatarImage extends Component {
|
168
|
173
|
overflow: 'hidden'
|
169
|
174
|
};
|
170
|
175
|
|
|
176
|
+ // We need to wrap the Image in a View because of a bug in React
|
|
177
|
+ // Native for Android:
|
|
178
|
+ // https://github.com/facebook/react-native/issues/3198
|
|
179
|
+ const workaround3198 = Platform.OS === 'android';
|
171
|
180
|
let element = React.createElement(Image, {
|
172
|
181
|
...props,
|
173
|
182
|
source: DEFAULT_AVATAR,
|
174
|
|
- style: Platform.OS === 'android' ? style : coloredBackground
|
|
183
|
+ style: workaround3198 ? style : coloredBackground
|
175
|
184
|
});
|
176
|
185
|
|
177
|
|
- if (Platform.OS === 'android') {
|
178
|
|
- // Here we need to wrap the Image in a View because of a bug in
|
179
|
|
- // React Native for Android:
|
180
|
|
- // https://github.com/facebook/react-native/issues/3198
|
181
|
|
-
|
182
|
|
- element = React.createElement(View,
|
183
|
|
- { style: coloredBackground }, element);
|
|
186
|
+ if (workaround3198) {
|
|
187
|
+ element
|
|
188
|
+ = React.createElement(
|
|
189
|
+ View,
|
|
190
|
+ { style: coloredBackground },
|
|
191
|
+ element);
|
184
|
192
|
}
|
185
|
193
|
|
186
|
194
|
return element;
|