@momo-kits/avatar 0.0.61-beta.9 → 0.0.62-alpha.2
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 +262 -547
- package/package.json +2 -2
package/Avatar.js
CHANGED
|
@@ -1,22 +1,15 @@
|
|
|
1
1
|
/* eslint-disable indent */
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import React, { Component } from 'react';
|
|
4
|
-
import {
|
|
5
|
-
View,
|
|
6
|
-
StyleSheet,
|
|
7
|
-
TouchableOpacity,
|
|
8
|
-
Dimensions,
|
|
9
|
-
Platform,
|
|
10
|
-
} from 'react-native';
|
|
11
|
-
import { get, isEqual } from 'lodash';
|
|
12
2
|
import {
|
|
13
|
-
ValueUtil,
|
|
14
3
|
Colors,
|
|
15
|
-
Text,
|
|
16
|
-
IconSource,
|
|
17
4
|
Image,
|
|
5
|
+
Radius,
|
|
18
6
|
ScaleSize,
|
|
19
|
-
|
|
7
|
+
Text,
|
|
8
|
+
ValueUtil,
|
|
9
|
+
} from '@momo-kits/core-v2';
|
|
10
|
+
import PropTypes from 'prop-types';
|
|
11
|
+
import React from 'react';
|
|
12
|
+
import { StyleSheet, TouchableOpacity, View } from 'react-native';
|
|
20
13
|
|
|
21
14
|
export const AvatarQuality = {
|
|
22
15
|
low: 'low',
|
|
@@ -30,43 +23,8 @@ export const AvatarSize = {
|
|
|
30
23
|
medium: 'medium',
|
|
31
24
|
large: 'large',
|
|
32
25
|
giant: 'giant',
|
|
33
|
-
size8: 'size8',
|
|
34
|
-
size24: 'size24',
|
|
35
|
-
size36: 'size36',
|
|
36
|
-
size44: 'size44',
|
|
37
|
-
size48: 'size48',
|
|
38
|
-
size52: 'size52',
|
|
39
|
-
size56: 'size56',
|
|
40
|
-
size64: 'size64',
|
|
41
|
-
size72: 'size72',
|
|
42
|
-
size80: 'size80',
|
|
43
|
-
size88: 'size88',
|
|
44
|
-
size96: 'size96',
|
|
45
26
|
};
|
|
46
27
|
|
|
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
|
-
|
|
70
28
|
export const SubIconType = {
|
|
71
29
|
momo: 'momo',
|
|
72
30
|
online: 'online',
|
|
@@ -80,12 +38,11 @@ const styles = StyleSheet.create({
|
|
|
80
38
|
alignItems: 'center',
|
|
81
39
|
},
|
|
82
40
|
shortNameView: {
|
|
41
|
+
backgroundColor: Colors.pink_09,
|
|
83
42
|
justifyContent: 'center',
|
|
84
43
|
alignItems: 'center',
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
width: '100%',
|
|
88
|
-
height: '100%',
|
|
44
|
+
borderWidth: 1,
|
|
45
|
+
borderColor: Colors.black_04,
|
|
89
46
|
},
|
|
90
47
|
shortNameText: {
|
|
91
48
|
// fontSize: 17,
|
|
@@ -106,6 +63,11 @@ const styles = StyleSheet.create({
|
|
|
106
63
|
bottom: 0,
|
|
107
64
|
right: 0,
|
|
108
65
|
},
|
|
66
|
+
topIcon: {
|
|
67
|
+
position: 'absolute',
|
|
68
|
+
top: 0,
|
|
69
|
+
right: 0,
|
|
70
|
+
},
|
|
109
71
|
subIconImage: {
|
|
110
72
|
width: 22,
|
|
111
73
|
height: 22,
|
|
@@ -117,268 +79,137 @@ const styles = StyleSheet.create({
|
|
|
117
79
|
},
|
|
118
80
|
});
|
|
119
81
|
|
|
120
|
-
const subIconSize = (
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
width: 10,
|
|
153
|
-
height: 10,
|
|
154
|
-
borderRadius: 5,
|
|
155
|
-
},
|
|
156
|
-
size44: {
|
|
157
|
-
width: 14,
|
|
158
|
-
height: 14,
|
|
159
|
-
borderRadius: 7,
|
|
160
|
-
},
|
|
161
|
-
size48: {
|
|
162
|
-
width: 14,
|
|
163
|
-
height: 14,
|
|
164
|
-
borderRadius: 7,
|
|
165
|
-
},
|
|
166
|
-
size52: {
|
|
167
|
-
width: 16,
|
|
168
|
-
height: 16,
|
|
169
|
-
borderRadius: 8,
|
|
170
|
-
},
|
|
171
|
-
size56: {
|
|
172
|
-
width: 16,
|
|
173
|
-
height: 16,
|
|
174
|
-
borderRadius: 8,
|
|
175
|
-
},
|
|
176
|
-
size64: {
|
|
177
|
-
width: 16,
|
|
178
|
-
height: 16,
|
|
179
|
-
borderRadius: 8,
|
|
180
|
-
top: -2,
|
|
181
|
-
left: -2,
|
|
182
|
-
},
|
|
183
|
-
size72: {
|
|
184
|
-
width: 18,
|
|
185
|
-
height: 18,
|
|
186
|
-
borderRadius: 9,
|
|
187
|
-
top: -3,
|
|
188
|
-
left: -3,
|
|
189
|
-
},
|
|
190
|
-
size80: {
|
|
191
|
-
width: 18,
|
|
192
|
-
height: 18,
|
|
193
|
-
borderRadius: 9,
|
|
194
|
-
top: -3,
|
|
195
|
-
left: -3,
|
|
196
|
-
},
|
|
197
|
-
size88: {
|
|
198
|
-
width: 18,
|
|
199
|
-
height: 18,
|
|
200
|
-
borderRadius: 9,
|
|
201
|
-
top: -4,
|
|
202
|
-
left: -4,
|
|
203
|
-
},
|
|
204
|
-
size96: {
|
|
205
|
-
width: 20,
|
|
206
|
-
height: 20,
|
|
207
|
-
borderRadius: 10,
|
|
208
|
-
top: -4,
|
|
209
|
-
left: -4,
|
|
210
|
-
},
|
|
211
|
-
giant: {
|
|
212
|
-
top: -5,
|
|
213
|
-
left: -5,
|
|
214
|
-
width: 24,
|
|
215
|
-
height: 24,
|
|
216
|
-
borderRadius: 12,
|
|
217
|
-
},
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
const avatarSize = (width) => ({
|
|
221
|
-
tiny: {
|
|
222
|
-
width: 16,
|
|
223
|
-
height: 16,
|
|
224
|
-
borderRadius: 8,
|
|
225
|
-
},
|
|
226
|
-
small: {
|
|
227
|
-
width: 32,
|
|
228
|
-
height: 32,
|
|
229
|
-
borderRadius: 16,
|
|
230
|
-
},
|
|
231
|
-
medium: {
|
|
232
|
-
width: 40,
|
|
233
|
-
height: 40,
|
|
234
|
-
borderRadius: 20,
|
|
235
|
-
},
|
|
236
|
-
large: {
|
|
237
|
-
width: 60,
|
|
238
|
-
height: 60,
|
|
239
|
-
borderRadius: 30,
|
|
240
|
-
},
|
|
241
|
-
giant: {
|
|
242
|
-
width: 120,
|
|
243
|
-
height: 120,
|
|
244
|
-
borderRadius: 60,
|
|
245
|
-
},
|
|
246
|
-
size8: {
|
|
247
|
-
width: 8,
|
|
248
|
-
height: 8,
|
|
249
|
-
borderRadius: 4,
|
|
250
|
-
},
|
|
251
|
-
size24: {
|
|
252
|
-
width: 24,
|
|
253
|
-
height: 24,
|
|
254
|
-
borderRadius: 12,
|
|
255
|
-
},
|
|
256
|
-
size36: {
|
|
257
|
-
width: 36,
|
|
258
|
-
height: 36,
|
|
259
|
-
borderRadius: 18,
|
|
260
|
-
},
|
|
261
|
-
size44: {
|
|
262
|
-
width: 44,
|
|
263
|
-
height: 44,
|
|
264
|
-
borderRadius: 22,
|
|
265
|
-
},
|
|
266
|
-
size48: {
|
|
267
|
-
width: 48,
|
|
268
|
-
height: 48,
|
|
269
|
-
borderRadius: 24,
|
|
270
|
-
},
|
|
271
|
-
size52: {
|
|
272
|
-
width: 52,
|
|
273
|
-
height: 52,
|
|
274
|
-
borderRadius: 26,
|
|
275
|
-
},
|
|
276
|
-
size56: {
|
|
277
|
-
width: 56,
|
|
278
|
-
height: 56,
|
|
279
|
-
borderRadius: 28,
|
|
280
|
-
},
|
|
281
|
-
size64: {
|
|
282
|
-
width: 64,
|
|
283
|
-
height: 64,
|
|
284
|
-
borderRadius: 32,
|
|
285
|
-
},
|
|
286
|
-
size72: {
|
|
287
|
-
width: 72,
|
|
288
|
-
height: 72,
|
|
289
|
-
borderRadius: 36,
|
|
290
|
-
},
|
|
291
|
-
size80: {
|
|
292
|
-
width: 80,
|
|
293
|
-
height: 80,
|
|
294
|
-
borderRadius: 40,
|
|
295
|
-
},
|
|
296
|
-
size88: {
|
|
297
|
-
width: 88,
|
|
298
|
-
height: 88,
|
|
299
|
-
borderRadius: 44,
|
|
300
|
-
},
|
|
301
|
-
size96: {
|
|
302
|
-
width: 96,
|
|
303
|
-
height: 96,
|
|
304
|
-
borderRadius: 48,
|
|
305
|
-
},
|
|
306
|
-
});
|
|
307
|
-
|
|
308
|
-
const shortName = (width) => ({
|
|
309
|
-
tiny: {
|
|
310
|
-
fontSize: ScaleSize(5, width),
|
|
311
|
-
},
|
|
312
|
-
small: {
|
|
313
|
-
fontSize: ScaleSize(11, width),
|
|
314
|
-
},
|
|
315
|
-
medium: {
|
|
316
|
-
fontSize: ScaleSize(15, width),
|
|
317
|
-
},
|
|
318
|
-
middle: {
|
|
319
|
-
fontSize: ScaleSize(16, width),
|
|
320
|
-
},
|
|
321
|
-
large: {
|
|
322
|
-
fontSize: ScaleSize(20, width),
|
|
323
|
-
},
|
|
324
|
-
giant: {
|
|
325
|
-
fontSize: ScaleSize(25, width),
|
|
326
|
-
},
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
export default class Avatar extends Component {
|
|
330
|
-
constructor(props) {
|
|
331
|
-
super(props);
|
|
332
|
-
this.color = props.custom
|
|
333
|
-
? this.getAvatarColor(props.name)
|
|
334
|
-
: Colors.pink_10;
|
|
335
|
-
this.state = {
|
|
336
|
-
hideSource: false,
|
|
337
|
-
ownUpdate: false,
|
|
338
|
-
source: props.source,
|
|
339
|
-
dimensions: {},
|
|
340
|
-
};
|
|
341
|
-
this.imageSource = '';
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
componentDidMount() {
|
|
345
|
-
const { scaleSize } = this.props;
|
|
346
|
-
if (scaleSize) {
|
|
347
|
-
this.subscription = Dimensions.addEventListener(
|
|
348
|
-
'change',
|
|
349
|
-
({ window }) => {
|
|
350
|
-
if (
|
|
351
|
-
window?.height > 0 &&
|
|
352
|
-
window?.width > 0 &&
|
|
353
|
-
Platform.OS === 'android'
|
|
354
|
-
) {
|
|
355
|
-
this.setState({ dimensions: window });
|
|
356
|
-
}
|
|
357
|
-
},
|
|
358
|
-
);
|
|
359
|
-
}
|
|
82
|
+
const subIconSize = (size) => {
|
|
83
|
+
switch (size) {
|
|
84
|
+
case 'giant':
|
|
85
|
+
return {
|
|
86
|
+
width: 12,
|
|
87
|
+
height: 12,
|
|
88
|
+
borderRadius: 6,
|
|
89
|
+
};
|
|
90
|
+
case 'small':
|
|
91
|
+
return {
|
|
92
|
+
width: 8,
|
|
93
|
+
height: 8,
|
|
94
|
+
borderRadius: 4,
|
|
95
|
+
};
|
|
96
|
+
case 'medium':
|
|
97
|
+
return {
|
|
98
|
+
width: 12,
|
|
99
|
+
height: 12,
|
|
100
|
+
borderRadius: 6,
|
|
101
|
+
};
|
|
102
|
+
case 'large':
|
|
103
|
+
return {
|
|
104
|
+
width: 12,
|
|
105
|
+
height: 12,
|
|
106
|
+
borderRadius: 6,
|
|
107
|
+
};
|
|
108
|
+
default:
|
|
109
|
+
return {
|
|
110
|
+
width: 12,
|
|
111
|
+
height: 12,
|
|
112
|
+
borderRadius: 6,
|
|
113
|
+
};
|
|
360
114
|
}
|
|
115
|
+
};
|
|
361
116
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
117
|
+
const avatarSize = (size) => {
|
|
118
|
+
switch (size) {
|
|
119
|
+
case 'tiny':
|
|
120
|
+
return {
|
|
121
|
+
width: 16,
|
|
122
|
+
height: 16,
|
|
123
|
+
};
|
|
124
|
+
case 'small': {
|
|
125
|
+
return {
|
|
126
|
+
width: 32,
|
|
127
|
+
height: 32,
|
|
128
|
+
};
|
|
366
129
|
}
|
|
130
|
+
case 'medium':
|
|
131
|
+
return {
|
|
132
|
+
width: 40,
|
|
133
|
+
height: 40,
|
|
134
|
+
};
|
|
135
|
+
case 'large':
|
|
136
|
+
return {
|
|
137
|
+
width: 56,
|
|
138
|
+
height: 56,
|
|
139
|
+
};
|
|
140
|
+
case 'giant':
|
|
141
|
+
return {
|
|
142
|
+
width: 72,
|
|
143
|
+
height: 72,
|
|
144
|
+
};
|
|
145
|
+
default:
|
|
146
|
+
return {
|
|
147
|
+
width: 40,
|
|
148
|
+
height: 40,
|
|
149
|
+
};
|
|
367
150
|
}
|
|
151
|
+
};
|
|
368
152
|
|
|
369
|
-
|
|
370
|
-
|
|
153
|
+
const shortName = (size) => {
|
|
154
|
+
switch (size) {
|
|
155
|
+
case 'tiny':
|
|
371
156
|
return {
|
|
372
|
-
|
|
157
|
+
fontSize: ScaleSize(8),
|
|
158
|
+
lineHeight: 16,
|
|
159
|
+
};
|
|
160
|
+
case 'small':
|
|
161
|
+
return {
|
|
162
|
+
fontSize: ScaleSize(15),
|
|
163
|
+
lineHeight: 22,
|
|
164
|
+
};
|
|
165
|
+
case 'medium':
|
|
166
|
+
return {
|
|
167
|
+
fontSize: ScaleSize(15),
|
|
168
|
+
lineHeight: 22,
|
|
169
|
+
};
|
|
170
|
+
case 'large':
|
|
171
|
+
return {
|
|
172
|
+
fontSize: ScaleSize(15),
|
|
173
|
+
lineHeight: 22,
|
|
174
|
+
};
|
|
175
|
+
case 'giant':
|
|
176
|
+
return {
|
|
177
|
+
fontSize: ScaleSize(15),
|
|
178
|
+
lineHeight: 22,
|
|
179
|
+
};
|
|
180
|
+
default:
|
|
181
|
+
return {
|
|
182
|
+
fontSize: ScaleSize(15),
|
|
183
|
+
lineHeight: 22,
|
|
373
184
|
};
|
|
374
|
-
}
|
|
375
|
-
if (!isEqual(nextProps.source, prevState.source)) {
|
|
376
|
-
return { source: nextProps.source, hideSource: false };
|
|
377
|
-
}
|
|
378
|
-
return null;
|
|
379
185
|
}
|
|
186
|
+
};
|
|
380
187
|
|
|
381
|
-
|
|
188
|
+
const Avatar = ({
|
|
189
|
+
resizeMode,
|
|
190
|
+
cached,
|
|
191
|
+
quality,
|
|
192
|
+
size,
|
|
193
|
+
shape,
|
|
194
|
+
name,
|
|
195
|
+
source,
|
|
196
|
+
onPress,
|
|
197
|
+
style,
|
|
198
|
+
subIcon,
|
|
199
|
+
topIcon,
|
|
200
|
+
loading,
|
|
201
|
+
}) => {
|
|
202
|
+
const { width, height } = avatarSize(size);
|
|
203
|
+
const { fontSize, lineHeight } = shortName(size);
|
|
204
|
+
const {
|
|
205
|
+
width: iconWidth,
|
|
206
|
+
height: iconHeight,
|
|
207
|
+
borderRadius: iconRadius,
|
|
208
|
+
} = subIconSize(size);
|
|
209
|
+
|
|
210
|
+
const imageSource = ValueUtil.getImageSource(source);
|
|
211
|
+
|
|
212
|
+
const getContactShortName = (name) => {
|
|
382
213
|
if (!name) return '';
|
|
383
214
|
const shortNameList = name.split(' ', 2);
|
|
384
215
|
const alphabet = [];
|
|
@@ -389,57 +220,18 @@ export default class Avatar extends Component {
|
|
|
389
220
|
});
|
|
390
221
|
return alphabet.join('');
|
|
391
222
|
};
|
|
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;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
renderShortName = (name, avatarStyle, size, color) => {
|
|
406
|
-
if (name) {
|
|
407
|
-
const shortedName = this.getContactShortName(name);
|
|
408
|
-
const shortNameStyle = this.mapShortNameStyle(size);
|
|
409
|
-
return (
|
|
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>
|
|
425
|
-
</View>
|
|
426
|
-
);
|
|
427
|
-
}
|
|
428
|
-
return <View />;
|
|
429
|
-
};
|
|
430
|
-
|
|
431
|
-
isUrl(url) {
|
|
223
|
+
const isUrl = (url) => {
|
|
432
224
|
const expression =
|
|
433
225
|
/(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-/]))?/gi;
|
|
434
226
|
return expression.test(url);
|
|
435
|
-
}
|
|
227
|
+
};
|
|
436
228
|
|
|
437
|
-
isValidImageUrl = (source) => {
|
|
438
|
-
const validSource = source && source.uri &&
|
|
229
|
+
const isValidImageUrl = (source) => {
|
|
230
|
+
const validSource = source && source.uri && isUrl(source.uri);
|
|
439
231
|
return validSource;
|
|
440
232
|
};
|
|
441
233
|
|
|
442
|
-
mapAvatarQuality = (url, quality) => {
|
|
234
|
+
const mapAvatarQuality = (url, quality) => {
|
|
443
235
|
if (!quality || quality === AvatarQuality.medium) {
|
|
444
236
|
return url;
|
|
445
237
|
}
|
|
@@ -453,227 +245,150 @@ export default class Avatar extends Component {
|
|
|
453
245
|
return url;
|
|
454
246
|
};
|
|
455
247
|
|
|
456
|
-
|
|
457
|
-
const { dimensions } = this.state;
|
|
458
|
-
const avatarStyle = avatarSize(
|
|
459
|
-
dimensions?.width > 0 ? dimensions?.width : null,
|
|
460
|
-
).small;
|
|
461
|
-
if (typeof size === 'object') return size;
|
|
462
|
-
if (avatarSize(dimensions?.width > 0 ? dimensions?.width : null)[size])
|
|
463
|
-
return avatarSize(dimensions?.width > 0 ? dimensions?.width : null)[
|
|
464
|
-
size
|
|
465
|
-
];
|
|
466
|
-
return avatarStyle;
|
|
467
|
-
};
|
|
468
|
-
|
|
469
|
-
mapShortNameStyle = (size) => {
|
|
470
|
-
let shortNameStyle = {};
|
|
471
|
-
const { dimensions } = this.state;
|
|
472
|
-
switch (size) {
|
|
473
|
-
case AvatarSize.tiny: {
|
|
474
|
-
shortNameStyle = shortName(
|
|
475
|
-
dimensions?.width > 0 ? dimensions?.width : null,
|
|
476
|
-
).tiny;
|
|
477
|
-
break;
|
|
478
|
-
}
|
|
479
|
-
case AvatarSize.small: {
|
|
480
|
-
shortNameStyle = shortName(
|
|
481
|
-
dimensions?.width > 0 ? dimensions?.width : null,
|
|
482
|
-
).small;
|
|
483
|
-
break;
|
|
484
|
-
}
|
|
485
|
-
case AvatarSize.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;
|
|
493
|
-
break;
|
|
494
|
-
}
|
|
495
|
-
case AvatarSize.large: {
|
|
496
|
-
shortNameStyle = shortName(
|
|
497
|
-
dimensions?.width > 0 ? dimensions?.width : null,
|
|
498
|
-
).large;
|
|
499
|
-
break;
|
|
500
|
-
}
|
|
501
|
-
case AvatarSize.giant: {
|
|
502
|
-
shortNameStyle = shortName(
|
|
503
|
-
dimensions?.width > 0 ? dimensions?.width : null,
|
|
504
|
-
).giant;
|
|
505
|
-
break;
|
|
506
|
-
}
|
|
507
|
-
default:
|
|
508
|
-
shortNameStyle = shortName(
|
|
509
|
-
dimensions?.width > 0 ? dimensions?.width : null,
|
|
510
|
-
).small;
|
|
511
|
-
}
|
|
512
|
-
return shortNameStyle;
|
|
513
|
-
};
|
|
514
|
-
|
|
515
|
-
mapSubIconSize = (size) => {
|
|
516
|
-
const { dimensions } = this.state;
|
|
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];
|
|
524
|
-
return subIconStyle;
|
|
525
|
-
};
|
|
526
|
-
|
|
527
|
-
extractSize = (avatarStyle) => {
|
|
528
|
-
const { style } = this.props;
|
|
529
|
-
const borderWidth = get(style, 'borderWidth', 1);
|
|
530
|
-
const containerWidth = Math.round(avatarStyle.width + 2 + borderWidth);
|
|
531
|
-
return {
|
|
532
|
-
width: containerWidth,
|
|
533
|
-
height: containerWidth,
|
|
534
|
-
borderRadius: containerWidth / 2,
|
|
535
|
-
borderWidth,
|
|
536
|
-
borderColor: Colors.black_01,
|
|
537
|
-
};
|
|
538
|
-
};
|
|
539
|
-
|
|
540
|
-
onLoadSourceError = (imageSource) => {
|
|
248
|
+
const onLoadSourceError = (imageSource) => {
|
|
541
249
|
if (this.imageSource?.uri !== imageSource?.uri) {
|
|
542
250
|
this.imageSource = imageSource;
|
|
543
251
|
this.setState({ hideSource: true, ownUpdate: true });
|
|
544
252
|
}
|
|
545
253
|
};
|
|
546
254
|
|
|
547
|
-
renderSubIcon = () => {
|
|
548
|
-
const
|
|
549
|
-
if (
|
|
550
|
-
return
|
|
551
|
-
|
|
552
|
-
const iconSource = ValueUtil.getImageSource(subIconSource);
|
|
553
|
-
return (
|
|
554
|
-
<View style={styles.subIcon}>
|
|
555
|
-
{subIcon === SubIconType.momo ? (
|
|
255
|
+
const renderSubIcon = () => {
|
|
256
|
+
// const subIconSizeStyle = this.mapSubIconSize(size);
|
|
257
|
+
if (subIcon && shape === 'circle' && size !== 'tiny') {
|
|
258
|
+
return (
|
|
259
|
+
<View style={styles.subIcon}>
|
|
556
260
|
<Image
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
261
|
+
source={subIcon}
|
|
262
|
+
style={[
|
|
263
|
+
{
|
|
264
|
+
width: iconWidth,
|
|
265
|
+
height: iconHeight,
|
|
266
|
+
borderRadius: iconRadius,
|
|
267
|
+
bottom: iconWidth / 2 - 2,
|
|
268
|
+
right: iconWidth / 2 - 2,
|
|
269
|
+
},
|
|
270
|
+
]}
|
|
566
271
|
/>
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
272
|
+
</View>
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
};
|
|
570
276
|
|
|
571
|
-
|
|
277
|
+
const renderTopIcon = () => {
|
|
278
|
+
if (topIcon && shape === 'circle' && size !== 'tiny') {
|
|
279
|
+
return (
|
|
280
|
+
<View style={styles.topIcon}>
|
|
572
281
|
<Image
|
|
573
|
-
|
|
574
|
-
|
|
282
|
+
source={topIcon}
|
|
283
|
+
style={[
|
|
284
|
+
{
|
|
285
|
+
width: iconWidth,
|
|
286
|
+
height: iconHeight,
|
|
287
|
+
borderRadius: iconRadius,
|
|
288
|
+
top: iconWidth / 2 - 2,
|
|
289
|
+
right: iconWidth / 2 - 2,
|
|
290
|
+
},
|
|
291
|
+
]}
|
|
575
292
|
/>
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
</View>
|
|
580
|
-
);
|
|
293
|
+
</View>
|
|
294
|
+
);
|
|
295
|
+
}
|
|
581
296
|
};
|
|
582
297
|
|
|
583
|
-
|
|
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];
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
onPress = () => {
|
|
593
|
-
const { onPress } = this.props;
|
|
298
|
+
const onPressIcon = () => {
|
|
594
299
|
if (onPress && typeof onPress === 'function') onPress();
|
|
595
300
|
};
|
|
596
301
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
name,
|
|
602
|
-
resizeMode,
|
|
603
|
-
style,
|
|
604
|
-
onPress,
|
|
605
|
-
isShowLoading,
|
|
606
|
-
loading,
|
|
607
|
-
cached,
|
|
608
|
-
extraPropsImage,
|
|
609
|
-
quality,
|
|
610
|
-
} = this.props;
|
|
611
|
-
const { hideSource } = this.state;
|
|
612
|
-
const avatarStyle = this.mapStyleFromSize(size);
|
|
613
|
-
const containerSize = this.extractSize(avatarStyle);
|
|
614
|
-
const imageSource = ValueUtil.getImageSource(source);
|
|
615
|
-
const showName =
|
|
616
|
-
typeof imageSource === 'object' &&
|
|
617
|
-
Object.keys(imageSource).length === 0 &&
|
|
618
|
-
typeof imageSource !== 'number';
|
|
619
|
-
// add priority high for avatar
|
|
620
|
-
if (imageSource?.uri) {
|
|
621
|
-
imageSource.priority = 'high';
|
|
622
|
-
imageSource.uri = this.mapAvatarQuality(imageSource.uri, quality);
|
|
623
|
-
// if doest not have time query, set default cache time to 1 day
|
|
624
|
-
if (!imageSource.uri?.includes('?') && cached) {
|
|
625
|
-
const midnight = new Date().setHours(0, 0, 0, 0);
|
|
626
|
-
imageSource.uri = `${imageSource.uri}?time=${midnight}`;
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
const inner = (
|
|
631
|
-
<View style={[styles.container, containerSize, style]}>
|
|
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
|
-
)}
|
|
650
|
-
{this.renderSubIcon()}
|
|
651
|
-
</View>
|
|
652
|
-
);
|
|
653
|
-
if (onPress) {
|
|
302
|
+
const renderShortName = () => {
|
|
303
|
+
if (name) {
|
|
304
|
+
const shortedName = getContactShortName(name);
|
|
305
|
+
// const shortNameStyle = mapShortNameStyle(size);
|
|
654
306
|
return (
|
|
655
|
-
<
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
307
|
+
<View
|
|
308
|
+
style={[
|
|
309
|
+
{
|
|
310
|
+
width,
|
|
311
|
+
height,
|
|
312
|
+
borderRadius:
|
|
313
|
+
shape === 'circle' ? width / 2 : Radius.XS,
|
|
314
|
+
},
|
|
315
|
+
styles.shortNameView,
|
|
316
|
+
]}>
|
|
317
|
+
<Text
|
|
318
|
+
weight="regular"
|
|
319
|
+
style={{
|
|
320
|
+
fontSize,
|
|
321
|
+
lineHeight,
|
|
322
|
+
color: Colors.pink_03,
|
|
323
|
+
}}>
|
|
324
|
+
{shortedName}
|
|
325
|
+
</Text>
|
|
326
|
+
</View>
|
|
660
327
|
);
|
|
661
328
|
}
|
|
662
|
-
return
|
|
329
|
+
return <View />;
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
if (imageSource?.uri) {
|
|
333
|
+
imageSource.priority = 'high';
|
|
334
|
+
imageSource.uri = mapAvatarQuality(imageSource.uri, quality);
|
|
335
|
+
// if doest not have time query, set default cache time to 1 day
|
|
336
|
+
if (!imageSource.uri?.includes('?') && cached) {
|
|
337
|
+
const midnight = new Date().setHours(0, 0, 0, 0);
|
|
338
|
+
imageSource.uri = `${imageSource.uri}?time=${midnight}`;
|
|
339
|
+
}
|
|
663
340
|
}
|
|
664
|
-
|
|
341
|
+
|
|
342
|
+
const renderImage = () => {
|
|
343
|
+
return (
|
|
344
|
+
<Image
|
|
345
|
+
cached={cached}
|
|
346
|
+
resizeMode={resizeMode}
|
|
347
|
+
onLoadSourceError={() => onLoadSourceError(source)}
|
|
348
|
+
source={source}
|
|
349
|
+
loading={loading}
|
|
350
|
+
style={[
|
|
351
|
+
{
|
|
352
|
+
width,
|
|
353
|
+
height,
|
|
354
|
+
borderRadius:
|
|
355
|
+
shape === 'circle' ? width / 2 : Radius.XS,
|
|
356
|
+
},
|
|
357
|
+
]}
|
|
358
|
+
/>
|
|
359
|
+
);
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
return (
|
|
363
|
+
<TouchableOpacity
|
|
364
|
+
activeOpacity={!!onPress ? 0.5 : 1}
|
|
365
|
+
style={[style]}
|
|
366
|
+
onPress={onPressIcon}>
|
|
367
|
+
<View
|
|
368
|
+
style={{
|
|
369
|
+
alignSelf: 'baseline',
|
|
370
|
+
}}>
|
|
371
|
+
{!!imageSource && isValidImageUrl(imageSource)
|
|
372
|
+
? renderImage()
|
|
373
|
+
: renderShortName()}
|
|
374
|
+
{renderTopIcon()}
|
|
375
|
+
{renderSubIcon()}
|
|
376
|
+
</View>
|
|
377
|
+
</TouchableOpacity>
|
|
378
|
+
);
|
|
379
|
+
};
|
|
665
380
|
|
|
666
381
|
Avatar.propTypes = {
|
|
667
382
|
name: PropTypes.string,
|
|
668
|
-
resizeMode: PropTypes.string,
|
|
669
383
|
quality: PropTypes.oneOf(['low', 'medium', 'high']),
|
|
670
|
-
size: PropTypes.
|
|
384
|
+
size: PropTypes.oneOf(['tiny', 'small', 'medium', 'large', 'giant']),
|
|
671
385
|
source: PropTypes.oneOfType([
|
|
672
386
|
PropTypes.shape({ uri: PropTypes.string }),
|
|
673
387
|
PropTypes.number,
|
|
674
388
|
PropTypes.string,
|
|
675
389
|
]),
|
|
676
|
-
subIcon: PropTypes.
|
|
390
|
+
subIcon: PropTypes.string,
|
|
391
|
+
topIcon: PropTypes.string,
|
|
677
392
|
subIconSource: PropTypes.oneOfType([
|
|
678
393
|
PropTypes.shape({ uri: PropTypes.string }),
|
|
679
394
|
PropTypes.number,
|
|
@@ -682,11 +397,8 @@ Avatar.propTypes = {
|
|
|
682
397
|
style: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
|
|
683
398
|
onPress: PropTypes.func,
|
|
684
399
|
loading: PropTypes.bool,
|
|
685
|
-
cached: PropTypes.bool,
|
|
686
|
-
scaleSize: PropTypes.bool,
|
|
687
400
|
extraPropsImage: PropTypes.object,
|
|
688
|
-
|
|
689
|
-
custom: PropTypes.bool,
|
|
401
|
+
shape: PropTypes.oneOf(['circle', 'square']),
|
|
690
402
|
};
|
|
691
403
|
|
|
692
404
|
Avatar.defaultProps = {
|
|
@@ -695,5 +407,8 @@ Avatar.defaultProps = {
|
|
|
695
407
|
scaleSize: false,
|
|
696
408
|
quality: 'medium',
|
|
697
409
|
size: 'small',
|
|
698
|
-
|
|
410
|
+
shape: 'circle',
|
|
411
|
+
name: '',
|
|
699
412
|
};
|
|
413
|
+
|
|
414
|
+
export default Avatar;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@momo-kits/avatar",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.62-alpha.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"dependencies": {},
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"react-native": ">=0.55",
|
|
9
9
|
"prop-types": "^15.7.2",
|
|
10
10
|
"react": "16.9.0",
|
|
11
|
-
"@momo-kits/core": ">=0.0.5-beta",
|
|
11
|
+
"@momo-kits/core-v2": ">=0.0.5-beta",
|
|
12
12
|
"lodash": "^4.17.15"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {},
|