moment_main.tsx 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  1. import TabBar from "@/components/navigation/TabBar";
  2. import { rpxToPx } from "@/utils/tools";
  3. import { View, Text, Image, ScrollView, Button, Block } from "@tarojs/components";
  4. import Taro, { useDidShow, useRouter, useShareAppMessage } from "@tarojs/taro";
  5. import { useDispatch, useSelector } from "react-redux";
  6. import { useEffect, useRef, useState } from "react";
  7. import { followUser, getFriendMoments, getMyFriends, getUserDashBoard } from "@/services/friend";
  8. import FriendGuide from "./guide";
  9. import EmptyContent from "./empty_content";
  10. import MomentItem from "./moment_item";
  11. import { useTranslation } from "react-i18next";
  12. import { windows } from "@/services/health";
  13. import { setFastWithSleep, setFinishSetup, setLongFast, setRefreshs, setWindows } from "@/store/health";
  14. import { getInfoSuccess } from "@/store/user";
  15. import showActionSheet from "@/components/basic/ActionSheet";
  16. import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
  17. import './moment.scss'
  18. import ListFooter from "@/_health/components/list_footer";
  19. import { MainColorType } from "@/context/themes/color";
  20. import dayjs from "dayjs";
  21. import { IconClose, IconMenu } from "@/components/basic/Icons";
  22. import MomentShare from "./moment_share";
  23. import NoRecord from "@/_health/components/no_record";
  24. import ShareBtn from "@/components/basic/ShareBtn";
  25. import NewButton, { NewButtonType } from "@/_health/base/new_button";
  26. import MomentDetailShare from "./moment_detail_share";
  27. import { getThemeColor } from "@/features/health/hooks/health_hooks";
  28. import shareTitle from "./moment_unit";
  29. let useRoute;
  30. let useNavigation;
  31. let FlatList;
  32. let useActionSheet;
  33. let RefreshControl;
  34. let useSafeAreaInsets;
  35. if (process.env.TARO_ENV == 'rn') {
  36. useActionSheet = require('@expo/react-native-action-sheet').useActionSheet
  37. RefreshControl = require("react-native").RefreshControl
  38. useRoute = require("@react-navigation/native").useRoute
  39. useNavigation = require("@react-navigation/native").useNavigation
  40. FlatList = require('react-native').FlatList
  41. useSafeAreaInsets = require('react-native-safe-area-context').useSafeAreaInsets
  42. }
  43. let timer;
  44. let myScrollTop = 0
  45. export default function MomentMain() {
  46. const user = useSelector((state: any) => state.user);
  47. // const observerObjBottom = Taro.createIntersectionObserver().relativeToViewport({ bottom: 100 })
  48. const [loading, setLoading] = useState(false)
  49. const [noMore, setNoMore] = useState(false)
  50. const [friends, setFriends] = useState<any>([])
  51. const [count, setCount] = useState(0)
  52. const systemInfo: any = Taro.getWindowInfo ? Taro.getWindowInfo() : Taro.getSystemInfoSync();
  53. const navigationBarHeight = systemInfo.statusBarHeight + 44;
  54. const screenHeight = systemInfo.screenHeight
  55. const [itemLayouts, setItemLayouts] = useState<any>([])
  56. const [itemHeights, setItemHeights] = useState<any>([])
  57. const [isPulling, setIsPulling] = useState(false)
  58. const [pageTop, setPageTop] = useState(0)
  59. const scrollRef = useRef()
  60. let showActionSheetWithOptions;
  61. let insets:any
  62. if (process.env.TARO_ENV == 'rn') {
  63. showActionSheetWithOptions = useActionSheet()
  64. insets = useSafeAreaInsets();
  65. }
  66. let router
  67. let navigation;
  68. if (useNavigation) {
  69. navigation = useNavigation()
  70. }
  71. if (process.env.TARO_ENV == 'rn') {
  72. router = useRoute()
  73. }
  74. else {
  75. router = useRouter()
  76. }
  77. const [loaded, setLoaded] = useState(false)
  78. const [homeType, setHomeType] = useState('NO_FRIEND')
  79. const [dashBoard, setDashBoard] = useState<any>(null)
  80. const [moments, setMoments] = useState<any>([])
  81. const [page, setPage] = useState(1)
  82. const [endSignal, setEndSignal] = useState(0)
  83. const [closeGuide, setCloseGuide] = useState(false)
  84. const [showGuide, setShowGuide] = useState(false)
  85. const [showShareGuide, setShowShareGuide] = useState(false)
  86. const [shareInfo, setShareInfo] = useState<any>(null)
  87. const query: any = process.env.TARO_ENV == 'weapp' ? Taro.createSelectorQuery() : null
  88. const dispatch = useDispatch()
  89. const { t } = useTranslation()
  90. const momentsRef = useRef(moments)
  91. useEffect(() => {
  92. dayjs.locale(global.language == 'en' ? 'en' : 'zh-cn');
  93. require('moment/locale/en-gb')
  94. require('moment/locale/zh-cn')
  95. timer = setInterval(() => {
  96. setCount(count => count + 1)
  97. }, 1000)
  98. Taro.eventCenter.on('followUser', listenFollowUser)
  99. Taro.eventCenter.on('unfollowUser', listenUnfollowUser)
  100. Taro.eventCenter.on('refreshMoments', refreshMoments)
  101. Taro.eventCenter.on('moment_share', momentShare)
  102. Taro.eventCenter.on('refresh_timeline', refreshItem)
  103. //Taro.eventCenter.trigger('refresh_timeline',(res as any).feed_item)
  104. return () => {
  105. Taro.eventCenter.off('followUser')
  106. Taro.eventCenter.off('unfollowUser')
  107. Taro.eventCenter.off('refreshMoments')
  108. Taro.eventCenter.off('moment_share')
  109. Taro.eventCenter.off('refresh_timeline')
  110. clearInterval(timer)
  111. }
  112. }, [])
  113. useEffect(() => {
  114. momentsRef.current = moments;
  115. }, [moments])
  116. function listenFollowUser(e) {
  117. myFriends()
  118. }
  119. function listenUnfollowUser(e) {
  120. myFriends()
  121. }
  122. function refreshMoments(e) {
  123. myFriends()
  124. }
  125. function refreshItem(e) {
  126. if (!e) return
  127. const { link, moment, user } = e
  128. var list = JSON.parse(JSON.stringify(momentsRef.current))
  129. list.map((item) => {
  130. if (item.link.event_id == link.event_id) {
  131. if (link) {
  132. item.link = e.link
  133. }
  134. if (moment) {
  135. item.moment = e.moment
  136. }
  137. if (user) {
  138. item.user = e.user
  139. }
  140. }
  141. })
  142. setMoments(list)
  143. }
  144. function momentShare(e) {
  145. setShareInfo(e)
  146. setShowShareGuide(true)
  147. // var dt = scrollRef.current
  148. // query.select(`#myscrollview`).boundingClientRect().exec(res=>{
  149. // debugger
  150. // })
  151. }
  152. useEffect(() => {
  153. myFriends()
  154. if (router.params && router.params.type == 'share') {
  155. if (global.shareTicket) {
  156. Taro.getShareInfo({
  157. shareTicket: global.shareTicket,
  158. success(result) {
  159. updateRelation(result)
  160. },
  161. })
  162. }
  163. else {
  164. updateRelation(null)
  165. }
  166. }
  167. }, [user.isLogin])
  168. useEffect(() => {
  169. if (moments.length == 0) return
  170. setTimeout(() => {
  171. measureItemLayouts()
  172. }, 300)
  173. if (process.env.TARO_ENV == 'weapp') {
  174. const observerObjBottom = Taro.createIntersectionObserver().relativeToViewport({ bottom: 100 })
  175. observerObjBottom && observerObjBottom.observe('#footer', (res) => {
  176. setEndSignal(endSignal => endSignal + 1)
  177. })
  178. }
  179. }, [moments])
  180. useEffect(() => {
  181. if (moments.length == 0) return
  182. loadMore()
  183. }, [endSignal])
  184. function measureItemLayouts() {
  185. if (process.env.TARO_ENV == 'rn') return
  186. if (moments.length <= 10) {
  187. moments.forEach((item, index) => {
  188. query.select(`#history2-${index}`).boundingClientRect()
  189. });
  190. query.exec((res) => {
  191. var layouts: any = []
  192. var heights: any = []
  193. res.forEach((rect, index) => {
  194. if (rect) {
  195. layouts[index] = rect.top + myScrollTop
  196. heights[index] = rect.height
  197. }
  198. });
  199. setItemLayouts(layouts)
  200. setItemHeights(heights)
  201. })
  202. }
  203. else {
  204. moments.forEach((item, index) => {
  205. if (index >= itemLayouts.length) {
  206. query.select(`#history2-${index}`).boundingClientRect()
  207. }
  208. });
  209. query.exec((res) => {
  210. var layouts: any = []
  211. var heights: any = []
  212. res.forEach((rect, index) => {
  213. if (rect) {
  214. layouts[index] = rect.top + myScrollTop
  215. heights[index] = rect.height
  216. }
  217. });
  218. setItemLayouts([...itemLayouts, ...layouts])
  219. setItemHeights([...itemHeights, ...heights])
  220. })
  221. }
  222. }
  223. function onScroll(e) {
  224. // var top = e.detail.scrollTop
  225. // myScrollTop = top
  226. var top = e.detail.scrollTop - e.detail.deltaY
  227. myScrollTop = e.detail.scrollTop
  228. setPageTop(top)
  229. }
  230. useDidShow(() => {
  231. getDashBoard()
  232. })
  233. function myFriends() {
  234. if (!user.isLogin) {
  235. setLoaded(true)
  236. Taro.hideLoading()
  237. return
  238. }
  239. setItemHeights([])
  240. setItemLayouts([])
  241. getDashBoard()
  242. getMoments(1)
  243. }
  244. function onRefresh() {
  245. setIsPulling(true)
  246. getMoments(1)
  247. getDashBoard()
  248. }
  249. function getMoments(index) {
  250. setPage(index)
  251. getFriendMoments({
  252. page: index,
  253. limit: 10
  254. }).then(res => {
  255. setIsPulling(false)
  256. if (index == 1) {
  257. setMoments((res as any).data)
  258. }
  259. else {
  260. setMoments([...moments, ...(res as any).data])
  261. }
  262. setLoading(false)
  263. if ((res as any).data.length == 0) {
  264. setNoMore(true)
  265. }
  266. else {
  267. setNoMore(false)
  268. }
  269. }).catch(e => {
  270. setIsPulling(false)
  271. setLoading(false)
  272. setLoaded(true)
  273. Taro.hideLoading()
  274. })
  275. }
  276. function getDashBoard() {
  277. getUserDashBoard().then(res => {
  278. setLoaded(true)
  279. setHomeType((res as any).homepage_type)
  280. setDashBoard(res)
  281. Taro.hideLoading()
  282. }).catch(e => {
  283. setLoaded(true)
  284. Taro.hideLoading()
  285. })
  286. }
  287. function updateRelation(obj) {
  288. if (!user.isLogin) {
  289. Taro.setStorageSync('share_uid', router.params.uid)
  290. Taro.setStorageSync('share_info', JSON.stringify(obj))
  291. return
  292. }
  293. if (user.id != router.params.uid) {
  294. var params: any = {
  295. follow_origin: obj ? 'WECHAT_GROUP_CHAT' : 'WECHAT_PRIVATE_CHAT',
  296. user_id: router.params.uid,
  297. }
  298. if (obj) {
  299. params.wechat = obj
  300. }
  301. followUser(params).then(res => {
  302. myFriends()
  303. })
  304. }
  305. }
  306. function loadMore() {
  307. if (loading) return;
  308. if (noMore) return;
  309. setLoading(true)
  310. var index = page;
  311. index++;
  312. setPage(index)
  313. getMoments(index)
  314. }
  315. function more() {
  316. showActionSheet({
  317. showActionSheetWithOptions: showActionSheetWithOptions,
  318. title: '',
  319. itemList: ['个人主页', '我的搭子', '消息通知'],
  320. success: (index) => {
  321. switch (index) {
  322. case 0:
  323. jumpPage('/_moment/pages/home?uid=' + user.id, 'UserHome', navigation, {
  324. uid: user.id
  325. })
  326. break;
  327. case 1:
  328. jumpPage('/_moment/pages/relation', 'Relation', navigation)
  329. break
  330. case 2:
  331. jumpPage('/_moment/pages/message', 'Message', navigation)
  332. break
  333. }
  334. }
  335. })
  336. }
  337. function friendGuide() {
  338. return <View style={{ position: process.env.TARO_ENV == 'weapp' ? 'fixed' : 'absolute', left: 0, top: 0, width: rpxToPx(750), height: process.env.TARO_ENV == 'weapp' ? '100vh' : screenHeight, zIndex: 100 }}>
  339. <View style={{ height: navigationBarHeight, width: rpxToPx(750), backgroundColor: '#fff' }} />
  340. {/* <View onClick={() => {
  341. setCloseGuide(true)
  342. }}>关闭</View> */}
  343. {
  344. user.isLogin && <View style={{
  345. position: 'absolute', left: 10, top: navigationBarHeight - 44, width: 44, height: 44,
  346. display: 'flex', alignItems: 'center', justifyContent: 'center'
  347. }}
  348. onClick={() => {
  349. // setCloseGuide(true)
  350. setShowGuide(false)
  351. }}
  352. >
  353. <IconClose color="#000" width={30} height={30} />
  354. </View>
  355. }
  356. <FriendGuide closeShare={() => {
  357. setTimeout(() => {
  358. setShowGuide(false)
  359. }, 500)
  360. }} />
  361. {
  362. process.env.TARO_ENV == 'weapp' && <TabBar index={4} />
  363. }</View>
  364. }
  365. function empty() {
  366. return <View style={{ position: process.env.TARO_ENV == 'weapp' ? 'fixed' : 'absolute', left: 0, top: 0, width: rpxToPx(750), height: process.env.TARO_ENV == 'weapp' ? '100vh' : screenHeight, zIndex: 100 }}>
  367. <View style={{ height: navigationBarHeight, width: rpxToPx(750), backgroundColor: '#fff' }} />
  368. {
  369. user.isLogin && <View style={{
  370. position: 'absolute', left: 10, top: navigationBarHeight - 44, width: 44, height: 44,
  371. display: 'flex', alignItems: 'center', justifyContent: 'center'
  372. }}
  373. onClick={() => {
  374. setCloseGuide(true)
  375. }}
  376. >
  377. <IconClose color="#000" width={30} height={30} />
  378. </View>
  379. }
  380. <EmptyContent friends={dashBoard.friends} />
  381. {
  382. process.env.TARO_ENV == 'weapp' && <TabBar index={4} />
  383. }
  384. </View>
  385. }
  386. function shareGuideContent() {
  387. console.log(shareInfo)
  388. return <Block><View className="share_guide_bg" style={{ top: 0 }} onClick={(e) => {
  389. if (process.env.TARO_ENV == 'weapp') {
  390. e.stopPropagation()
  391. }
  392. setShowShareGuide(false)
  393. }}>
  394. <View className="share_guide_card" onClick={(e) => {
  395. if (process.env.TARO_ENV == 'weapp') {
  396. e.stopPropagation()
  397. }
  398. }}>
  399. <Image className="share_guide_avatar" mode="aspectFill" src={shareInfo.join.user.avatar} />
  400. <View className="h34 bold" style={{ marginTop: rpxToPx(60), marginBottom: rpxToPx(60) }}>{shareTitle(t, shareInfo.join.user)}</View>
  401. <ShareBtn onClick={() => {
  402. setShowShareGuide(false)
  403. }}>
  404. <NewButton
  405. title="分享给微信好友"
  406. type={NewButtonType.fill}
  407. width={rpxToPx(480)}
  408. height={rpxToPx(96)}
  409. color={MainColorType.success}
  410. onClick={() => {
  411. }}
  412. />
  413. </ShareBtn>
  414. </View>
  415. </View>
  416. </Block>
  417. }
  418. function wxList() {
  419. return <ScrollView style={{
  420. marginTop: navigationBarHeight,
  421. height: '90vh'
  422. }}
  423. enableBackToTop
  424. ref={scrollRef}
  425. id="myscrollview"
  426. scrollY={showShareGuide ? false : true}
  427. refresherEnabled={true}
  428. upperThreshold={70}
  429. // scrollTop={showShareGuide ? pageTop : undefined}
  430. // lowerThreshold={140}
  431. refresherBackground={MainColorType.g05}
  432. onRefresherRefresh={onRefresh}
  433. refresherTriggered={isPulling}
  434. onScroll={onScroll}
  435. onScrollToUpper={() => {
  436. // setPage(1)
  437. // if (moments.length > 10) {
  438. // setMoments(moments.slice(0, 10))
  439. // setItemHeights(itemHeights.slice(0, 10))
  440. // setItemLayouts(itemLayouts.slice(0, 10))
  441. // }
  442. }}
  443. // onScrollToLower={props.loadMore}
  444. >
  445. <View style={{ backgroundColor: '#fff', minHeight: '100vh', paddingTop: rpxToPx(30), paddingBottom: 100 }}>
  446. {
  447. dashBoard && dashBoard.new_message && <View className="new_message_bg">
  448. <View className="new_message" onClick={() => {
  449. jumpPage('/_moment/pages/message')
  450. }}>
  451. {
  452. dashBoard.new_message.avatars.map((item, index) => {
  453. return <Image className="message_avatar" src={item} key={index} style={{ zIndex: 9 - index, marginLeft: index == 0 ? rpxToPx(8) : -15 }} />
  454. })
  455. }
  456. <View className="h26 bold" style={{ color: '#fff', minWidth: rpxToPx(260), textAlign: 'center' }}>{dashBoard.new_message.message_tip}</View>
  457. </View>
  458. </View>
  459. }
  460. {
  461. moments.map((item, index) => {
  462. if (itemLayouts.length >= index + 1 && pageTop > 0 && index > 5) {
  463. if (Math.abs(itemLayouts[index] - pageTop) > 2500) {
  464. return <View style={{ height: itemHeights[index] }} id={`history—temp-${index}`}>
  465. </View>
  466. }
  467. }
  468. return <View key={index} id={`history2-${index}`}>
  469. <MomentItem data={item} del={
  470. () => {
  471. var list = JSON.parse(JSON.stringify(moments))
  472. list.splice(index, 1)
  473. setMoments(list)
  474. }
  475. } />
  476. </View>
  477. })
  478. }
  479. {
  480. moments.length == 0 && <NoRecord style={{ marginTop: rpxToPx(160) }} />
  481. }
  482. <ListFooter noMore={noMore} loading={loading} />
  483. <View id="footer" style={{ width: 1, height: 1 }}></View>
  484. </View>
  485. </ScrollView>
  486. }
  487. function rnList() {
  488. return <FlatList
  489. style={{
  490. marginTop: navigationBarHeight,
  491. height: screenHeight - navigationBarHeight-(insets?insets.bottom:0)-40,
  492. backgroundColor: '#fff'
  493. }}
  494. data={moments}
  495. keyExtractor={(item,index) => {
  496. // console.log(item,index)
  497. return index
  498. }}
  499. renderItem={({ item, index }) => <MomentItem data={item} del={
  500. () => {
  501. var list = JSON.parse(JSON.stringify(moments))
  502. list.splice(index, 1)
  503. setMoments(list)
  504. }
  505. }
  506. />}
  507. refreshControl={
  508. <RefreshControl
  509. tintColor='black'
  510. colors={['black']} // 设置刷新指示器的颜色为白色
  511. progressBackgroundColor="black" // 设置刷新指示器的背景颜色为白色
  512. refreshing={isPulling}
  513. onRefresh={onRefresh}
  514. />
  515. }
  516. onEndReached={loadMore} // 上拉加载更多
  517. onEndReachedThreshold={0.5} // 当距离底部还有 50% 的高度时触发加载
  518. ListFooterComponent={<ListFooter noMore={noMore} loading={loading} />} // 加载指示器
  519. />
  520. }
  521. function listDetail() {
  522. return <View >
  523. <View style={{
  524. position: process.env.TARO_ENV == 'weapp' ? 'fixed' : 'absolute',
  525. top: 0,
  526. left: 0,
  527. zIndex: 10,
  528. height: navigationBarHeight, width: rpxToPx(750), backgroundColor: '#f5f5f5', display: 'flex',
  529. flexDirection: 'column', justifyContent: 'flex-end'
  530. }}>
  531. <View style={{ height: 44, width: rpxToPx(750), position: 'relative', display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }}>
  532. <View style={{ fontWeight: 'bold', }}>{t('health.moments')}</View>
  533. <View onClick={more} style={{ position: 'absolute', left: 10, top: 0, bottom: 0, width: 44, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
  534. <IconMenu color="#000" width={rpxToPx(40)} />
  535. </View>
  536. <View onClick={() => {
  537. setShowGuide(true)
  538. }} style={{ position: 'absolute', left: 54, top: 0, bottom: 0, width: 44, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
  539. <Image src={require('@assets/_health/wechat.png')} style={{ width: rpxToPx(48), height: rpxToPx(48) }} />
  540. {/* <Button openType="share" style={{ position: 'absolute', left: 0, right: 0, top: 0, bottom: 0, opacity: 0 }} /> */}
  541. </View>
  542. </View>
  543. </View>
  544. {
  545. process.env.TARO_ENV == 'weapp' ? wxList() : rnList()
  546. }
  547. <Block>
  548. {
  549. showShareGuide && <MomentDetailShare user={shareInfo.join.user} btnColor={getThemeColor(shareInfo.join.window)}
  550. cover={shareInfo.moment && shareInfo.moment.media && shareInfo.moment.media.length > 0 ? shareInfo.moment.media[0].url : null} />
  551. }
  552. </Block>
  553. <Block>
  554. {
  555. showShareGuide && shareGuideContent()
  556. }
  557. </Block>
  558. {
  559. process.env.TARO_ENV == 'weapp' && <TabBar index={4} />
  560. }
  561. {/* {
  562. homeType == 'NO_FRIEND' && !closeGuide && friendGuide()
  563. } */}
  564. {
  565. showGuide && friendGuide()
  566. }
  567. {
  568. homeType == 'NO_MOMENT' && !closeGuide && empty()
  569. }
  570. </View>
  571. }
  572. function content() {
  573. if (!loaded) {
  574. return <View >
  575. {
  576. process.env.TARO_ENV == 'weapp' && <TabBar index={4} />
  577. }
  578. </View>
  579. }
  580. if (!user.isLogin) {
  581. return friendGuide()
  582. }
  583. return listDetail()
  584. }
  585. return <View>
  586. {
  587. content()
  588. }
  589. {
  590. process.env.TARO_ENV == 'weapp' && <MomentShare />
  591. }
  592. </View>
  593. return <View>
  594. <ScrollView scrollY style={{ height: '100vh' }}>
  595. <Button openType="share">分享</Button>
  596. <View>好友数量{count}</View>
  597. {
  598. friends.map((item, index) => {
  599. return <View key={index}>
  600. <Image src={item.avatar} style={{ width: 70, height: 70 }} />
  601. <Text>{item.nickname}</Text>
  602. <Text>{item.relation}</Text>
  603. </View>
  604. })
  605. }
  606. <View style={{ height: '100vh', backgroundColor: 'pink', width: rpxToPx(750) }} id="a"></View>
  607. <View style={{ height: '100vh', backgroundColor: 'blue', width: rpxToPx(750) }} id="b"></View>
  608. <View style={{ height: '100vh', backgroundColor: 'yellow', width: rpxToPx(750) }} id="c"></View>
  609. <View style={{ height: '100vh', backgroundColor: 'green', width: rpxToPx(750) }} id="d"></View>
  610. <View style={{ height: '100vh', backgroundColor: 'red', width: rpxToPx(750) }} id="e"></View>
  611. </ScrollView>
  612. {
  613. process.env.TARO_ENV == 'weapp' && <TabBar index={4} />
  614. }
  615. </View>
  616. }