@momo-kits/avatar 0.0.2-beta → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Avatar.js +150 -31
- package/Avatar.web.js +98 -69
- package/package.json +15 -16
package/Avatar.js
CHANGED
|
@@ -2,13 +2,19 @@
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import React, { Component } from 'react';
|
|
4
4
|
import {
|
|
5
|
-
View, StyleSheet, TouchableOpacity
|
|
5
|
+
View, StyleSheet, TouchableOpacity, Dimensions
|
|
6
6
|
} from 'react-native';
|
|
7
7
|
import { get, isEqual } from 'lodash';
|
|
8
8
|
import {
|
|
9
|
-
ValueUtil, Colors, Text, IconSource, Image
|
|
9
|
+
ValueUtil, Colors, Text, IconSource, Image, ScaleSize
|
|
10
10
|
} from '@momo-kits/core';
|
|
11
11
|
|
|
12
|
+
export const AvatarQuality = {
|
|
13
|
+
low: 'low',
|
|
14
|
+
medium: 'medium',
|
|
15
|
+
high: 'high',
|
|
16
|
+
};
|
|
17
|
+
|
|
12
18
|
export const AvatarSize = {
|
|
13
19
|
tiny: 'tiny',
|
|
14
20
|
small: 'small',
|
|
@@ -29,6 +35,29 @@ export const AvatarSize = {
|
|
|
29
35
|
size96: 'size96'
|
|
30
36
|
};
|
|
31
37
|
|
|
38
|
+
const COLORS = [
|
|
39
|
+
'#3683f3',
|
|
40
|
+
'#ea63af',
|
|
41
|
+
'#f94889',
|
|
42
|
+
'#82b6da',
|
|
43
|
+
'#2fc093',
|
|
44
|
+
'#7b4a41',
|
|
45
|
+
'#ff97bc',
|
|
46
|
+
'#4130d7',
|
|
47
|
+
'#c3c3c3',
|
|
48
|
+
'#f7ae2f',
|
|
49
|
+
'#b04595',
|
|
50
|
+
'#57b748',
|
|
51
|
+
'#ff8900',
|
|
52
|
+
'#7841bf',
|
|
53
|
+
'#be3f3e',
|
|
54
|
+
'#c51515',
|
|
55
|
+
'#8e6472',
|
|
56
|
+
'#fed27d',
|
|
57
|
+
'#ff6f5d',
|
|
58
|
+
'#05b8ae',
|
|
59
|
+
];
|
|
60
|
+
|
|
32
61
|
export const SubIconType = {
|
|
33
62
|
momo: 'momo',
|
|
34
63
|
online: 'online',
|
|
@@ -76,7 +105,7 @@ const styles = StyleSheet.create({
|
|
|
76
105
|
}
|
|
77
106
|
});
|
|
78
107
|
|
|
79
|
-
const subIconSize =
|
|
108
|
+
const subIconSize = (width) => ({
|
|
80
109
|
tiny: {
|
|
81
110
|
width: 8,
|
|
82
111
|
height: 8,
|
|
@@ -176,7 +205,7 @@ const subIconSize = StyleSheet.create({
|
|
|
176
205
|
}
|
|
177
206
|
});
|
|
178
207
|
|
|
179
|
-
const avatarSize =
|
|
208
|
+
const avatarSize = (width) => ({
|
|
180
209
|
tiny: {
|
|
181
210
|
width: 16,
|
|
182
211
|
height: 16,
|
|
@@ -264,32 +293,59 @@ const avatarSize = StyleSheet.create({
|
|
|
264
293
|
}
|
|
265
294
|
});
|
|
266
295
|
|
|
267
|
-
const shortName =
|
|
296
|
+
const shortName = (width) => ({
|
|
268
297
|
tiny: {
|
|
269
|
-
fontSize: 5
|
|
298
|
+
fontSize: ScaleSize(5, width)
|
|
270
299
|
},
|
|
271
300
|
small: {
|
|
272
|
-
fontSize: 11
|
|
301
|
+
fontSize: ScaleSize(11, width)
|
|
273
302
|
},
|
|
274
303
|
medium: {
|
|
275
|
-
fontSize: 15
|
|
304
|
+
fontSize: ScaleSize(15, width)
|
|
305
|
+
},
|
|
306
|
+
middle: {
|
|
307
|
+
fontSize: ScaleSize(16, width)
|
|
276
308
|
},
|
|
277
309
|
large: {
|
|
278
|
-
fontSize: 20
|
|
310
|
+
fontSize: ScaleSize(20, width)
|
|
279
311
|
},
|
|
280
312
|
giant: {
|
|
281
|
-
fontSize: 25
|
|
313
|
+
fontSize: ScaleSize(25, width)
|
|
282
314
|
}
|
|
283
315
|
});
|
|
284
316
|
|
|
285
317
|
export default class Avatar extends Component {
|
|
286
318
|
constructor(props) {
|
|
287
319
|
super(props);
|
|
320
|
+
this.color = this.getAvatarColor();
|
|
288
321
|
this.state = {
|
|
289
322
|
hideSource: false,
|
|
290
323
|
ownUpdate: false,
|
|
291
|
-
source: props.source
|
|
324
|
+
source: props.source,
|
|
325
|
+
dimensions: {}
|
|
292
326
|
};
|
|
327
|
+
this.imageSource = '';
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
componentDidMount() {
|
|
331
|
+
const { scaleSize } = this.props;
|
|
332
|
+
if (scaleSize) {
|
|
333
|
+
this.subscription = Dimensions.addEventListener(
|
|
334
|
+
'change',
|
|
335
|
+
({ window }) => {
|
|
336
|
+
if(window?.height > 0 && window?.width > 0) {
|
|
337
|
+
this.setState({ dimensions: window });
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
componentWillUnmount() {
|
|
345
|
+
const { scaleSize } = this.props;
|
|
346
|
+
if (scaleSize) {
|
|
347
|
+
this.subscription?.remove?.();
|
|
348
|
+
}
|
|
293
349
|
}
|
|
294
350
|
|
|
295
351
|
static getDerivedStateFromProps(nextProps, prevState) {
|
|
@@ -315,12 +371,24 @@ export default class Avatar extends Component {
|
|
|
315
371
|
return alphabet.join('');
|
|
316
372
|
}
|
|
317
373
|
|
|
318
|
-
|
|
374
|
+
hashUrl(url) {
|
|
375
|
+
let hash = 0;
|
|
376
|
+
let char;
|
|
377
|
+
if (url?.length === 0) return hash;
|
|
378
|
+
for (let i = 0; i < url?.length; i++) {
|
|
379
|
+
char = url?.charCodeAt(i);
|
|
380
|
+
hash = ((hash << 5) - hash) + char;
|
|
381
|
+
hash &= hash; // Convert to 32bit integer
|
|
382
|
+
}
|
|
383
|
+
return hash;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
renderShortName = (name, avatarStyle, size, color,) => {
|
|
319
387
|
if (name) {
|
|
320
388
|
const shortedName = this.getContactShortName(name);
|
|
321
389
|
const shortNameStyle = this.mapShortNameStyle(size);
|
|
322
390
|
return (
|
|
323
|
-
<View style={[styles.shortNameView, avatarStyle]}>
|
|
391
|
+
<View style={[styles.shortNameView, avatarStyle, { backgroundColor: color }]}>
|
|
324
392
|
<Text.H4 style={[styles.shortNameText, shortNameStyle]}>{shortedName}</Text.H4>
|
|
325
393
|
</View>
|
|
326
394
|
);
|
|
@@ -334,49 +402,70 @@ export default class Avatar extends Component {
|
|
|
334
402
|
}
|
|
335
403
|
|
|
336
404
|
isValidImageUrl = (source) => {
|
|
337
|
-
const validSource = source &&
|
|
405
|
+
const validSource = source && source.uri && this.isUrl(source.uri);
|
|
338
406
|
return validSource;
|
|
339
407
|
}
|
|
340
408
|
|
|
409
|
+
mapAvatarQuality = (url, quality) => {
|
|
410
|
+
if (!quality || quality === AvatarQuality.medium) {
|
|
411
|
+
return url;
|
|
412
|
+
}
|
|
413
|
+
if (quality === AvatarQuality.low) {
|
|
414
|
+
return url.replace('.png', '_s64.png');
|
|
415
|
+
}
|
|
416
|
+
if (quality === AvatarQuality.high) {
|
|
417
|
+
return url.replace('.png', '_s512.png');
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
return url;
|
|
421
|
+
}
|
|
422
|
+
|
|
341
423
|
mapStyleFromSize = (size) => {
|
|
342
|
-
const
|
|
424
|
+
const { dimensions } = this.state;
|
|
425
|
+
const avatarStyle = avatarSize(dimensions?.width > 0 ? dimensions?.width : null).small;
|
|
343
426
|
if (typeof size === 'object') return size;
|
|
344
|
-
if (avatarSize[size]) return avatarSize[size];
|
|
427
|
+
if (avatarSize(dimensions?.width > 0 ? dimensions?.width : null)[size]) return avatarSize(dimensions?.width > 0 ? dimensions?.width : null)[size];
|
|
345
428
|
return avatarStyle;
|
|
346
429
|
}
|
|
347
430
|
|
|
348
431
|
mapShortNameStyle = (size) => {
|
|
349
432
|
let shortNameStyle = {};
|
|
433
|
+
const { dimensions } = this.state;
|
|
350
434
|
switch (size) {
|
|
351
435
|
case AvatarSize.tiny: {
|
|
352
|
-
shortNameStyle = shortName.tiny;
|
|
436
|
+
shortNameStyle = shortName(dimensions?.width > 0 ? dimensions?.width : null).tiny;
|
|
353
437
|
break;
|
|
354
438
|
}
|
|
355
439
|
case AvatarSize.small: {
|
|
356
|
-
shortNameStyle = shortName.small;
|
|
440
|
+
shortNameStyle = shortName(dimensions?.width > 0 ? dimensions?.width : null).small;
|
|
357
441
|
break;
|
|
358
442
|
}
|
|
359
443
|
case AvatarSize.medium: {
|
|
360
|
-
shortNameStyle = shortName.medium;
|
|
444
|
+
shortNameStyle = shortName(dimensions?.width > 0 ? dimensions?.width : null).medium;
|
|
445
|
+
break;
|
|
446
|
+
}
|
|
447
|
+
case AvatarSize.size48: {
|
|
448
|
+
shortNameStyle = shortName(dimensions?.width || null).middle;
|
|
361
449
|
break;
|
|
362
450
|
}
|
|
363
451
|
case AvatarSize.large: {
|
|
364
|
-
shortNameStyle = shortName.large;
|
|
452
|
+
shortNameStyle = shortName(dimensions?.width > 0 ? dimensions?.width : null).large;
|
|
365
453
|
break;
|
|
366
454
|
}
|
|
367
455
|
case AvatarSize.giant: {
|
|
368
|
-
shortNameStyle = shortName.giant;
|
|
456
|
+
shortNameStyle = shortName(dimensions?.width > 0 ? dimensions?.width : null).giant;
|
|
369
457
|
break;
|
|
370
458
|
}
|
|
371
459
|
default:
|
|
372
|
-
shortNameStyle = shortName.small;
|
|
460
|
+
shortNameStyle = shortName(dimensions?.width > 0 ? dimensions?.width : null).small;
|
|
373
461
|
}
|
|
374
462
|
return shortNameStyle;
|
|
375
463
|
}
|
|
376
464
|
|
|
377
465
|
mapSubIconSize = (size) => {
|
|
378
|
-
const
|
|
379
|
-
|
|
466
|
+
const { dimensions } = this.state;
|
|
467
|
+
const subIconStyle = subIconSize(dimensions?.width > 0 ? dimensions?.width : null).small;
|
|
468
|
+
if (subIconSize(dimensions?.width > 0 ? dimensions?.width : null)[size]) return subIconSize(dimensions?.width > 0 ? dimensions?.width : null)[size];
|
|
380
469
|
return subIconStyle;
|
|
381
470
|
}
|
|
382
471
|
|
|
@@ -393,8 +482,11 @@ export default class Avatar extends Component {
|
|
|
393
482
|
};
|
|
394
483
|
}
|
|
395
484
|
|
|
396
|
-
onLoadSourceError = () => {
|
|
397
|
-
this.
|
|
485
|
+
onLoadSourceError = (imageSource) => {
|
|
486
|
+
if(this.imageSource?.uri !== imageSource?.uri){
|
|
487
|
+
this.imageSource = imageSource;
|
|
488
|
+
this.setState({ hideSource: true, ownUpdate: true });
|
|
489
|
+
}
|
|
398
490
|
}
|
|
399
491
|
|
|
400
492
|
renderSubIcon = () => {
|
|
@@ -426,6 +518,16 @@ export default class Avatar extends Component {
|
|
|
426
518
|
);
|
|
427
519
|
}
|
|
428
520
|
|
|
521
|
+
getAvatarColor() {
|
|
522
|
+
const { source } = this.props;
|
|
523
|
+
const number = Math.abs(this.hashUrl(source));
|
|
524
|
+
if (number && !isNaN(Number(number))) {
|
|
525
|
+
const colorIndex = Number(number) % COLORS.length;
|
|
526
|
+
return COLORS[colorIndex];
|
|
527
|
+
}
|
|
528
|
+
return '#d5d6d6';
|
|
529
|
+
}
|
|
530
|
+
|
|
429
531
|
onPress = () => {
|
|
430
532
|
const { onPress } = this.props;
|
|
431
533
|
if (onPress && typeof onPress === 'function') onPress();
|
|
@@ -433,23 +535,34 @@ export default class Avatar extends Component {
|
|
|
433
535
|
|
|
434
536
|
render() {
|
|
435
537
|
const {
|
|
436
|
-
size, source, name, resizeMode, style, onPress, isShowLoading, loading, cached, extraPropsImage
|
|
538
|
+
size, source, name, resizeMode, style, onPress, isShowLoading, loading, cached, extraPropsImage, quality
|
|
437
539
|
} = this.props;
|
|
438
540
|
const { hideSource } = this.state;
|
|
439
541
|
const avatarStyle = this.mapStyleFromSize(size);
|
|
440
542
|
const containerSize = this.extractSize(avatarStyle);
|
|
441
543
|
const imageSource = ValueUtil.getImageSource(source);
|
|
442
544
|
const showName = typeof imageSource === 'object' && Object.keys(imageSource).length === 0 && typeof imageSource !== 'number';
|
|
545
|
+
// add priority high for avatar
|
|
546
|
+
if (imageSource?.uri) {
|
|
547
|
+
imageSource.priority = 'high';
|
|
548
|
+
imageSource.uri = this.mapAvatarQuality(imageSource.uri, quality);
|
|
549
|
+
// if doest not have time query, set default cache time to 1 day
|
|
550
|
+
if (!imageSource.uri?.includes('?') && cached) {
|
|
551
|
+
const midnight = new Date().setHours(0, 0, 0, 0);
|
|
552
|
+
imageSource.uri = `${imageSource.uri}?time=${midnight}`;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
443
556
|
const inner = (
|
|
444
557
|
<View style={[styles.container, containerSize, style]}>
|
|
445
|
-
{(showName || hideSource) ? this.renderShortName(name, avatarStyle, size) : <View />}
|
|
558
|
+
{(showName || hideSource) ? this.renderShortName(name, avatarStyle, size, this.color) : <View />}
|
|
446
559
|
{this.isValidImageUrl(imageSource) && !hideSource
|
|
447
560
|
? (
|
|
448
561
|
<Image
|
|
449
562
|
cached={cached}
|
|
450
563
|
loading={loading || isShowLoading}
|
|
451
564
|
source={imageSource}
|
|
452
|
-
onError={this.onLoadSourceError}
|
|
565
|
+
onError={() => this.onLoadSourceError(imageSource)}
|
|
453
566
|
style={avatarStyle}
|
|
454
567
|
resizeMode={resizeMode}
|
|
455
568
|
{...extraPropsImage}
|
|
@@ -472,6 +585,7 @@ export default class Avatar extends Component {
|
|
|
472
585
|
Avatar.propTypes = {
|
|
473
586
|
name: PropTypes.string,
|
|
474
587
|
resizeMode: PropTypes.string,
|
|
588
|
+
quality: PropTypes.oneOf(['low', 'medium', 'high']),
|
|
475
589
|
size: PropTypes.oneOf(['tiny', 'small', 'medium', 'large', 'giant', 'size8', 'size24', 'size36', 'size44', 'size48', 'size52', 'size56', 'size64', 'size72', 'size80', 'size88', 'size96',
|
|
476
590
|
PropTypes.shape({
|
|
477
591
|
width: PropTypes.number, height: PropTypes.number, borderRadius: PropTypes.number
|
|
@@ -483,10 +597,15 @@ Avatar.propTypes = {
|
|
|
483
597
|
onPress: PropTypes.func,
|
|
484
598
|
loading: PropTypes.bool,
|
|
485
599
|
cached: PropTypes.bool,
|
|
486
|
-
|
|
600
|
+
scaleSize: PropTypes.bool,
|
|
601
|
+
extraPropsImage: PropTypes.object,
|
|
602
|
+
number: PropTypes.string
|
|
487
603
|
};
|
|
488
604
|
|
|
489
605
|
Avatar.defaultProps = {
|
|
490
606
|
resizeMode: 'cover',
|
|
491
|
-
cached: true
|
|
607
|
+
cached: true,
|
|
608
|
+
scaleSize: false,
|
|
609
|
+
quality: 'medium',
|
|
610
|
+
size: 'small'
|
|
492
611
|
};
|
package/Avatar.web.js
CHANGED
|
@@ -2,14 +2,20 @@
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import React, { Component } from 'react';
|
|
4
4
|
import {
|
|
5
|
-
View, StyleSheet, TouchableOpacity, Image
|
|
5
|
+
View, StyleSheet, TouchableOpacity, Image, Dimensions
|
|
6
6
|
} from 'react-native';
|
|
7
7
|
import { get, isEqual } from 'lodash';
|
|
8
|
-
import
|
|
9
|
-
import Colors from '../../colors';
|
|
10
|
-
import { Icons } from '../../icons';
|
|
11
|
-
import Text from '
|
|
12
|
-
import {
|
|
8
|
+
import ValueUtil from '../../core/utils/ValueUtil';
|
|
9
|
+
import Colors from '../../core/colors';
|
|
10
|
+
import { Icons as IconSource } from '../../core/icons';
|
|
11
|
+
import Text from '../../core/components/typography';
|
|
12
|
+
import { RFValueHorizontal as ScaleSize } from '../../core/components/typography/reponsiveSize';
|
|
13
|
+
|
|
14
|
+
export const AvatarQuality = {
|
|
15
|
+
low: 'low',
|
|
16
|
+
medium: 'medium',
|
|
17
|
+
high: 'high',
|
|
18
|
+
};
|
|
13
19
|
|
|
14
20
|
export const AvatarSize = {
|
|
15
21
|
tiny: 'tiny',
|
|
@@ -78,7 +84,7 @@ const styles = StyleSheet.create({
|
|
|
78
84
|
}
|
|
79
85
|
});
|
|
80
86
|
|
|
81
|
-
const subIconSize =
|
|
87
|
+
const subIconSize = (width) => ({
|
|
82
88
|
tiny: {
|
|
83
89
|
width: 8,
|
|
84
90
|
height: 8,
|
|
@@ -178,7 +184,7 @@ const subIconSize = StyleSheet.create({
|
|
|
178
184
|
}
|
|
179
185
|
});
|
|
180
186
|
|
|
181
|
-
const avatarSize =
|
|
187
|
+
const avatarSize = (width) => ({
|
|
182
188
|
tiny: {
|
|
183
189
|
width: 16,
|
|
184
190
|
height: 16,
|
|
@@ -266,21 +272,21 @@ const avatarSize = StyleSheet.create({
|
|
|
266
272
|
}
|
|
267
273
|
});
|
|
268
274
|
|
|
269
|
-
const shortName =
|
|
275
|
+
const shortName = (width) => ({
|
|
270
276
|
tiny: {
|
|
271
|
-
fontSize: 5
|
|
277
|
+
fontSize: ScaleSize(5, width)
|
|
272
278
|
},
|
|
273
279
|
small: {
|
|
274
|
-
fontSize: 11
|
|
280
|
+
fontSize: ScaleSize(11, width)
|
|
275
281
|
},
|
|
276
282
|
medium: {
|
|
277
|
-
fontSize: 15
|
|
283
|
+
fontSize: ScaleSize(15, width)
|
|
278
284
|
},
|
|
279
285
|
large: {
|
|
280
|
-
fontSize: 20
|
|
286
|
+
fontSize: ScaleSize(20, width)
|
|
281
287
|
},
|
|
282
288
|
giant: {
|
|
283
|
-
fontSize: 25
|
|
289
|
+
fontSize: ScaleSize(25, width)
|
|
284
290
|
}
|
|
285
291
|
});
|
|
286
292
|
|
|
@@ -290,10 +296,32 @@ export default class Avatar extends Component {
|
|
|
290
296
|
this.state = {
|
|
291
297
|
hideSource: false,
|
|
292
298
|
ownUpdate: false,
|
|
293
|
-
source: props.source
|
|
299
|
+
source: props.source,
|
|
300
|
+
dimensions: {}
|
|
294
301
|
};
|
|
295
302
|
}
|
|
296
303
|
|
|
304
|
+
componentDidMount() {
|
|
305
|
+
const { scaleSize } = this.props;
|
|
306
|
+
if (scaleSize) {
|
|
307
|
+
this.subscription = Dimensions.addEventListener(
|
|
308
|
+
'change',
|
|
309
|
+
({ window }) => {
|
|
310
|
+
if(window?.height > 0 && window?.width > 0) {
|
|
311
|
+
this.setState({ dimensions: window });
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
componentWillUnmount() {
|
|
319
|
+
const { scaleSize } = this.props;
|
|
320
|
+
if (scaleSize) {
|
|
321
|
+
this.subscription?.remove?.();
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
297
325
|
static getDerivedStateFromProps(nextProps, prevState) {
|
|
298
326
|
if (prevState.ownUpdate) {
|
|
299
327
|
return {
|
|
@@ -336,49 +364,66 @@ export default class Avatar extends Component {
|
|
|
336
364
|
}
|
|
337
365
|
|
|
338
366
|
isValidImageUrl = (source) => {
|
|
339
|
-
const validSource = source &&
|
|
367
|
+
const validSource = source && source.uri && this.isUrl(source.uri);
|
|
340
368
|
return validSource;
|
|
341
369
|
}
|
|
342
370
|
|
|
371
|
+
mapAvatarQuality = (url, quality) => {
|
|
372
|
+
if (!quality || quality === AvatarQuality.medium) {
|
|
373
|
+
return url;
|
|
374
|
+
}
|
|
375
|
+
if (quality === AvatarQuality.low) {
|
|
376
|
+
return url.replace('.png', '_s64.png');
|
|
377
|
+
}
|
|
378
|
+
if (quality === AvatarQuality.high) {
|
|
379
|
+
return url.replace('.png', '_s512.png');
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
return url;
|
|
383
|
+
}
|
|
384
|
+
|
|
343
385
|
mapStyleFromSize = (size) => {
|
|
344
|
-
const
|
|
386
|
+
const { dimensions } = this.state;
|
|
387
|
+
const avatarStyle = avatarSize(dimensions?.width || null).small;
|
|
345
388
|
if (typeof size === 'object') return size;
|
|
346
|
-
if (avatarSize[size]) return avatarSize[size];
|
|
389
|
+
if (avatarSize(dimensions?.width || null)[size]) return avatarSize(dimensions?.width || null)[size];
|
|
347
390
|
return avatarStyle;
|
|
348
391
|
}
|
|
349
392
|
|
|
350
393
|
mapShortNameStyle = (size) => {
|
|
351
394
|
let shortNameStyle = {};
|
|
395
|
+
const { dimensions } = this.state;
|
|
352
396
|
switch (size) {
|
|
353
397
|
case AvatarSize.tiny: {
|
|
354
|
-
shortNameStyle = shortName.tiny;
|
|
398
|
+
shortNameStyle = shortName(dimensions?.width || null).tiny;
|
|
355
399
|
break;
|
|
356
400
|
}
|
|
357
401
|
case AvatarSize.small: {
|
|
358
|
-
shortNameStyle = shortName.small;
|
|
402
|
+
shortNameStyle = shortName(dimensions?.width || null).small;
|
|
359
403
|
break;
|
|
360
404
|
}
|
|
361
405
|
case AvatarSize.medium: {
|
|
362
|
-
shortNameStyle = shortName.medium;
|
|
406
|
+
shortNameStyle = shortName(dimensions?.width || null).medium;
|
|
363
407
|
break;
|
|
364
408
|
}
|
|
365
409
|
case AvatarSize.large: {
|
|
366
|
-
shortNameStyle = shortName.large;
|
|
410
|
+
shortNameStyle = shortName(dimensions?.width || null).large;
|
|
367
411
|
break;
|
|
368
412
|
}
|
|
369
413
|
case AvatarSize.giant: {
|
|
370
|
-
shortNameStyle = shortName.giant;
|
|
414
|
+
shortNameStyle = shortName(dimensions?.width || null).giant;
|
|
371
415
|
break;
|
|
372
416
|
}
|
|
373
417
|
default:
|
|
374
|
-
shortNameStyle = shortName.small;
|
|
418
|
+
shortNameStyle = shortName(dimensions?.width || null).small;
|
|
375
419
|
}
|
|
376
420
|
return shortNameStyle;
|
|
377
421
|
}
|
|
378
422
|
|
|
379
423
|
mapSubIconSize = (size) => {
|
|
380
|
-
const
|
|
381
|
-
|
|
424
|
+
const { dimensions } = this.state;
|
|
425
|
+
const subIconStyle = subIconSize(dimensions?.width || null).small;
|
|
426
|
+
if (subIconSize(dimensions?.width || null)[size]) return subIconSize(dimensions?.width || null)[size];
|
|
382
427
|
return subIconStyle;
|
|
383
428
|
}
|
|
384
429
|
|
|
@@ -391,7 +436,7 @@ export default class Avatar extends Component {
|
|
|
391
436
|
height: containerWidth,
|
|
392
437
|
borderRadius: containerWidth / 2,
|
|
393
438
|
borderWidth,
|
|
394
|
-
borderColor:
|
|
439
|
+
borderColor: Colors.black_01
|
|
395
440
|
};
|
|
396
441
|
}
|
|
397
442
|
|
|
@@ -403,14 +448,14 @@ export default class Avatar extends Component {
|
|
|
403
448
|
const { subIcon, size, subIconSource } = this.props;
|
|
404
449
|
if ((!subIcon || subIcon === SubIconType.none) && !subIconSource) return <View />;
|
|
405
450
|
const subIconSizeStyle = this.mapSubIconSize(size);
|
|
406
|
-
const iconSource =
|
|
451
|
+
const iconSource = ValueUtil.getImageSource(subIconSource);
|
|
407
452
|
return (
|
|
408
453
|
<View style={styles.subIcon}>
|
|
409
454
|
{subIcon === SubIconType.momo
|
|
410
455
|
? (
|
|
411
456
|
<Image
|
|
412
457
|
style={[styles.subIconImage, subIconSizeStyle]}
|
|
413
|
-
source={
|
|
458
|
+
source={IconSource.ic_round_momo_tiny}
|
|
414
459
|
/>
|
|
415
460
|
)
|
|
416
461
|
: <View />}
|
|
@@ -435,16 +480,27 @@ export default class Avatar extends Component {
|
|
|
435
480
|
|
|
436
481
|
render() {
|
|
437
482
|
const {
|
|
438
|
-
size, source, name, resizeMode, style, onPress, isShowLoading, loading, cached, extraPropsImage
|
|
483
|
+
size, source, name, resizeMode, style, onPress, isShowLoading, loading, cached, extraPropsImage, quality
|
|
439
484
|
} = this.props;
|
|
440
485
|
const { hideSource } = this.state;
|
|
441
486
|
const avatarStyle = this.mapStyleFromSize(size);
|
|
442
487
|
const containerSize = this.extractSize(avatarStyle);
|
|
443
|
-
const imageSource =
|
|
488
|
+
const imageSource = ValueUtil.getImageSource(source);
|
|
444
489
|
const showName = typeof imageSource === 'object' && Object.keys(imageSource).length === 0 && typeof imageSource !== 'number';
|
|
490
|
+
// add priority high for avatar
|
|
491
|
+
if (imageSource?.uri) {
|
|
492
|
+
imageSource.priority = 'high';
|
|
493
|
+
imageSource.uri = this.mapAvatarQuality(imageSource.uri, quality);
|
|
494
|
+
// if doest not have time query, set default cache time to 1 day
|
|
495
|
+
if (!imageSource.uri?.includes('?') && cached) {
|
|
496
|
+
const midnight = new Date().setHours(0, 0, 0, 0);
|
|
497
|
+
imageSource.uri = `${imageSource.uri}?time=${midnight}`;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
445
501
|
const inner = (
|
|
446
|
-
<View style={[styles.container,
|
|
447
|
-
{(showName || hideSource) ? this.renderShortName(name, avatarStyle, size) :
|
|
502
|
+
<View style={[styles.container, containerSize, style]}>
|
|
503
|
+
{(showName || hideSource) ? this.renderShortName(name, avatarStyle, size) : <View />}
|
|
448
504
|
{this.isValidImageUrl(imageSource) && !hideSource
|
|
449
505
|
? (
|
|
450
506
|
<Image
|
|
@@ -472,54 +528,27 @@ export default class Avatar extends Component {
|
|
|
472
528
|
}
|
|
473
529
|
|
|
474
530
|
Avatar.propTypes = {
|
|
475
|
-
/**
|
|
476
|
-
* The default name when image load fail.
|
|
477
|
-
*/
|
|
478
531
|
name: PropTypes.string,
|
|
479
|
-
/**
|
|
480
|
-
* How resize should the avatar be?
|
|
481
|
-
*/
|
|
482
532
|
resizeMode: PropTypes.string,
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
* What source Avatar to use?
|
|
489
|
-
*/
|
|
533
|
+
quality: PropTypes.oneOf(['low', 'medium', 'high']),
|
|
534
|
+
size: PropTypes.oneOf(['tiny', 'small', 'medium', 'large', 'giant', 'size8', 'size24', 'size36', 'size44', 'size48', 'size52', 'size56', 'size64', 'size72', 'size80', 'size88', 'size96',
|
|
535
|
+
PropTypes.shape({
|
|
536
|
+
width: PropTypes.number, height: PropTypes.number, borderRadius: PropTypes.number
|
|
537
|
+
})]),
|
|
490
538
|
source: PropTypes.oneOfType([PropTypes.shape({ uri: PropTypes.string }), PropTypes.number, PropTypes.string]),
|
|
491
|
-
/**
|
|
492
|
-
* What subIcon Avatar to use?
|
|
493
|
-
*/
|
|
494
539
|
subIcon: PropTypes.oneOf(['momo', 'online', 'key', 'none']),
|
|
495
|
-
/**
|
|
496
|
-
* What custom subIcon Avatar to use?
|
|
497
|
-
*/
|
|
498
540
|
subIconSource: PropTypes.oneOfType([PropTypes.shape({ uri: PropTypes.string }), PropTypes.number, PropTypes.string]),
|
|
499
|
-
/**
|
|
500
|
-
* What custom style Avatar to use?
|
|
501
|
-
*/
|
|
502
541
|
style: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
|
|
503
|
-
/**
|
|
504
|
-
* Optional click handler.
|
|
505
|
-
*/
|
|
506
542
|
onPress: PropTypes.func,
|
|
507
|
-
/**
|
|
508
|
-
* Optional loading handler.
|
|
509
|
-
*/
|
|
510
543
|
loading: PropTypes.bool,
|
|
511
|
-
/**
|
|
512
|
-
* Optional cached handler.
|
|
513
|
-
*/
|
|
514
544
|
cached: PropTypes.bool,
|
|
515
|
-
|
|
516
|
-
* Optional extra prop of Image.
|
|
517
|
-
*/
|
|
545
|
+
scaleSize: PropTypes.bool,
|
|
518
546
|
extraPropsImage: PropTypes.object
|
|
519
547
|
};
|
|
520
548
|
|
|
521
549
|
Avatar.defaultProps = {
|
|
522
550
|
resizeMode: 'cover',
|
|
523
|
-
|
|
524
|
-
|
|
551
|
+
cached: true,
|
|
552
|
+
scaleSize: false,
|
|
553
|
+
quality: 'medium',
|
|
525
554
|
};
|
package/package.json
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
2
|
+
"name": "@momo-kits/avatar",
|
|
3
|
+
"version": "0.0.7",
|
|
4
|
+
"private": false,
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"dependencies": {},
|
|
7
|
+
"peerDependencies": {
|
|
8
|
+
"react-native": ">=0.55",
|
|
9
|
+
"prop-types": "^15.7.2",
|
|
10
|
+
"react": "16.9.0",
|
|
11
|
+
"@momo-kits/core": ">=0.0.5-beta",
|
|
12
|
+
"lodash": "^4.17.15"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {},
|
|
15
|
+
"license": "MoMo"
|
|
16
|
+
}
|