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.

RecentList.native.js 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. import React from 'react';
  2. import { ListView, Text, TouchableHighlight, View } from 'react-native';
  3. import { connect } from 'react-redux';
  4. import { Icon } from '../../base/font-icons';
  5. import AbstractRecentList, { _mapStateToProps } from './AbstractRecentList';
  6. import { getRecentRooms } from '../functions';
  7. import styles, { UNDERLAY_COLOR } from './styles';
  8. /**
  9. * The native container rendering the list of the recently joined rooms.
  10. *
  11. * @extends AbstractRecentList
  12. */
  13. class RecentList extends AbstractRecentList {
  14. /**
  15. * The datasource wrapper to be used for the display.
  16. */
  17. dataSource = new ListView.DataSource({
  18. rowHasChanged: (r1, r2) =>
  19. r1.conference !== r2.conference
  20. && r1.dateTimeStamp !== r2.dateTimeStamp
  21. });
  22. /**
  23. * Initializes a new {@code RecentList} instance.
  24. *
  25. * @inheritdoc
  26. */
  27. constructor() {
  28. super();
  29. // Bind event handlers so they are only bound once per instance.
  30. this._getAvatarStyle = this._getAvatarStyle.bind(this);
  31. this._onSelect = this._onSelect.bind(this);
  32. this._renderConfDuration = this._renderConfDuration.bind(this);
  33. this._renderRow = this._renderRow.bind(this);
  34. this._renderServerInfo = this._renderServerInfo.bind(this);
  35. }
  36. /**
  37. * Implements React's {@link Component#render()}. Renders a list of recently
  38. * joined rooms.
  39. *
  40. * @inheritdoc
  41. * @returns {ReactElement}
  42. */
  43. render() {
  44. if (!this.props || !this.props._recentList) {
  45. return null;
  46. }
  47. const listViewDataSource
  48. = this.dataSource.cloneWithRows(
  49. getRecentRooms(this.props._recentList));
  50. return (
  51. <View style = { styles.container }>
  52. <ListView
  53. dataSource = { listViewDataSource }
  54. enableEmptySections = { true }
  55. renderRow = { this._renderRow } />
  56. </View>
  57. );
  58. }
  59. /**
  60. * Assembles the style array of the avatar based on if the conference was a
  61. * home or remote server conference (based on current app setting).
  62. *
  63. * @param {Object} recentListEntry - The recent list entry being rendered.
  64. * @private
  65. * @returns {Array<Object>}
  66. */
  67. _getAvatarStyle(recentListEntry) {
  68. const avatarStyles = [ styles.avatar ];
  69. if (recentListEntry.baseURL !== this.props._homeServer) {
  70. avatarStyles.push(
  71. this._getColorForServerName(recentListEntry.serverName));
  72. }
  73. return avatarStyles;
  74. }
  75. /**
  76. * Returns a style (color) based on the server name, so then the same server
  77. * will always be rendered with the same avatar color.
  78. *
  79. * @param {string} serverName - The recent list entry being rendered.
  80. * @private
  81. * @returns {Object}
  82. */
  83. _getColorForServerName(serverName) {
  84. let nameHash = 0;
  85. for (let i = 0; i < serverName.length; i++) {
  86. nameHash += serverName.codePointAt(i);
  87. }
  88. return styles[`avatarRemoteServer${(nameHash % 5) + 1}`];
  89. }
  90. /**
  91. * Renders the conference duration if available.
  92. *
  93. * @param {Object} recentListEntry - The recent list entry being rendered.
  94. * @private
  95. * @returns {ReactElement}
  96. */
  97. _renderConfDuration({ conferenceDurationString }) {
  98. if (conferenceDurationString) {
  99. return (
  100. <View style = { styles.infoWithIcon } >
  101. <Icon
  102. name = 'timer'
  103. style = { styles.inlineIcon } />
  104. <Text style = { styles.confLength }>
  105. { conferenceDurationString }
  106. </Text>
  107. </View>
  108. );
  109. }
  110. return null;
  111. }
  112. /**
  113. * Renders the server info component based on if the entry was on a
  114. * different server or not.
  115. *
  116. * @param {Object} recentListEntry - The recent list entry being rendered.
  117. * @private
  118. * @returns {ReactElement}
  119. */
  120. _renderServerInfo(recentListEntry) {
  121. if (recentListEntry.baseURL !== this.props._homeServer) {
  122. return (
  123. <View style = { styles.infoWithIcon } >
  124. <Icon
  125. name = 'public'
  126. style = { styles.inlineIcon } />
  127. <Text style = { styles.serverName }>
  128. { recentListEntry.serverName }
  129. </Text>
  130. </View>
  131. );
  132. }
  133. return null;
  134. }
  135. /**
  136. * Renders the list of recently joined rooms.
  137. *
  138. * @param {Object} data - The row data to be rendered.
  139. * @private
  140. * @returns {ReactElement}
  141. */
  142. _renderRow(data) {
  143. return (
  144. <TouchableHighlight
  145. onPress = { this._onSelect(data.conference) }
  146. underlayColor = { UNDERLAY_COLOR } >
  147. <View style = { styles.row } >
  148. <View style = { styles.avatarContainer } >
  149. <View style = { this._getAvatarStyle(data) } >
  150. <Text style = { styles.avatarContent }>
  151. { data.initials }
  152. </Text>
  153. </View>
  154. </View>
  155. <View style = { styles.detailsContainer } >
  156. <Text
  157. numberOfLines = { 1 }
  158. style = { styles.roomName }>
  159. { data.room }
  160. </Text>
  161. <View style = { styles.infoWithIcon } >
  162. <Icon
  163. name = 'event_note'
  164. style = { styles.inlineIcon } />
  165. <Text style = { styles.date }>
  166. { data.dateString }
  167. </Text>
  168. </View>
  169. {
  170. this._renderConfDuration(data)
  171. }
  172. {
  173. this._renderServerInfo(data)
  174. }
  175. </View>
  176. </View>
  177. </TouchableHighlight>
  178. );
  179. }
  180. }
  181. export default connect(_mapStateToProps)(RecentList);