@momo-kits/avatar 0.0.64-beta → 0.0.65-alpha.8

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.
Files changed (4) hide show
  1. package/Avatar.js +264 -115
  2. package/Avatar.web.js +37 -1
  3. package/package.json +14 -14
  4. package/publish.sh +2 -2
package/Avatar.js CHANGED
@@ -2,11 +2,20 @@
2
2
  import PropTypes from 'prop-types';
3
3
  import React, { Component } from 'react';
4
4
  import {
5
- View, StyleSheet, TouchableOpacity, Dimensions
5
+ View,
6
+ StyleSheet,
7
+ TouchableOpacity,
8
+ Dimensions,
9
+ Platform,
6
10
  } from 'react-native';
7
11
  import { get, isEqual } from 'lodash';
8
12
  import {
9
- ValueUtil, Colors, Text, IconSource, Image, ScaleSize
13
+ ValueUtil,
14
+ Colors,
15
+ Text,
16
+ IconSource,
17
+ Image,
18
+ ScaleSize,
10
19
  } from '@momo-kits/core';
11
20
 
12
21
  export const AvatarQuality = {
@@ -32,20 +41,43 @@ export const AvatarSize = {
32
41
  size72: 'size72',
33
42
  size80: 'size80',
34
43
  size88: 'size88',
35
- size96: 'size96'
44
+ size96: 'size96',
36
45
  };
37
46
 
47
+ const COLORS = [
48
+ '#3683f3',
49
+ '#ea63af',
50
+ '#f94889',
51
+ '#82b6da',
52
+ '#2fc093',
53
+ '#7b4a41',
54
+ '#ff97bc',
55
+ '#4130d7',
56
+ '#c3c3c3',
57
+ '#f7ae2f',
58
+ '#b04595',
59
+ '#57b748',
60
+ '#ff8900',
61
+ '#7841bf',
62
+ '#be3f3e',
63
+ '#c51515',
64
+ '#8e6472',
65
+ '#fed27d',
66
+ '#ff6f5d',
67
+ '#05b8ae',
68
+ ];
69
+
38
70
  export const SubIconType = {
39
71
  momo: 'momo',
40
72
  online: 'online',
41
73
  key: 'key',
42
- none: 'none'
74
+ none: 'none',
43
75
  };
44
76
 
45
77
  const styles = StyleSheet.create({
46
78
  container: {
47
79
  justifyContent: 'center',
48
- alignItems: 'center'
80
+ alignItems: 'center',
49
81
  },
50
82
  shortNameView: {
51
83
  justifyContent: 'center',
@@ -53,90 +85,93 @@ const styles = StyleSheet.create({
53
85
 
54
86
  backgroundColor: Colors.very_light_pink_four,
55
87
  width: '100%',
56
- height: '100%'
88
+ height: '100%',
57
89
  },
58
90
  shortNameText: {
59
91
  // fontSize: 17,
60
- color: '#f6f6f6'
92
+ color: Colors.pink_03,
93
+ },
94
+ shortNameTextCustom: {
95
+ color: '#f6f6f6',
61
96
  },
62
97
  absolute: {
63
98
  position: 'absolute',
64
99
  top: 0,
65
100
  left: 0,
66
101
  right: 0,
67
- bottom: 0
102
+ bottom: 0,
68
103
  },
69
104
  subIcon: {
70
105
  position: 'absolute',
71
106
  bottom: 0,
72
- right: 0
107
+ right: 0,
73
108
  },
74
109
  subIconImage: {
75
110
  width: 22,
76
- height: 22
111
+ height: 22,
77
112
  },
78
113
  subIconImageOnline: {
79
114
  backgroundColor: Colors.kiwi_green,
80
115
  borderColor: 'white',
81
- borderWidth: 1
82
- }
116
+ borderWidth: 1,
117
+ },
83
118
  });
84
119
 
85
120
  const subIconSize = (width) => ({
86
121
  tiny: {
87
122
  width: 8,
88
123
  height: 8,
89
- borderRadius: 4
124
+ borderRadius: 4,
90
125
  },
91
126
  small: {
92
127
  width: 10,
93
128
  height: 10,
94
- borderRadius: 5
129
+ borderRadius: 5,
95
130
  },
96
131
  medium: {
97
132
  width: 12,
98
133
  height: 12,
99
- borderRadius: 6
134
+ borderRadius: 6,
100
135
  },
101
136
  large: {
102
137
  width: 16,
103
138
  height: 16,
104
- borderRadius: 8
139
+ borderRadius: 8,
105
140
  },
106
141
  size8: {
107
142
  width: 8,
108
143
  height: 8,
109
- borderRadius: 4
144
+ borderRadius: 4,
110
145
  },
111
146
  size24: {
112
147
  width: 10,
113
148
  height: 10,
114
- borderRadius: 5
149
+ borderRadius: 5,
115
150
  },
116
151
  size36: {
117
152
  width: 10,
118
153
  height: 10,
119
- borderRadius: 5
154
+ borderRadius: 5,
120
155
  },
121
156
  size44: {
122
157
  width: 14,
123
158
  height: 14,
124
- borderRadius: 7
159
+ borderRadius: 7,
125
160
  },
126
161
  size48: {
127
162
  width: 14,
128
163
  height: 14,
129
- borderRadius: 7
164
+ borderRadius: 7,
130
165
  },
131
166
  size52: {
132
167
  width: 16,
133
168
  height: 16,
134
- borderRadius: 8
169
+ borderRadius: 8,
135
170
  },
136
171
  size56: {
137
172
  width: 16,
138
173
  height: 16,
139
- borderRadius: 8
174
+ borderRadius: 8,
140
175
  },
141
176
  size64: {
142
177
  width: 16,
@@ -178,125 +213,132 @@ const subIconSize = (width) => ({
178
213
  left: -5,
179
214
  width: 24,
180
215
  height: 24,
181
- borderRadius: 12
182
- }
216
+ borderRadius: 12,
217
+ },
183
218
  });
184
219
 
185
220
  const avatarSize = (width) => ({
186
221
  tiny: {
187
222
  width: 16,
188
223
  height: 16,
189
- borderRadius: 8
224
+ borderRadius: 8,
190
225
  },
191
226
  small: {
192
227
  width: 32,
193
228
  height: 32,
194
- borderRadius: 16
229
+ borderRadius: 16,
195
230
  },
196
231
  medium: {
197
232
  width: 40,
198
233
  height: 40,
199
- borderRadius: 20
234
+ borderRadius: 20,
200
235
  },
201
236
  large: {
202
237
  width: 60,
203
238
  height: 60,
204
- borderRadius: 30
239
+ borderRadius: 30,
205
240
  },
206
241
  giant: {
207
242
  width: 120,
208
243
  height: 120,
209
- borderRadius: 60
244
+ borderRadius: 60,
210
245
  },
211
246
  size8: {
212
247
  width: 8,
213
248
  height: 8,
214
- borderRadius: 4
249
+ borderRadius: 4,
215
250
  },
216
251
  size24: {
217
252
  width: 24,
218
253
  height: 24,
219
- borderRadius: 12
254
+ borderRadius: 12,
220
255
  },
221
256
  size36: {
222
257
  width: 36,
223
258
  height: 36,
224
- borderRadius: 18
259
+ borderRadius: 18,
225
260
  },
226
261
  size44: {
227
262
  width: 44,
228
263
  height: 44,
229
- borderRadius: 22
264
+ borderRadius: 22,
230
265
  },
231
266
  size48: {
232
267
  width: 48,
233
268
  height: 48,
234
- borderRadius: 24
269
+ borderRadius: 24,
235
270
  },
236
271
  size52: {
237
272
  width: 52,
238
273
  height: 52,
239
- borderRadius: 26
274
+ borderRadius: 26,
240
275
  },
241
276
  size56: {
242
277
  width: 56,
243
278
  height: 56,
244
- borderRadius: 28
279
+ borderRadius: 28,
245
280
  },
246
281
  size64: {
247
282
  width: 64,
248
283
  height: 64,
249
- borderRadius: 32
284
+ borderRadius: 32,
250
285
  },
251
286
  size72: {
252
287
  width: 72,
253
288
  height: 72,
254
- borderRadius: 36
289
+ borderRadius: 36,
255
290
  },
256
291
  size80: {
257
292
  width: 80,
258
293
  height: 80,
259
- borderRadius: 40
294
+ borderRadius: 40,
260
295
  },
261
296
  size88: {
262
297
  width: 88,
263
298
  height: 88,
264
- borderRadius: 44
299
+ borderRadius: 44,
265
300
  },
266
301
  size96: {
267
302
  width: 96,
268
303
  height: 96,
269
- borderRadius: 48
270
- }
304
+ borderRadius: 48,
305
+ },
271
306
  });
272
307
 
273
308
  const shortName = (width) => ({
274
309
  tiny: {
275
- fontSize: ScaleSize(5, width)
310
+ fontSize: ScaleSize(5, width),
276
311
  },
277
312
  small: {
278
- fontSize: ScaleSize(11, width)
313
+ fontSize: ScaleSize(11, width),
279
314
  },
280
315
  medium: {
281
- fontSize: ScaleSize(15, width)
316
+ fontSize: ScaleSize(15, width),
317
+ },
318
+ middle: {
319
+ fontSize: ScaleSize(16, width),
282
320
  },
283
321
  large: {
284
- fontSize: ScaleSize(20, width)
322
+ fontSize: ScaleSize(20, width),
285
323
  },
286
324
  giant: {
287
- fontSize: ScaleSize(25, width)
288
- }
325
+ fontSize: ScaleSize(25, width),
326
+ },
289
327
  });
290
328
 
291
329
  export default class Avatar extends Component {
292
330
  constructor(props) {
293
331
  super(props);
332
+ this.color = props.custom
333
+ ? this.getAvatarColor(props.name)
334
+ : Colors.pink_10;
294
335
  this.state = {
295
336
  hideSource: false,
296
337
  ownUpdate: false,
297
338
  source: props.source,
298
- dimensions: {}
339
+ dimensions: {},
299
340
  };
341
+ this.imageSource = '';
300
342
  }
301
343
 
302
344
  componentDidMount() {
@@ -305,8 +347,14 @@ export default class Avatar extends Component {
305
347
  this.subscription = Dimensions.addEventListener(
306
348
  'change',
307
349
  ({ window }) => {
308
- this.setState({ dimensions: window });
309
- }
350
+ if (
351
+ window?.height > 0 &&
352
+ window?.width > 0 &&
353
+ Platform.OS === 'android'
354
+ ) {
355
+ this.setState({ dimensions: window });
356
+ }
357
+ },
310
358
  );
311
359
  }
312
360
  }
@@ -323,7 +371,8 @@ export default class Avatar extends Component {
323
371
  return {
324
372
  ownUpdate: false,
325
373
  };
326
- } if (!isEqual(nextProps.source, prevState.source)) {
374
+ }
375
+ if (!isEqual(nextProps.source, prevState.source)) {
327
376
  return { source: nextProps.source, hideSource: false };
328
377
  }
329
378
  return null;
@@ -339,30 +388,56 @@ export default class Avatar extends Component {
339
388
  }
340
389
  });
