MainHistory.tsx 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809
  1. import { View, Text, Image } from "@tarojs/components";
  2. import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from "react";
  3. import { getLatestJournal, records } from "@/services/health";
  4. import './History.scss'
  5. import Calendar from "./calendar";
  6. import { useDispatch, useSelector } from "react-redux";
  7. import HistoryItem from "./HistoryItem";
  8. import { rpxToPx } from "@/utils/tools";
  9. import { jumpPage } from "../trackTimeDuration/hooks/Common";
  10. import Taro, { useReady } from "@tarojs/taro";
  11. import { getScenario, getThemeColor } from "./hooks/health_hooks";
  12. import { TimeFormatter } from "@/utils/time_format";
  13. import dayjs from "dayjs";
  14. import { MainColorType } from "@/context/themes/color";
  15. import { IconArrow, IconCellArrow, IconClose } from "@/components/basic/Icons";
  16. import NoRecord from "@/_health/components/no_record";
  17. import ListFooter from "@/_health/components/list_footer";
  18. import { useTranslation } from "react-i18next";
  19. import { setActiveTip, setEatTip, setFirstActiveId, setFirstEatId } from "@/store/health";
  20. import RightArrowRow from "@/_health/components/right_arrow_row";
  21. import NewButton, { NewButtonType } from "@/_health/base/new_button";
  22. import TimelineDate from "@/_health/components/timeline_date";
  23. let lastMode = ''
  24. let myScrollTop = 0
  25. export default forwardRef((props: { type?: string, fast_type?: string, updateDate?: any, refreshSuccess?: any }, ref) => {
  26. const [itemLayouts, setItemLayouts] = useState<any>([])
  27. const [itemHeights, setItemHeights] = useState<any>([])
  28. const [list, setList] = useState<any>([])
  29. const [page, setPage] = useState(1)
  30. const [total, setTotal] = useState(0)
  31. const [loaded, setLoaded] = useState(false)
  32. const health = useSelector((state: any) => state.health);
  33. const user = useSelector((state: any) => state.user);
  34. const [loading, setLoading] = useState(false)
  35. const [showEatArchive, setShowEatArchive] = useState(true)
  36. const [showActiveArchive, setShowActiveArchive] = useState(true)
  37. const [fastList, setFastList] = useState<any>([])
  38. const [eatList, setEatList] = useState<any>([])
  39. const [activeList, setActiveList] = useState<any>([])
  40. const [sleepList, setSleepList] = useState<any>([])
  41. const [fastTotal, setFastTotal] = useState(-1)
  42. const [eatTotal, setEatTotal] = useState(-1)
  43. const [activeTotal, setActiveTotal] = useState(-1)
  44. const [sleepTotal, setSleepTotal] = useState(-1)
  45. const [hideEatArchiveTip, setHideEatArchiveTip] = useState(false)
  46. const [hideActiveArchiveTip, setHideActiveArchiveTip] = useState(false)
  47. const [hideFastTip, setHideFastTip] = useState(false)
  48. const [hideSleepTip, setHideSleepTip] = useState(false)
  49. const [pageTop, setPageTop] = useState(0)
  50. const query = Taro.createSelectorQuery()
  51. const dispatch = useDispatch()
  52. const { t } = useTranslation()
  53. useImperativeHandle(ref, () => ({
  54. onScroll: onScroll,
  55. refresh: refresh,
  56. more: more
  57. }))
  58. useEffect(() => {
  59. if (list.length > 0) {
  60. setTimeout(() => {
  61. measureItemLayouts()
  62. }, 300)
  63. }
  64. }, [list])
  65. useEffect(() => {
  66. if (!user.isLogin) {
  67. setList([])
  68. }
  69. }, [user.isLogin])
  70. useEffect(()=>{
  71. return ()=>{
  72. myScrollTop = 0
  73. }
  74. },[])
  75. global.refreshHistory = () => {
  76. refresh()
  77. refreshItem('FAST')
  78. refreshItem('SLEEP')
  79. refreshItem('EAT')
  80. refreshItem('ACTIVE')
  81. }
  82. useEffect(() => {
  83. if (props.type) {
  84. loadData(1)
  85. }
  86. }, [props.type])
  87. useEffect(() => {
  88. if (lastMode != health.mode) {
  89. lastMode = health.mode
  90. // loadData(1)
  91. setPage(1)
  92. switch (health.mode) {
  93. case 'DAY':
  94. case 'NIGHT':
  95. setList([])
  96. return
  97. case 'FAST':
  98. if (fastList.length > 0) {
  99. setList(fastList)
  100. setTotal(fastTotal)
  101. return;
  102. }
  103. break
  104. case 'EAT':
  105. if (eatList.length > 0) {
  106. setList(eatList)
  107. setTotal(eatTotal)
  108. return;
  109. }
  110. break
  111. case 'SLEEP':
  112. if (sleepList.length > 0) {
  113. setList(sleepList)
  114. setTotal(sleepTotal)
  115. return;
  116. }
  117. break
  118. case 'ACTIVE':
  119. if (activeList.length > 0) {
  120. setList(activeList)
  121. setTotal(activeTotal)
  122. return;
  123. }
  124. break
  125. }
  126. loadData(1)
  127. }
  128. }, [health.mode])
  129. function measureItemLayouts() {
  130. list.forEach((item, index) => {
  131. query.select(`#history-${index}`).boundingClientRect()
  132. });
  133. query.exec((res) => {
  134. var layouts: any = []
  135. var heights: any = []
  136. res.forEach((rect, index) => {
  137. if (rect) {
  138. layouts[index] = rect.top + myScrollTop
  139. heights[index] = rect.height
  140. }
  141. });
  142. setItemLayouts(layouts)
  143. setItemHeights(heights)
  144. })
  145. }
  146. function onScroll(e) {
  147. // var top = e.detail.scrollTop
  148. // myScrollTop = top
  149. var top = e.detail.scrollTop - e.detail.deltaY
  150. myScrollTop = e.detail.scrollTop
  151. setPageTop(top)
  152. if (itemLayouts.length > 0) {
  153. var i = -1
  154. var date = ''
  155. list.forEach((item, index) => {
  156. if (top >= itemLayouts[index] - 50) {
  157. i = index
  158. if (TimeFormatter.isTimestampInThisWeek(item.window_range.start_timestamp)) {
  159. date = t('health.this_week')
  160. }
  161. else if (dayjs(item.window_range.start_timestamp).format('YYYY') == dayjs().format('YYYY')) {
  162. date = global.language == 'en' ? dayjs(item.window_range.start_timestamp).format('MMMM') : dayjs(item.window_range.start_timestamp).format('MMMM')
  163. }
  164. else {
  165. date = global.language == 'en' ? dayjs(item.window_range.start_timestamp).format('YYYY') : dayjs(item.window_range.start_timestamp).format('YYYY年')
  166. }
  167. }
  168. })
  169. if (props.updateDate) {
  170. props.updateDate({
  171. show: i != -1,
  172. date: date
  173. })
  174. }
  175. }
  176. else {
  177. if (props.updateDate) {
  178. props.updateDate({
  179. show: false,
  180. date: ''
  181. })
  182. }
  183. }
  184. }
  185. function refresh() {
  186. loadData(1)
  187. setPage(1)
  188. }
  189. function more() {
  190. if (loading) return;
  191. if (total == list.length) return;
  192. var index = page;
  193. index++;
  194. setPage(index)
  195. loadData(index)
  196. }
  197. function refreshItem(type) {
  198. setPage(1)
  199. var params: any = {
  200. window: type,
  201. limit: 10,
  202. page: 1
  203. }
  204. records(params).then(res => {
  205. var array = (res as any).data
  206. array.map(item => {
  207. var temps: any = []
  208. var lastType = ''
  209. var lastTextArray: any = []
  210. var lastImageArray: any = []
  211. item.events.map(event => {
  212. event.moments && event.moments.map(moment => {
  213. switch (moment.type) {
  214. case 'TEXT':
  215. {
  216. lastTextArray.push({
  217. title: moment.title,
  218. description: moment.description,
  219. event_id: event.id
  220. })
  221. if (lastType == 'PIC') {
  222. temps.push({
  223. type: 'PIC',
  224. data: JSON.parse(JSON.stringify(lastImageArray))
  225. })
  226. lastImageArray = []
  227. }
  228. lastType = 'TEXT'
  229. }
  230. break;
  231. case 'PIC':
  232. {
  233. lastImageArray.push(moment.media[0].url)
  234. if (lastType == 'TEXT') {
  235. temps.push({
  236. type: 'TEXT',
  237. data: JSON.parse(JSON.stringify(lastTextArray))
  238. })
  239. lastTextArray = []
  240. }
  241. lastType = 'PIC'
  242. }
  243. break;
  244. case 'PIC_TEXT':
  245. if (lastType == 'PIC') {
  246. temps.push({
  247. type: 'PIC',
  248. data: JSON.parse(JSON.stringify(lastImageArray))
  249. })
  250. lastImageArray = []
  251. }
  252. if (lastType == 'TEXT') {
  253. temps.push({
  254. type: 'TEXT',
  255. data: JSON.parse(JSON.stringify(lastTextArray))
  256. })
  257. lastTextArray = []
  258. }
  259. temps.push({
  260. type: 'PIC_TEXT',
  261. data: [
  262. {
  263. title: moment.title,
  264. description: moment.description,
  265. url: moment.media[0].url,
  266. urls:moment.media,
  267. event_id: event.id
  268. }
  269. ]
  270. })
  271. lastType = 'PIC_TEXT'
  272. break;
  273. }
  274. })
  275. })
  276. if (lastType == 'PIC') {
  277. temps.push({
  278. type: 'PIC',
  279. data: JSON.parse(JSON.stringify(lastImageArray))
  280. })
  281. lastImageArray = []
  282. }
  283. if (lastType == 'TEXT') {
  284. temps.push({
  285. type: 'TEXT',
  286. data: JSON.parse(JSON.stringify(lastTextArray))
  287. })
  288. lastTextArray = []
  289. }
  290. item.dataArray = temps;
  291. })
  292. switch (type) {
  293. case 'FAST':
  294. setFastList(array)
  295. setFastTotal((res as any).total)
  296. break
  297. case 'SLEEP':
  298. setSleepList(array)
  299. setSleepTotal((res as any).total)
  300. break
  301. case 'EAT':
  302. setEatList(array)
  303. setEatTotal((res as any).total)
  304. break
  305. case 'ACTIVE':
  306. setActiveList(array)
  307. setActiveTotal((res as any).total)
  308. break
  309. }
  310. })
  311. }
  312. function loadData(index: number) {
  313. // console.log('load data, page',index)
  314. if (index == 1) {
  315. Taro.setStorage({
  316. key: 'lastRefresh',
  317. data: new Date().getTime() + ''
  318. })
  319. }
  320. var params: any = {
  321. window: props.type ? props.type : health.mode,
  322. limit: 10,
  323. page: index
  324. }
  325. if (props.fast_type) {
  326. params.fast_type = props.fast_type
  327. }
  328. setPage(index)
  329. setLoading(true)
  330. records(params).then(res => {
  331. var array = (res as any).data
  332. array.map(item => {
  333. var temps: any = []
  334. var lastType = ''
  335. var lastTextArray: any = []
  336. var lastImageArray: any = []
  337. item.events.map(event => {
  338. event.moments && event.moments.map(moment => {
  339. switch (moment.type) {
  340. case 'TEXT':
  341. {
  342. lastTextArray.push({
  343. title: moment.title,
  344. description: moment.description,
  345. event_id: event.id
  346. })
  347. if (lastType == 'PIC') {
  348. temps.push({
  349. type: 'PIC',
  350. data: JSON.parse(JSON.stringify(lastImageArray))
  351. })
  352. lastImageArray = []
  353. }
  354. lastType = 'TEXT'
  355. }
  356. break;
  357. case 'PIC':
  358. {
  359. lastImageArray.push(moment.media[0].url)
  360. if (lastType == 'TEXT') {
  361. temps.push({
  362. type: 'TEXT',
  363. data: JSON.parse(JSON.stringify(lastTextArray))
  364. })
  365. lastTextArray = []
  366. }
  367. lastType = 'PIC'
  368. }
  369. break;
  370. case 'PIC_TEXT':
  371. if (lastType == 'PIC') {
  372. temps.push({
  373. type: 'PIC',
  374. data: JSON.parse(JSON.stringify(lastImageArray))
  375. })
  376. lastImageArray = []
  377. }
  378. if (lastType == 'TEXT') {
  379. temps.push({
  380. type: 'TEXT',
  381. data: JSON.parse(JSON.stringify(lastTextArray))
  382. })
  383. lastTextArray = []
  384. }
  385. temps.push({
  386. type: 'PIC_TEXT',
  387. data: [
  388. {
  389. title: moment.title,
  390. description: moment.description,
  391. url: moment.media[0].url,
  392. urls:moment.media,
  393. event_id: event.id
  394. }
  395. ]
  396. })
  397. lastType = 'PIC_TEXT'
  398. break;
  399. }
  400. })
  401. })
  402. if (lastType == 'PIC') {
  403. temps.push({
  404. type: 'PIC',
  405. data: JSON.parse(JSON.stringify(lastImageArray))
  406. })
  407. lastImageArray = []
  408. }
  409. if (lastType == 'TEXT') {
  410. temps.push({
  411. type: 'TEXT',
  412. data: JSON.parse(JSON.stringify(lastTextArray))
  413. })
  414. lastTextArray = []
  415. }
  416. item.dataArray = temps;
  417. })
  418. setLoading(false)
  419. setLoaded(true)
  420. if (index == 1) {
  421. // console.log(props.type,health.mode)
  422. if (!props.type && array.length >= 0) {
  423. if (health.mode == 'EAT') {
  424. setEatList(array)
  425. setList(array)
  426. setEatTotal((res as any).total)
  427. }
  428. else if (health.mode == 'ACTIVE') {
  429. setActiveList(array)
  430. setList(array)
  431. setActiveTotal((res as any).total)
  432. }
  433. else if (health.mode == 'FAST') {
  434. setFastList(array)
  435. setList(array)
  436. setFastTotal((res as any).total)
  437. }
  438. else if (health.mode == 'SLEEP') {
  439. setSleepList(array)
  440. setList(array)
  441. setSleepTotal((res as any).total)
  442. }
  443. }
  444. setTotal((res as any).total)
  445. if (props.refreshSuccess) {
  446. props.refreshSuccess()
  447. }
  448. }
  449. else {
  450. setList([...list, ...array])
  451. }
  452. }).catch(e => {
  453. setLoading(false)
  454. })
  455. }
  456. function historyMonth(index) {
  457. var showDate = false;
  458. var dateStr = ''
  459. if (index == 0) {
  460. var currentDate = global.language == 'en' ? dayjs(list[index].window_range.start_timestamp).format('YYYY') : dayjs(list[index].window_range.start_timestamp).format('YYYY年')
  461. var now = global.language == 'en' ? dayjs().format('YYYY') : dayjs().format('YYYY年')
  462. if (currentDate != now) {
  463. showDate = true
  464. dateStr = currentDate
  465. }
  466. }
  467. else {
  468. var currentDate = global.language == 'en' ? dayjs(list[index].window_range.start_timestamp).format('YYYY') : dayjs(list[index].window_range.start_timestamp).format('YYYY年')
  469. var now = global.language == 'en' ? dayjs(list[index - 1].window_range.start_timestamp).format('YYYY') : dayjs(list[index - 1].window_range.start_timestamp).format('YYYY年')
  470. if (currentDate != now) {
  471. showDate = true
  472. dateStr = currentDate
  473. }
  474. }
  475. if (showDate) {
  476. return <View className="history_year_month h42 bold" style={{ marginBottom: rpxToPx(60) }}>{dateStr}</View>
  477. }
  478. return <View />
  479. }
  480. function hideLine(index) {
  481. var currentDate = dayjs(list[index].window_range.start_timestamp).format('YYYY年M月D日')
  482. if (list.length > index + 1) {
  483. var nextDate = dayjs(list[index + 1].window_range.start_timestamp).format('YYYY年M月D日')
  484. if (currentDate == nextDate) return true
  485. }
  486. return false
  487. }
  488. if (!loaded || health.mode == 'DAY' || health.mode == 'NIGHT')
  489. return <View />
  490. if (!user.isLogin) return <View />
  491. function showTipF() {
  492. var showTip = false
  493. if (getScenario(health.windows, health.mode).status == 'OG') {
  494. if (health.mode == 'EAT') {
  495. showTip = !global.hideEatArchiveTip
  496. }
  497. else if (health.mode == 'ACTIVE') {
  498. showTip = !global.hideActiveArchiveTip
  499. }
  500. }
  501. return showTip
  502. }
  503. function newJournalTip() {
  504. if (!props.type) {
  505. var show = false
  506. if (health.mode == 'EAT' && health.eat_journal_tip) {
  507. show = true
  508. }
  509. else if (health.mode == 'ACTIVE' && health.active_journal_tip) {
  510. show = true
  511. }
  512. if (show) {
  513. return <View style={{
  514. display: 'flex',
  515. flexDirection: 'column',
  516. alignItems: 'center',
  517. paddingTop: rpxToPx(82),
  518. paddingBottom: rpxToPx(82),
  519. backgroundColor: '#fff',
  520. position: 'relative'
  521. }}>
  522. <View className="archived_bg" onClick={() => {
  523. // jumpPage('/_health/pages/archive')
  524. var data = list[0]
  525. jumpPage(`/_health/pages/timeline_detail?window_id=${data.window_id}&type=recent&isfastsleep=0&timestamp=${data.publish.timestamp}`)
  526. // getLatestJournal(false, {
  527. // id: health.mode == 'EAT' ? global.eatTipId : global.activeTipId,
  528. // user_confirmed: true
  529. // }).then(res => {
  530. // })
  531. setTimeout(() => {
  532. if (health.mode == 'EAT') {
  533. dispatch(setEatTip(false))
  534. }
  535. else {
  536. dispatch(setActiveTip(false))
  537. }
  538. }, 1000)
  539. }}>
  540. <Text className="archived_text bold" style={{ color: getThemeColor(health.mode) }}>{t('health.new_journal_created')}</Text>
  541. {/* {
  542. health.eatArchived.images.map((item, index) => {
  543. return <Image src={item} key={index} className="archived_img" mode="aspectFill" />
  544. })
  545. } */}
  546. <IconArrow color={MainColorType.g02} width={rpxToPx(34)} />
  547. </View>
  548. <View className="border_footer_line" />
  549. </View>
  550. // return <View className="h28 bold"
  551. // onClick={()=>{
  552. // if (health.mode == 'EAT'){
  553. // dispatch(setEatTip(false))
  554. // }
  555. // else {
  556. // dispatch(setActiveTip(false))
  557. // }
  558. // }}
  559. // style={{
  560. // width:rpxToPx(750),
  561. // height:rpxToPx(156),
  562. // display:'flex',
  563. // alignItems:'center',
  564. // justifyContent:'center',
  565. // backgroundColor:'#fff',
  566. // color:getThemeColor(health.mode),
  567. // }}>
  568. // New Journal Created {'>'}
  569. // </View>
  570. }
  571. }
  572. return <View />
  573. }
  574. function markDoneTip() {
  575. if (health.mode == 'DAY' && health.mode != 'NIGHT') return
  576. var scenario = getScenario(health.windows, health.mode)
  577. if (scenario.status != 'OG') return
  578. if (health.mode == 'EAT' && hideEatArchiveTip) return
  579. if (health.mode == 'ACTIVE' && hideActiveArchiveTip) return
  580. if (health.mode == 'FAST' && hideFastTip) return
  581. if (health.mode == 'SLEEP' && hideSleepTip) return
  582. function tipContent() {
  583. var strTime = ''
  584. var today = new Date().getDate()
  585. var date = new Date(scenario.archive_timestamp).getDate()
  586. var time = dayjs(scenario.archive_timestamp).format('HH:mm')
  587. if (today == date) {
  588. strTime = t('health.today_at', { time: time })
  589. if (global.language == 'en') {
  590. if (time == '23:59') {
  591. strTime = 'at midnight'
  592. }
  593. else {
  594. strTime = `today at ${time}`
  595. }
  596. }
  597. }
  598. else {
  599. strTime = t('health.tomorrow_at', { time: time })
  600. if (global.language == 'en') {
  601. strTime = `tomorrow at ${time}`
  602. }
  603. }
  604. switch (health.mode) {
  605. case 'FAST':
  606. if (global.language == 'en') {
  607. return <Text className="h26 g01"><Text className="bold">Today's Moments</Text> will appear in Recents when you <Text className="italic">log end fast</Text>.</Text>
  608. }
  609. return <Text className="h26 g01"><Text className="bold">今天的时刻</Text> 将在您 <Text className="italic">记录结束断食</Text> 之际,出现在最近记录中。</Text>
  610. case 'SLEEP':
  611. if (global.language == 'en') {
  612. return <Text className="h26 g01"><Text className="bold">Today's Moments</Text> will appear in Recents when you <Text className="italic">log wake up</Text>.</Text>
  613. }
  614. return <Text className="h26 g01"><Text className="bold">今天的时刻</Text> 将在您 <Text className="italic">记录起床</Text> 之际,出现在最近记录中。</Text>
  615. case 'EAT':
  616. case 'ACTIVE':
  617. if (global.language == 'en') {
  618. return <Text className="h26 g01"><Text className="bold">Today's Moments</Text> will appear in Recents {strTime} or when you <Text className="italic">mark done</Text>.</Text>
  619. }
  620. return <Text className="h26 g01"><Text className="bold">今天的时刻</Text> 将在今夜或在您 <Text className="italic">标记完成</Text> 之际,出现在最近记录中。</Text>
  621. }
  622. return <Text className="h26">1</Text>
  623. }
  624. return <View className="mark_done_tip" style={{
  625. backgroundColor: '#fff'//getThemeColor(health.mode) + '1A'
  626. }}>
  627. <View style={{ display: 'flex', flexDirection: 'column', flex: 1 }}>
  628. {
  629. tipContent()
  630. }
  631. </View>
  632. <NewButton type={NewButtonType.img} btnStyle={{
  633. paddingLeft: 20,
  634. height: rpxToPx(32),
  635. width: rpxToPx(32)
  636. }} onClick={() => {
  637. switch (health.mode) {
  638. case 'FAST':
  639. setHideFastTip(true)
  640. break;
  641. case 'EAT':
  642. setHideEatArchiveTip(true)
  643. break;
  644. case 'SLEEP':
  645. setHideSleepTip(true)
  646. break
  647. case 'ACTIVE':
  648. setHideActiveArchiveTip(true)
  649. break
  650. }
  651. }}>
  652. <IconClose color={MainColorType.g03} width={rpxToPx(32)} height={rpxToPx(32)} />
  653. </NewButton>
  654. <View className="border_footer_line" />
  655. </View>
  656. }
  657. return <View style={{ width: rpxToPx(750) }}>
  658. {
  659. (list.length >= 0 || health.mode == 'EAT' || health.mode == 'ACTIVE') && <View className="new_header_bg2">
  660. <Text className="h50 bold">{t('health.recents')}</Text>
  661. {
  662. (health.mode == 'EAT' || health.mode == 'ACTIVE') && <View style={{ marginTop: rpxToPx(0) }}><RightArrowRow
  663. height={rpxToPx(50)}
  664. title={t('health.my_journal')}
  665. bgColor="transparent"
  666. onClick={() => {
  667. var showBadge = (health.mode == 'EAT' && health.eat_journal_tip) ||
  668. (health.mode == 'ACTIVE' && health.active_journal_tip)
  669. jumpPage('/pages/account/Journal?type=' + health.mode + `&show_tip=${showTipF() && false ? '1' : '0'}&show_badge=${showBadge ? 1 : 0}`)
  670. }} />
  671. </View>
  672. }
  673. </View>
  674. }
  675. {
  676. markDoneTip()
  677. }
  678. {
  679. list.length == 0 && <NoRecord />
  680. }
  681. {
  682. list.length > 0 && <View style={{ minHeight: rpxToPx(464), backgroundColor: '#fff', paddingTop: rpxToPx(60) }}>
  683. {
  684. list.map((item, index) => {
  685. if (itemLayouts.length >= index + 1 && pageTop > 0) {
  686. if (Math.abs(itemLayouts[index] - pageTop) > 3000) {
  687. return <View style={{ height: itemHeights[index] }} id={`history-${index}`}>
  688. {/* {index} */}
  689. </View>
  690. }
  691. if (Math.abs(itemLayouts[index] - pageTop) > 1500) {
  692. return <View style={{
  693. height: itemHeights[index], display: 'flex',
  694. paddingLeft: rpxToPx(40),
  695. paddingRight: rpxToPx(40),
  696. boxSizing: 'border-box',
  697. flexDirection: 'row'
  698. }} id={`history-${index}`}>
  699. <TimelineDate timestamp={item.window_range.start_timestamp}
  700. pre_timestamp={index > 0 ? list[index - 1].window_range.start_timestamp : null}
  701. />
  702. <View style={{
  703. display: 'flex', flexDirection: 'column', flex: 1,
  704. width: rpxToPx(552), height: itemHeights[index] - rpxToPx(60), backgroundColor: '#fafafa'
  705. }}>
  706. </View>
  707. </View>
  708. }
  709. }
  710. return <View id={`history-${index}`} key={index}>
  711. {
  712. historyMonth(index)
  713. }
  714. <HistoryItem
  715. data={item}
  716. preData={index > 0 ? list[index - 1] : null}
  717. index={index}
  718. mode={props.type ?? health.mode}
  719. fast_type={props.fast_type}
  720. type={props.type}
  721. hideLine={hideLine(index)}
  722. onClick={() => {
  723. }} />
  724. </View>
  725. })
  726. }
  727. </View>
  728. }
  729. {/* <View style={{ height: rpxToPx(40), flexShrink: 0, backgroundColor: '#fff' }} /> */}
  730. <ListFooter noMore={(list.length > 0) && (total == list.length)} loading={loading} />
  731. </View>
  732. })