You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

StatelessAvatar.js 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. // @flow
  2. import React from 'react';
  3. import { Image, Text, View } from 'react-native';
  4. import { Icon } from '../../../icons';
  5. import { type StyleType } from '../../../styles';
  6. import AbstractStatelessAvatar, { type Props as AbstractProps } from '../AbstractStatelessAvatar';
  7. import styles from './styles';
  8. const DEFAULT_AVATAR = require('../../../../../../images/avatar.png');
  9. type Props = AbstractProps & {
  10. /**
  11. * One of the expected status strings (e.g. 'available') to render a badge on the avatar, if necessary.
  12. */
  13. status?: ?string,
  14. /**
  15. * External style passed to the component.
  16. */
  17. style?: StyleType
  18. };
  19. /**
  20. * Implements a stateless avatar component that renders an avatar purely from what gets passed through
  21. * props.
  22. */
  23. export default class StatelessAvatar extends AbstractStatelessAvatar<Props> {
  24. /**
  25. * Implements {@code Component#render}.
  26. *
  27. * @inheritdoc
  28. */
  29. render() {
  30. const { initials, size, style, url } = this.props;
  31. let avatar;
  32. if (this._isIcon(url)) {
  33. avatar = this._renderIconAvatar(url);
  34. } else if (url) {
  35. avatar = this._renderURLAvatar();
  36. } else if (initials) {
  37. avatar = this._renderInitialsAvatar();
  38. } else {
  39. avatar = this._renderDefaultAvatar();
  40. }
  41. return (
  42. <View>
  43. <View
  44. style = { [
  45. styles.avatarContainer(size),
  46. style
  47. ] }>
  48. { avatar }
  49. </View>
  50. { this._renderAvatarStatus() }
  51. </View>
  52. );
  53. }
  54. _isIcon: (?string | ?Object) => boolean
  55. /**
  56. * Renders a badge representing the avatar status.
  57. *
  58. * @returns {React$Elementaa}
  59. */
  60. _renderAvatarStatus() {
  61. const { size, status } = this.props;
  62. if (!status) {
  63. return null;
  64. }
  65. return (
  66. <View style = { styles.badgeContainer }>
  67. <View style = { styles.badge(size, status) } />
  68. </View>
  69. );
  70. }
  71. /**
  72. * Renders the default avatar.
  73. *
  74. * @returns {React$Element<*>}
  75. */
  76. _renderDefaultAvatar() {
  77. const { size } = this.props;
  78. return (
  79. <Image
  80. source = { DEFAULT_AVATAR }
  81. style = { [
  82. styles.avatarContent(size),
  83. styles.staticAvatar
  84. ] } />
  85. );
  86. }
  87. /**
  88. * Renders the icon avatar.
  89. *
  90. * @param {Object} icon - The icon component to render.
  91. * @returns {React$Element<*>}
  92. */
  93. _renderIconAvatar(icon) {
  94. const { color, size } = this.props;
  95. return (
  96. <View
  97. style = { [
  98. styles.initialsContainer,
  99. {
  100. backgroundColor: color
  101. }
  102. ] }>
  103. <Icon
  104. src = { icon }
  105. style = { styles.initialsText(size) } />
  106. </View>
  107. );
  108. }
  109. /**
  110. * Renders the initials-based avatar.
  111. *
  112. * @returns {React$Element<*>}
  113. */
  114. _renderInitialsAvatar() {
  115. const { color, initials, size } = this.props;
  116. return (
  117. <View
  118. style = { [
  119. styles.initialsContainer,
  120. {
  121. backgroundColor: color
  122. }
  123. ] }>
  124. <Text style = { styles.initialsText(size) }> { initials } </Text>
  125. </View>
  126. );
  127. }
  128. /**
  129. * Renders the url-based avatar.
  130. *
  131. * @returns {React$Element<*>}
  132. */
  133. _renderURLAvatar() {
  134. const { onAvatarLoadError, size, url } = this.props;
  135. return (
  136. <Image
  137. defaultSource = { DEFAULT_AVATAR }
  138. onError = { onAvatarLoadError }
  139. resizeMode = 'cover'
  140. source = {{ uri: url }}
  141. style = { styles.avatarContent(size) } />
  142. );
  143. }
  144. }