341
390
  return alphabet.join('');
391
+ };
392
+
393
+ hashUrl(url) {
394
+ let hash = 0;
395
+ let char;
396
+ if (url?.length === 0) return hash;
397
+ for (let i = 0; i < url?.length; i++) {
398
+ char = url?.charCodeAt(i);
399
+ hash = (hash << 5) - hash + char;
400
+ hash &= hash; // Convert to 32bit integer
401
+ }
402
+ return hash;
342
403
  }
343
404
 
344
- renderShortName = (name, avatarStyle, size) => {
405
+ renderShortName = (name, avatarStyle, size, color) => {
345
406
  if (name) {
346
407
  const shortedName = this.getContactShortName(name);
347
408
  const shortNameStyle = this.mapShortNameStyle(size);
348
409
  return (
349
- <View style={[styles.shortNameView, avatarStyle]}>
350
- <Text.H4 style={[styles.shortNameText, shortNameStyle]}>{shortedName}</Text.H4>
410
+ <View
411
+ style={[
412
+ styles.shortNameView,
413
+ avatarStyle,
414
+ { backgroundColor: color },
415
+ ]}>
416
+ <Text.H4
417
+ style={[
418
+ this.props.custom
419
+ ? styles.shortNameTextCustom
420
+ : styles.shortNameText,
421
+ shortNameStyle,
422
+ ]}>
423
+ {shortedName}
424
+ </Text.H4>
351
425
  </View>
352
426
  );
353
427
  }
354
428
  return <View />;
355
- }
429
+ };
356
430
 
