@momo-kits/avatar 0.0.48-rc.2 → 0.0.48

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.web.js DELETED
@@ -1,588 +0,0 @@
1
- /* eslint-disable indent */
2
- import PropTypes from 'prop-types';
3
- import React, { Component } from 'react';
4
- import {
5
- View, StyleSheet, TouchableOpacity, Image, Dimensions
6
- } from 'react-native';
7
- import { get, isEqual } from 'lodash';
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
- };
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
-
43
- export const AvatarSize = {
44
- tiny: 'tiny',
45
- small: 'small',
46
- medium: 'medium',
47
- large: 'large',
48
- giant: 'giant',
49
- size8: 'size8',
50
- size24: 'size24',
51
- size36: 'size36',
52
- size44: 'size44',
53
- size48: 'size48',
54
- size52: 'size52',
55
- size56: 'size56',
56
- size64: 'size64',
57
- size72: 'size72',
58
- size80: 'size80',
59
- size88: 'size88',
60
- size96: 'size96'
61
- };
62
-
63
- export const SubIconType = {
64
- momo: 'momo',
65
- online: 'online',
66
- key: 'key',
67
- none: 'none'
68
- };
69
-
70
- const styles = StyleSheet.create({
71
- container: {
72
- justifyContent: 'center',
73
- alignItems: 'center'
74
- },
75
- shortNameView: {
76
- justifyContent: 'center',
77
- alignItems: 'center',
78
-
79
- backgroundColor: Colors.very_light_pink_four,
80
- width: '100%',
81
- height: '100%'
82
- },
83
- shortNameText: {
84
- // fontSize: 17,
85
- color: '#f6f6f6'
86
- },
87
- absolute: {
88
- position: 'absolute',
89
- top: 0,
90
- left: 0,
91
- right: 0,
92
- bottom: 0
93
- },
94
- subIcon: {
95
- position: 'absolute',
96
- bottom: 0,
97
- right: 0
98
- },
99
- subIconImage: {
100
- width: 22,
101
- height: 22
102
- },
103
- subIconImageOnline: {
104
- backgroundColor: Colors.kiwi_green,
105
- borderColor: 'white',
106
- borderWidth: 1
107
- }
108
- });
109
-
110
- const subIconSize = (width) => ({
111
- tiny: {
112
- width: 8,
113
- height: 8,
114
- borderRadius: 4
115
- },
116
- small: {
117
- width: 10,
118
- height: 10,
119
- borderRadius: 5
120
- },
121
- medium: {
122
- width: 12,
123
- height: 12,
124
- borderRadius: 6
125
- },
126
- large: {
127
- width: 16,
128
- height: 16,
129
- borderRadius: 8
130
- },
131
- size8: {
132
- width: 8,
133
- height: 8,
134
- borderRadius: 4
135
- },
136
- size24: {
137
- width: 10,
138
- height: 10,
139
- borderRadius: 5
140
- },
141
- size36: {
142
- width: 10,
143
- height: 10,
144
- borderRadius: 5
145
- },
146
- size44: {
147
- width: 14,
148
- height: 14,
149
- borderRadius: 7
150
- },
151
- size48: {
152
- width: 14,
153
- height: 14,
154
- borderRadius: 7
155
- },
156
- size52: {
157
- width: 16,
158
- height: 16,
159
- borderRadius: 8
160
- },
161
- size56: {
162
- width: 16,
163
- height: 16,
164
- borderRadius: 8
165
- },
166
- size64: {
167
- width: 16,
168
- height: 16,
169
- borderRadius: 8,
170
- top: -2,
171
- left: -2,
172
- },
173
- size72: {
174
- width: 18,
175
- height: 18,
176
- borderRadius: 9,
177
- top: -3,
178
- left: -3,
179
- },
180
- size80: {
181
- width: 18,
182
- height: 18,
183
- borderRadius: 9,
184
- top: -3,
185
- left: -3,
186
- },
187
- size88: {
188
- width: 18,
189
- height: 18,
190
- borderRadius: 9,
191
- top: -4,
192
- left: -4,
193
- },
194
- size96: {
195
- width: 20,
196
- height: 20,
197
- borderRadius: 10,
198
- top: -4,
199
- left: -4,
200
- },
201
- giant: {
202
- top: -5,
203
- left: -5,
204
- width: 24,
205
- height: 24,
206
- borderRadius: 12
207
- }
208
- });
209
-
210
- const avatarSize = (width) => ({
211
- tiny: {
212
- width: 16,
213
- height: 16,
214
- borderRadius: 8
215
- },
216
- small: {
217
- width: 32,
218
- height: 32,
219
- borderRadius: 16
220
- },
221
- medium: {
222
- width: 40,
223
- height: 40,
224
- borderRadius: 20
225
- },
226
- large: {
227
- width: 60,
228
- height: 60,
229
- borderRadius: 30
230
- },
231
- giant: {
232
- width: 120,
233
- height: 120,
234
- borderRadius: 60
235
- },
236
- size8: {
237
- width: 8,
238
- height: 8,
239
- borderRadius: 4
240
- },
241
- size24: {
242
- width: 24,
243
- height: 24,
244
- borderRadius: 12
245
- },
246
- size36: {
247
- width: 36,
248
- height: 36,
249
- borderRadius: 18
250
- },
251
- size44: {
252
- width: 44,
253
- height: 44,
254
- borderRadius: 22
255
- },
256
- size48: {
257
- width: 48,
258
- height: 48,
259
- borderRadius: 24
260
- },
261
- size52: {
262
- width: 52,
263
- height: 52,
264
- borderRadius: 26
265
- },
266
- size56: {
267
- width: 56,
268
- height: 56,
269
- borderRadius: 28
270
- },
271
- size64: {
272
- width: 64,
273
- height: 64,
274
- borderRadius: 32
275
- },
276
- size72: {
277
- width: 72,
278
- height: 72,
279
- borderRadius: 36
280
- },
281
- size80: {
282
- width: 80,
283
- height: 80,
284
- borderRadius: 40
285
- },
286
- size88: {
287
- width: 88,
288
- height: 88,
289
- borderRadius: 44
290
- },
291
- size96: {
292
- width: 96,
293
- height: 96,
294
- borderRadius: 48
295
- }
296
- });
297
-
298
- const shortName = (width) => ({
299
- tiny: {
300
- fontSize: ScaleSize(5, width)
301
- },
302
- small: {
303
- fontSize: ScaleSize(11, width)
304
- },
305
- medium: {
306
- fontSize: ScaleSize(15, width)
307
- },
308
- large: {
309
- fontSize: ScaleSize(20, width)
310
- },
311
- giant: {
312
- fontSize: ScaleSize(25, width)
313
- }
314
- });
315
-
316
- export default class Avatar extends Component {
317
- constructor(props) {
318
- super(props);
319
- this.color = this.getAvatarColor(props.name);
320
- this.state = {
321
- hideSource: false,
322
- ownUpdate: false,
323
- source: props.source,
324
- dimensions: {}
325
- };
326
- }
327
-
328
- componentDidMount() {
329
- const { scaleSize } = this.props;
330
- if (scaleSize) {
331
- this.subscription = Dimensions.addEventListener(
332
- 'change',
333
- ({ window }) => {
334
- if(window?.height > 0 && window?.width > 0) {
335
- this.setState({ dimensions: window });
336
- }
337
- }
338
- );
339
- }
340
- }
341
-
342
- componentWillUnmount() {
343
- const { scaleSize } = this.props;
344
- if (scaleSize) {
345
- this.subscription?.remove?.();
346
- }
347
- }
348
-
349
- static getDerivedStateFromProps(nextProps, prevState) {
350
- if (prevState.ownUpdate) {
351
- return {
352
- ownUpdate: false,
353
- };
354
- } if (!isEqual(nextProps.source, prevState.source)) {
355
- return { source: nextProps.source, hideSource: false };
356
- }
357
- return null;
358
- }
359
-
360
- getContactShortName = (name) => {
361
- if (!name) return '';
362
- const shortNameList = name.split(' ', 2);
363
- const alphabet = [];
364
- shortNameList.forEach((n) => {
365
- if (n && n.length > 0) {
366
- alphabet.push(n[0].toString().toUpperCase());
367
- }
368
- });
369
- return alphabet.join('');
370
- }
371
-
372
- renderShortName = (name, avatarStyle, size) => {
373
- if (name) {
374
- const shortedName = this.getContactShortName(name);
375
- const shortNameStyle = this.mapShortNameStyle(size);
376
- return (
377
- <View style={[styles.shortNameView, avatarStyle]}>
378
- <Text.H4 style={[styles.shortNameText, shortNameStyle]}>{shortedName}</Text.H4>
379
- </View>
380
- );
381
- }
382
- return <View />;
383
- }
384
-
385
- isUrl(url) {
386
- const expression = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-/]))?/gi;
387
- return expression.test(url);
388
- }
389
-
390
- isValidImageUrl = (source) => {
391
- const validSource = source && source.uri && this.isUrl(source.uri);
392
- return validSource;
393
- }
394
-
395
- mapAvatarQuality = (url, quality) => {
396
- if (!quality || quality === AvatarQuality.medium) {
397
- return url;
398
- }
399
- if (quality === AvatarQuality.low) {
400
- return url.replace('.png', '_s64.png');
401
- }
402
- if (quality === AvatarQuality.high) {
403
- return url.replace('.png', '_s512.png');
404
- }
405
-
406
- return url;
407
- }
408
-
409
- mapStyleFromSize = (size) => {
410
- const { dimensions } = this.state;
411
- const avatarStyle = avatarSize(dimensions?.width || null).small;
412
- if (typeof size === 'object') return size;
413
- if (avatarSize(dimensions?.width || null)[size]) return avatarSize(dimensions?.width || null)[size];
414
- return avatarStyle;
415
- }
416
-
417
- mapShortNameStyle = (size) => {
418
- let shortNameStyle = {};
419
- const { dimensions } = this.state;
420
- switch (size) {
421
- case AvatarSize.tiny: {
422
- shortNameStyle = shortName(dimensions?.width || null).tiny;
423
- break;
424
- }
425
- case AvatarSize.small: {
426
- shortNameStyle = shortName(dimensions?.width || null).small;
427
- break;
428
- }
429
- case AvatarSize.medium: {
430
- shortNameStyle = shortName(dimensions?.width || null).medium;
431
- break;
432
- }
433
- case AvatarSize.large: {
434
- shortNameStyle = shortName(dimensions?.width || null).large;
435
- break;
436
- }
437
- case AvatarSize.giant: {
438
- shortNameStyle = shortName(dimensions?.width || null).giant;
439
- break;
440
- }
441
- default:
442
- shortNameStyle = shortName(dimensions?.width || null).small;
443
- }
444
- return shortNameStyle;
445
- }
446
-
447
- mapSubIconSize = (size) => {
448
- const { dimensions } = this.state;
449
- const subIconStyle = subIconSize(dimensions?.width || null).small;
450
- if (subIconSize(dimensions?.width || null)[size]) return subIconSize(dimensions?.width || null)[size];
451
- return subIconStyle;
452
- }
453
-
454
- extractSize = (avatarStyle) => {
455
- const { style } = this.props;
456
- const borderWidth = get(style, 'borderWidth', 1);
457
- const containerWidth = Math.round(avatarStyle.width + 2 + borderWidth);
458
- return {
459
- width: containerWidth,
460
- height: containerWidth,
461
- borderRadius: containerWidth / 2,
462
- borderWidth,
463
- borderColor: Colors.black_01
464
- };
465
- }
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
-
477
- onLoadSourceError = () => {
478
- this.setState({ hideSource: true, ownUpdate: true });
479
- }
480
-
481
- renderSubIcon = () => {
482
- const { subIcon, size, subIconSource } = this.props;
483
- if ((!subIcon || subIcon === SubIconType.none) && !subIconSource) return <View />;
484
- const subIconSizeStyle = this.mapSubIconSize(size);
485
- const iconSource = ValueUtil.getImageSource(subIconSource);
486
- return (
487
- <View style={styles.subIcon}>
488
- {subIcon === SubIconType.momo
489
- ? (
490
- <Image
491
- style={[styles.subIconImage, subIconSizeStyle]}
492
- source={IconSource.ic_round_momo_tiny}
493
- />
494
- )
495
- : <View />}
496
- {subIcon === SubIconType.online
497
- ? <View style={[styles.subIconImageOnline, subIconSizeStyle]} /> : <View />}
498
-
499
- {iconSource && subIconSource && !subIcon ? (
500
- <Image
501
- style={[styles.subIconImage, subIconSizeStyle]}
502
- source={iconSource}
503
- />
504
- )
505
- : <View />}
506
- </View>
507
- );
508
- }
509
-
510
- onPress = () => {
511
- const { onPress } = this.props;
512
- if (onPress && typeof onPress === 'function') onPress();
513
- }
514
-
515
- render() {
516
- const {
517
- size, source, name, resizeMode, style, onPress, isShowLoading, loading, cached, extraPropsImage, quality
518
- } = this.props;
519
- const { hideSource } = this.state;
520
- const avatarStyle = this.mapStyleFromSize(size);
521
- const containerSize = this.extractSize(avatarStyle);
522
- const imageSource = ValueUtil.getImageSource(source);
523
- const showName = typeof imageSource === 'object' && Object.keys(imageSource).length === 0 && typeof imageSource !== 'number';
524
- // add priority high for avatar
525
- if (imageSource?.uri) {
526
- imageSource.priority = 'high';
527
- imageSource.uri = this.mapAvatarQuality(imageSource.uri, quality);
528
- // if doest not have time query, set default cache time to 1 day
529
- if (!imageSource.uri?.includes('?') && cached) {
530
- const midnight = new Date().setHours(0, 0, 0, 0);
531
- imageSource.uri = `${imageSource.uri}?time=${midnight}`;
532
- }
533
- }
534
-
535
- const inner = (
536
- <View style={[styles.container, containerSize, style]}>
537
- {(showName || hideSource) ? this.renderShortName(name, avatarStyle, size) : <View />}
538
- {this.isValidImageUrl(imageSource) && !hideSource
539
- ? (
540
- <Image
541
- cached={cached}
542
- loading={loading || isShowLoading}
543
- source={imageSource}
544
- onError={this.onLoadSourceError}
545
- style={avatarStyle}
546
- resizeMode={resizeMode}
547
- {...extraPropsImage}
548
- />
549
- ) : <View />}
550
- {this.renderSubIcon()}
551
- </View>
552
- );
553
- if (onPress) {
554
- return (
555
- <TouchableOpacity activeOpacity={onPress ? 0.5 : 1} onPress={this.onPress}>
556
- {inner}
557
- </TouchableOpacity>
558
- );
559
- }
560
- return inner;
561
- }
562
- }
563
-
564
- Avatar.propTypes = {
565
- name: PropTypes.string,
566
- resizeMode: PropTypes.string,
567
- quality: PropTypes.oneOf(['low', 'medium', 'high']),
568
- size: PropTypes.oneOf(['tiny', 'small', 'medium', 'large', 'giant', 'size8', 'size24', 'size36', 'size44', 'size48', 'size52', 'size56', 'size64', 'size72', 'size80', 'size88', 'size96',
569
- PropTypes.shape({
570
- width: PropTypes.number, height: PropTypes.number, borderRadius: PropTypes.number
571
- })]),
572
- source: PropTypes.oneOfType([PropTypes.shape({ uri: PropTypes.string }), PropTypes.number, PropTypes.string]),
573
- subIcon: PropTypes.oneOf(['momo', 'online', 'key', 'none']),
574
- subIconSource: PropTypes.oneOfType([PropTypes.shape({ uri: PropTypes.string }), PropTypes.number, PropTypes.string]),
575
- style: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
576
- onPress: PropTypes.func,
577
- loading: PropTypes.bool,
578
- cached: PropTypes.bool,
579
- scaleSize: PropTypes.bool,
580
- extraPropsImage: PropTypes.object
581
- };
582
-
583
- Avatar.defaultProps = {
584
- resizeMode: 'cover',
585
- cached: true,
586
- scaleSize: false,
587
- quality: 'medium',
588
- };
package/index.js DELETED
@@ -1,3 +0,0 @@
1
- import Avatar from './Avatar';
2
-
3
- export default Avatar;