index.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. import React, { Component } from 'react'
  2. import {
  3. SafeAreaView,
  4. View,
  5. Text,
  6. Image,
  7. FlatList,
  8. StyleSheet,
  9. TouchableOpacity,
  10. } from 'react-native'
  11. import {connect} from 'react-redux'
  12. import {Device} from '../../../../tool'
  13. import SearchBar from '../searchBar'
  14. import ItemInContact from '../ItemInContact';
  15. import SeparatorLine from './SeparatorLine';
  16. import simplePinyin from 'simple-pinyin';
  17. class ContactList extends Component {
  18. constructor(props) {
  19. super(props)
  20. this.state = {
  21. labels: [],
  22. }
  23. }
  24. componentWillMount() {
  25. const {userGroup} =this.props
  26. console.log(userGroup)
  27. this._dataConvert(this._pySegSort(userGroup.friendArr, 'nickname'))
  28. }
  29. componentDidMount() {
  30. }
  31. // 排序并添加首字母
  32. _pySegSort(arr, key) {
  33. const letters = "abcdefghjklmnopqrstwxyz".split('')
  34. let segs = []
  35. let curr
  36. let otherName = []
  37. let t = new Date()
  38. arr.map((a,m)=>{
  39. let firstKey = a[key][0]
  40. let reg = new RegExp("^[A-Za-z\u4e00-\u9fa5]+$");
  41. if(!reg.test(firstKey)){
  42. otherName.push(JSON.parse(JSON.stringify(a)))
  43. }
  44. })
  45. letters.map((l,i) => {
  46. curr = {label: l.toUpperCase(), data:[]}
  47. arr.map((a,m) =>{
  48. if(a[key]==='') return
  49. let firstKey = a[key][0]
  50. let nameKey = simplePinyin(firstKey,{ pinyinOnly: false })
  51. if(nameKey.length===0) return
  52. if(nameKey[0][0].toUpperCase()===l.toUpperCase()){
  53. curr.data.push(JSON.parse(JSON.stringify(a)))
  54. arr[m][key]=''
  55. }
  56. })
  57. if(curr.data.length) {
  58. segs.push(curr)
  59. curr.data.sort(function(a,b){
  60. return a[key].localeCompare(b[key])
  61. })
  62. }
  63. })
  64. console.log(new Date() -t)
  65. if(otherName.length){
  66. segs.push({
  67. label:'#',
  68. data:otherName
  69. })
  70. }
  71. segs.unshift({
  72. label:'@',
  73. data:[]
  74. })
  75. return segs
  76. }
  77. // 转换成 FlatList 需要的数据
  78. _dataConvert(names) {
  79. if (!names || names.length === 0) {
  80. return
  81. }
  82. let contacts = []
  83. let labels = []
  84. let index = 0
  85. let labelItem = {}
  86. names.map((item) => {
  87. labelItem = {
  88. index: index,
  89. label: item.label
  90. }
  91. contacts.push(labelItem)
  92. labels.push(labelItem)
  93. index++
  94. if (item.data && item.data.length > 0) {
  95. item.data.map((nameItem) => {
  96. contacts.push({ index: index, ...nameItem })
  97. index++
  98. })
  99. }
  100. })
  101. this.setState({
  102. contacts: contacts,
  103. labels: labels
  104. })
  105. }
  106. render() {
  107. const { contacts, labels } = this.state
  108. const {navigation} =this.props.props
  109. const Icon_Contact_search = require('../../../../../assets/2x/contact/search.png')
  110. const scollTo = (item) => {
  111. // 当viewPosition 为 0 时将它滚动到屏幕顶部,为 1 时将它滚动到屏幕底部,为 0.5 时将它滚动到屏幕中央。
  112. this._flatList.scrollToIndex({viewPosition:0, index:item.index})
  113. }
  114. const renderItem = ({item}) => {
  115. const onPress = () => {
  116. //跳转到 个人详情
  117. navigation.navigate("DetailedInfo",{item})
  118. }
  119. if(item.index===0){
  120. return (<SearchBar props={this.props.props}/>)
  121. }
  122. return (
  123. item.username ?
  124. <TouchableOpacity style={styles.listItem} onPress={onPress}>
  125. <ItemInContact item={item}></ItemInContact>
  126. </TouchableOpacity> :
  127. <View style={styles.labelItem}>
  128. {/* title */}
  129. <Text style={styles.itemLabel}>{`${item.label}`}</Text>
  130. </View>
  131. )
  132. }
  133. return (
  134. <SafeAreaView style={styles.container}>
  135. <FlatList data={contacts}
  136. keyExtractor={(item, index) => index + ''}
  137. ref={(flatList)=>this._flatList = flatList}
  138. ItemSeparatorComponent={() => <SeparatorLine />}
  139. showsVerticalScrollIndicator = {false}
  140. renderItem={renderItem}/>
  141. <View style={styles.slideCtn}>
  142. {labels.map((item) =>{
  143. if(item.index===0 && item.label==='@'){
  144. return (
  145. <TouchableOpacity
  146. key={item.label}
  147. style={styles.labelCtn}
  148. onPress={()=> scollTo(item)}>
  149. <Image
  150. style={{width:Device.scale(12),height:Device.scale(12)}}
  151. source={Icon_Contact_search}></Image>
  152. </TouchableOpacity>
  153. )
  154. }
  155. return (
  156. <TouchableOpacity
  157. key={item.label}
  158. style={styles.labelCtn}
  159. onPress={()=> scollTo(item)}>
  160. <Text style={styles.slideLabel}>{item.label}</Text>
  161. </TouchableOpacity>
  162. )
  163. }
  164. )}
  165. </View>
  166. </SafeAreaView>
  167. )
  168. }
  169. }
  170. const styles = StyleSheet.create({
  171. container: {
  172. flex: 1,
  173. backgroundColor: 'white'
  174. },
  175. listItem: {
  176. height: Device.scale(45),
  177. justifyContent: 'center',
  178. // marginLeft:Device.scale(20),
  179. height:Device.scale(55)
  180. },
  181. labelItem: {
  182. justifyContent: 'center',
  183. backgroundColor: '#f0f0f0',
  184. height:Device.scale(25)
  185. },
  186. itemLabel: {
  187. fontSize: Device.scale(17),
  188. color: 'rgba(0,0,0,0.5)',
  189. marginLeft: Device.scale(10),
  190. // fontWeight: 'bold',
  191. fontSize:Device.scale(15)
  192. },
  193. itemName: {
  194. fontSize: Device.scale(16),
  195. color: '#4C5361',
  196. marginLeft: Device.scale(10)
  197. },
  198. slideCtn: {
  199. top: Device.scale(80),
  200. right: 0,
  201. position: 'absolute',
  202. backgroundColor: 'transparent',
  203. alignItems: 'center',
  204. },
  205. labelCtn: {
  206. paddingLeft: Device.scale(10),
  207. paddingRight: Device.scale(10),
  208. paddingTop:Device.scale(3),
  209. paddingBottom:Device.scale(3)
  210. },
  211. slideLabel: {
  212. color: '#504f4f',
  213. fontSize: Device.scale(9),
  214. },
  215. })
  216. const getUserGroup=(state)=>{
  217. const {userGroup} = state
  218. return {userGroup}
  219. }
  220. export default connect(getUserGroup)(ContactList);