357
431
  isUrl(url) {
358
- const expression = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-/]))?/gi;
432
+ const expression =
433
+ /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-/]))?/gi;
359
434
  return expression.test(url);
360
435
  }
361
436
 
362
437
  isValidImageUrl = (source) => {
363
438
  const validSource = source && source.uri && this.isUrl(source.uri);
364
439
  return validSource;
365
- }
440
+ };
366
441
 
367
442
  mapAvatarQuality = (url, quality) => {
368
443
  if (!quality || quality === AvatarQuality.medium) {
@@ -376,52 +451,78 @@ export default class Avatar extends Component {
376
451
  }
377
452
 
378
453
  return url;
379
- }
454
+ };
380
455
 
381
456
  mapStyleFromSize = (size) => {
382
457
  const { dimensions } = this.state;
383
- const avatarStyle = avatarSize(dimensions?.width || null).small;
458
+ const avatarStyle = avatarSize(
459
+ dimensions?.width > 0 ? dimensions?.width : null,
460
+ ).small;
384
461
  if (typeof size === 'object') return size;
385
- if (avatarSize(dimensions?.width || null)[size]) return avatarSize(dimensions?.width || null)[size];
462
+ if (avatarSize(dimensions?.width > 0 ? dimensions?.width : null)[size])
463
+ return avatarSize(dimensions?.width > 0 ? dimensions?.width : null)[
464
+ size
465
+ ];
386
466
  return avatarStyle;
387
- }
467
+ };
388
468
 
389
469
  mapShortNameStyle = (size) => {
390
470
  let shortNameStyle = {};
391
471
  const { dimensions } = this.state;
392
472
  switch (size) {
393
473
  case AvatarSize.tiny: {
394
- shortNameStyle = shortName(dimensions?.width || null).tiny;
474
+ shortNameStyle = shortName(
475
+ dimensions?.width > 0 ? dimensions?.width : null,
476
+ ).tiny;
395
477
  break;
396
478
  }
397
479
  case AvatarSize.small: {
398
- shortNameStyle = shortName(dimensions?.width || null).small;
480
+ shortNameStyle = shortName(
481
+ dimensions?.width > 0 ? dimensions?.width : null,
482
+ ).small;
399
483
  break;
400
484
  }
401
485
  case AvatarSize.medium: {
402
- shortNameStyle = shortName(dimensions?.width || null).medium;
486
+ shortNameStyle = shortName(
487
+ dimensions?.width > 0 ? dimensions?.width : null,
488
+ ).medium;
489
+ break;
490
+ }
491
+ case AvatarSize.size48: {
492
+ shortNameStyle = shortName(dimensions?.width || null).middle;
403
493
  break;
404
494
  }
405
495
  case AvatarSize.large: {
406
- shortNameStyle = shortName(dimensions?.width || null).large;
496
+ shortNameStyle = shortName(
497
+ dimensions?.width > 0 ? dimensions?.width : null,
498
+ ).large;
407
499
  break;
408
500
  }
409
501
  case AvatarSize.giant: {
410
- shortNameStyle = shortName(dimensions?.width || null).giant;
502
+ shortNameStyle = shortName(
503
+ dimensions?.width > 0 ? dimensions?.width : null,
504
+ ).giant;
411
505
  break;
412
506
  }
413
507
  default:
414
- shortNameStyle = shortName(dimensions?.width || null).small;
508
+ shortNameStyle = shortName(
509
+ dimensions?.width > 0 ? dimensions?.width : null,
510
+ ).small;
415
511
  }
416
512
  return shortNameStyle;
417
- }
513
+ };
418
514
 
419
515
  mapSubIconSize = (size) => {
420
516
  const { dimensions } = this.state;
421
- const subIconStyle = subIconSize(dimensions?.width || null).small;
422
- if (subIconSize(dimensions?.width || null)[size]) return subIconSize(dimensions?.width || null)[size];
517
+ const subIconStyle = subIconSize(
518
+ dimensions?.width > 0 ? dimensions?.width : null,
519
+ ).small;
520
+ if (subIconSize(dimensions?.width > 0 ? dimensions?.width : null)[size])
521
+ return subIconSize(
522
+ dimensions?.width > 0 ? dimensions?.width : null,
523
+ )[size];
423
524
  return subIconStyle;
424
- }
525
+ };
425
526
 
426
527
  extractSize = (avatarStyle) => {
427
528
  const { style } = this.props;
@@ -432,57 +533,89 @@ export default class Avatar extends Component {
432
533
  height: containerWidth,
433
534
  borderRadius: containerWidth / 2,
434
535
  borderWidth,
435
- borderColor: Colors.black_01
536
+ borderColor: Colors.black_01,
436
537
  };
437
- }
538
+ };
438
539
 
439
- onLoadSourceError = () => {
440
- this.setState({ hideSource: true, ownUpdate: true });
441
- }
540
+ onLoadSourceError = (imageSource) => {
541
+ if (this.imageSource?.uri !== imageSource?.uri) {
542
+ this.imageSource = imageSource;
543
+ this.setState({ hideSource: true, ownUpdate: true });
544
+ }
545
+ };
442
546
 
443
547
  renderSubIcon = () => {
444
548
  const { subIcon, size, subIconSource } = this.props;
445
- if ((!subIcon || subIcon === SubIconType.none) && !subIconSource) return <View />;
549
+ if ((!subIcon || subIcon === SubIconType.none) && !subIconSource)
550
+ return <View />;
446
551
  const subIconSizeStyle = this.mapSubIconSize(size);
447
552
  const iconSource = ValueUtil.getImageSource(subIconSource);
448
553
  return (
449
554
  <View style={styles.subIcon}>
450
- {subIcon === SubIconType.momo
451
- ? (
452
- <Image
453
- style={[styles.subIconImage, subIconSizeStyle]}
454
- source={IconSource.ic_round_momo_tiny}
455
- />
456
- )
457
- : <View />}
458
- {subIcon === SubIconType.online
459
- ? <View style={[styles.subIconImageOnline, subIconSizeStyle]} /> : <View />}
555
+ {subIcon === SubIconType.momo ? (
556
+ <Image
557
+ style={[styles.subIconImage, subIconSizeStyle]}
558
+ source={IconSource.ic_round_momo_tiny}
559
+ />
560
+ ) : (
561
+ <View />
562
+ )}
563
+ {subIcon === SubIconType.online ? (
564
+ <View
565
+ style={[styles.subIconImageOnline, subIconSizeStyle]}
566
+ />
567
+ ) : (
568
+ <View />
569
+ )}
460
570
 
461
571
  {iconSource && subIconSource && !subIcon ? (
462
572
  <Image
463
573
  style={[styles.subIconImage, subIconSizeStyle]}
464
574
  source={iconSource}
465
575
  />
466
- )
467
- : <View />}
576
+ ) : (
577
+ <View />
578
+ )}
468
579
  </View>
469
580
  );
581
+ };
582
+
583
+ getAvatarColor(name) {
584
+ const shortName = this.getContactShortName(name);
585
+ if (!shortName) return '#d5d6d6';
586
+ const firstLetter = shortName[0].charCodeAt(0);
587
+ let colorIndex = Number(firstLetter) % 26;
588
+ if (colorIndex > 19) colorIndex = 25 - colorIndex;
589
+ return COLORS[colorIndex];
470
590
  }
471
591
 
472
592
  onPress = () => {
473
593
  const { onPress } = this.props;
474
594
  if (onPress && typeof onPress === 'function') onPress();
475
- }
595
+ };
476
596
 
477
597
  render() {
478
598
  const {
479
- size, source, name, resizeMode, style, onPress, isShowLoading, loading, cached, extraPropsImage, quality
599
+ size,
600
+ source,
601
+ name,
602
+ resizeMode,
603
+ style,
604
+ onPress,
605
+ isShowLoading,
606
+ loading,
607
+ cached,
608
+ extraPropsImage,
609
+ quality,
480
610
  } = this.props;
481
611
  const { hideSource } = this.state;
482
612
  const avatarStyle = this.mapStyleFromSize(size);
483
613
  const containerSize = this.extractSize(avatarStyle);
484
614
  const imageSource = ValueUtil.getImageSource(source);
485
- const showName = typeof imageSource === 'object' && Object.keys(imageSource).length === 0 && typeof imageSource !== 'number';
615
+ const showName =
616
+ typeof imageSource === 'object' &&
617
+ Object.keys(imageSource).length === 0 &&
618
+ typeof imageSource !== 'number';
486
619
  // add priority high for avatar
487
620
  if (imageSource?.uri) {
488
621
  imageSource.priority = 'high';
@@ -496,25 +629,32 @@ export default class Avatar extends Component {
496
629
 
497
630
  const inner = (
498
631
  <View style={[styles.container, containerSize, style]}>
499
- {(showName || hideSource) ? this.renderShortName(name, avatarStyle, size) : <View />}
500
- {this.isValidImageUrl(imageSource) && !hideSource
501
- ? (
502
- <Image
503
- cached={cached}
504
- loading={loading || isShowLoading}
505
- source={imageSource}
506
- onError={this.onLoadSourceError}
507
- style={avatarStyle}
508
- resizeMode={resizeMode}
509
- {...extraPropsImage}
510
- />
511
- ) : <View />}
632
+ {showName || hideSource ? (
633
+ this.renderShortName(name, avatarStyle, size, this.color)
634
+ ) : (
635
+ <View />
636
+ )}
637
+ {this.isValidImageUrl(imageSource) && !hideSource ? (
638
+ <Image
639
+ cached={cached}
640
+ loading={loading || isShowLoading}
641
+ source={imageSource}
642
+ onError={() => this.onLoadSourceError(imageSource)}
643
+ style={avatarStyle}
644
+ resizeMode={resizeMode}
645
+ {...extraPropsImage}
646
+ />
647
+ ) : (
648
+ <View />
649
+ )}
512
650
  {this.renderSubIcon()}
513
651
  </View>
514
652
  );
515
653
  if (onPress) {
516
654
  return (
517
- <TouchableOpacity activeOpacity={onPress ? 0.5 : 1} onPress={this.onPress}>
655
+ <TouchableOpacity
656
+ activeOpacity={onPress ? 0.5 : 1}
657
+ onPress={this.onPress}>
518
658
  {inner}
519
659
  </TouchableOpacity>
520
660
  );
@@ -527,19 +667,26 @@ Avatar.propTypes = {
527
667
  name: PropTypes.string,
528
668
  resizeMode: PropTypes.string,
529
669
  quality: PropTypes.oneOf(['low', 'medium', 'high']),
530
- size: PropTypes.oneOf(['tiny', 'small', 'medium', 'large', 'giant', 'size8', 'size24', 'size36', 'size44', 'size48', 'size52', 'size56', 'size64', 'size72', 'size80', 'size88', 'size96',
531
- PropTypes.shape({
532
- width: PropTypes.number, height: PropTypes.number, borderRadius: PropTypes.number
533
- })]),
534
- source: PropTypes.oneOfType([PropTypes.shape({ uri: PropTypes.string }), PropTypes.number, PropTypes.string]),
670
+ size: PropTypes.any,
671
+ source: PropTypes.oneOfType([
672
+ PropTypes.shape({ uri: PropTypes.string }),
673
+ PropTypes.number,
674
+ PropTypes.string,
675
+ ]),
535
676
  subIcon: PropTypes.oneOf(['momo', 'online', 'key', 'none']),
536
- subIconSource: PropTypes.oneOfType([PropTypes.shape({ uri: PropTypes.string }), PropTypes.number, PropTypes.string]),
677
+ subIconSource: PropTypes.oneOfType([
678
+ PropTypes.shape({ uri: PropTypes.string }),
679
+ PropTypes.number,
680
+ PropTypes.string,
681
+ ]),
537
682
  style: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
538
683
  onPress: PropTypes.func,
539
684
  loading: PropTypes.bool,
540
685
  cached: PropTypes.bool,
541
686
  scaleSize: PropTypes.bool,
542
- extraPropsImage: PropTypes.object
687
+ extraPropsImage: PropTypes.object,
688
+ number: PropTypes.string,
689
+ custom: PropTypes.bool,
543
690
  };
544
691
 
545
692
  Avatar.defaultProps = {
@@ -547,4 +694,6 @@ Avatar.defaultProps = {
547
694
  cached: true,
548
695
  scaleSize: false,
549
696
  quality: 'medium',
697
+ size: 'small',
698
+ custom: false,
550
699
  };
package/Avatar.web.js CHANGED
@@ -17,6 +17,29 @@ export const AvatarQuality = {
17
17
  high: 'high',
18
18
  };
19
19
 
20
+ const COLORS = [
21
+ '#3683f3',
22
+ '#ea63af',
23
+ '#f94889',
24
+ '#82b6da',
25
+ '#2fc093',
26
+ '#7b4a41',
27
+ '#ff97bc',
28
+ '#4130d7',
29
+ '#c3c3c3',
30
+ '#f7ae2f',
31
+ '#b04595',
32
+ '#57b748',
33
+ '#ff8900',
34
+ '#7841bf',
35
+ '#be3f3e',
36
+ '#c51515',
37
+ '#8e6472',
38
+ '#fed27d',
39
+ '#ff6f5d',
40
+ '#05b8ae',
41
+ ];
42
+
20
43
  export const AvatarSize = {
21
44
  tiny: 'tiny',
22
45
  small: 'small',
@@ -293,6 +316,7 @@ const shortName = (width) => ({
293
316
  export default class Avatar extends Component {
294
317
  constructor(props) {
295
318
  super(props);
319
+ this.color = this.getAvatarColor(props.name);
296
320
  this.state = {
297
321
  hideSource: false,
298
322
  ownUpdate: false,
@@ -307,7 +331,9 @@ export default class Avatar extends Component {
307
331
  this.subscription = Dimensions.addEventListener(
308
332
  'change',
309
333
  ({ window }) => {
310
- this.setState({ dimensions: window });
334
+ if(window?.height > 0 && window?.width > 0) {
335
+ this.setState({ dimensions: window });
336
+ }
311
337
  }
312
338
  );
313
339
  }
@@ -438,6 +464,16 @@ export default class Avatar extends Component {
438
464
  };
439
465
  }
440
466
 
467
+ getAvatarColor(name) {
468
+ const shortName = this.getContactShortName(name)
469
+ if (!shortName) return "#d5d6d6"
470
+ const firstLetter = shortName[0].charCodeAt(0)
471
+ let colorIndex = Number(firstLetter) % 26
472
+ if (colorIndex > 19) colorIndex = 25 - colorIndex
473
+ return COLORS[colorIndex]
474
+ }
475
+
476
+
441
477
  onLoadSourceError = () => {
442
478
  this.setState({ hideSource: true, ownUpdate: true });
443
479
  }
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
- "name": "@momo-kits/avatar",
3
- "version": "0.0.64-beta",
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"
2
+ "name": "@momo-kits/avatar",
3
+ "version": "0.0.65-alpha.8",
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
16
  }
package/publish.sh CHANGED
@@ -21,9 +21,9 @@ rsync -r --verbose --exclude '*.mdx' --exclude '*Demo.js' --exclude 'props-type
21
21
  #npm login
22
22
  #publish dist to npm
23
23
  cd dist
24
- npm publish --access=public
24
+ npm publish --tag beta --access=public
25
25
  cd ..
26
26
  rm -rf dist
27
27
 
28
28
 
29
- curl -X POST -H 'Content-Type: application/json' 'https://chat.googleapis.com/v1/spaces/AAAAbP8987c/messages?key=AIzaSyDdI0hCZtE6vySjMm-WEfRq3CPzqKqqsHI&token=UGSFRvk_oYb9uGsAgs31bVvMm6jDkmD8zihGm3eyaQA%3D&threadKey=JoaXTEYaNNkl' -d '{"text": "@momo-kits/avatar new version release: '*"$VERSION"*' https://www.npmjs.com/package/@momo-kits/avatar"}'
29
+ #curl -X POST -H 'Content-Type: application/json' 'https://chat.googleapis.com/v1/spaces/AAAAbP8987c/messages?key=AIzaSyDdI0hCZtE6vySjMm-WEfRq3CPzqKqqsHI&token=UGSFRvk_oYb9uGsAgs31bVvMm6jDkmD8zihGm3eyaQA%3D&threadKey=JoaXTEYaNNkl' -d '{"text": "@momo-kits/avatar new version release: '*"$VERSION"*' https://www.npmjs.com/package/@momo-kits/avatar"}'