IndexItem.tsx 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. import { View, Text, Image } from "@tarojs/components";
  2. import { dotIsOuterRange, getBgRing, getCommon, getDot, getReal, getSchedule, getTarget, timeTotimestamp } from "../hooks/RingData";
  3. import { RealRing, CurrentDot } from "@/features/trackTimeDuration/components/Rings";
  4. import Rings from "./Rings";
  5. import './IndexItem.scss'
  6. import { useTranslation } from "react-i18next";
  7. import { ColorType } from "@/context/themes/color";
  8. import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
  9. import { TimeFormatter } from "@/utils/time_format";
  10. import { useSelector } from "react-redux";
  11. import { useEffect, useState } from "react";
  12. import Taro from "@tarojs/taro";
  13. import Modal from "@/components/layout/Modal.weapp";
  14. import { ModalType } from "@/utils/types";
  15. import TimelineStage from "./TimelineStage";
  16. let useNavigation;
  17. if (process.env.TARO_ENV == 'rn') {
  18. useNavigation = require("@react-navigation/native").useNavigation
  19. }
  20. let popTimer;
  21. let currentRecordTemp;
  22. export default function Component(props: { type: string, data: any, time: any, showStage?: boolean }) {
  23. const { t } = useTranslation()
  24. const [record, setRecord] = useState(props.data.current_record);
  25. const user = useSelector((state: any) => state.user);
  26. const dayNight = useSelector((state: any) => state.dayNight);
  27. const [stageList, setStageList] = useState([true, false, false])
  28. const [isStageMode, setIsStageMode] = useState(false)
  29. let navigation;
  30. if (useNavigation) {
  31. navigation = useNavigation()
  32. }
  33. useEffect(() => {
  34. setRecord(props.data.current_record)
  35. currentRecordTemp = props.data.current_record
  36. }, [props.data])
  37. useEffect(() => {
  38. if (props.type == 'FAST_SLEEP') {
  39. global.updateMixItem = (data) => {
  40. setStageList(data)
  41. }
  42. global.changeMixIndex = (index) => {
  43. setIsStageMode(index == 1)
  44. }
  45. }
  46. }, [])
  47. function durationArc(start_time: number, end_time: number) {
  48. var duration = (end_time - start_time) / 1000;
  49. return duration / (24 * 3600) * 2 * Math.PI;
  50. }
  51. const startArc = (time: number) => {
  52. var date = new Date(time);
  53. var hour = date.getHours();
  54. var minute = date.getMinutes();
  55. var second = date.getSeconds();
  56. return (hour * 3600 + minute * 60 + second) / (24 * 3600) * 2 * Math.PI - Math.PI / 2.0;
  57. }
  58. function bigRing() {
  59. var common = getCommon(null, true)
  60. common.radius = 42;
  61. common.lineWidth = 9;
  62. var bgRing = getBgRing()
  63. var currentDot1 = getDot(record, true)
  64. var targetBigRing1 = getTarget(record, true)
  65. if (record.status == 'ONGOING') {
  66. var realRing1 = getReal(record, true, false)
  67. return <Rings common={common} bgRing={bgRing} currentDot={currentDot1} realRing={realRing1} targetRing={targetBigRing1} canvasId={props.type + props.time + 'big'} />
  68. }
  69. if (record.status == 'WAIT_FOR_START') {
  70. var realRing1 = getSchedule(props.data.scenario, props.type != 'SLEEP', true, true)//getSchedule(record, props.type != 'SLEEP', true)
  71. var list: any = []
  72. if (props.type == 'FAST_SLEEP') {
  73. realRing1.color = ColorType.fast + '66'
  74. if (dotIsOuterRange(true, record.fast)) {
  75. currentDot1.color = ColorType.ring
  76. }
  77. var detail = timeTotimestamp(props.data.scenario)
  78. if (stageList[0]) {
  79. const realRingBig: RealRing = {
  80. color: global.fastColor ? global.fastColor : ColorType.fast,
  81. startArc: startArc(detail.fast.target_start_time),
  82. durationArc: durationArc(detail.fast.target_start_time, detail.sleep.target_start_time)
  83. }
  84. list.push(realRingBig)
  85. }
  86. if (stageList[1]) {
  87. const realRingBig: RealRing = {
  88. color: global.fastColor ? global.fastColor : ColorType.fast,
  89. startArc: startArc(detail.sleep.target_start_time),
  90. durationArc: durationArc(detail.sleep.target_start_time, detail.sleep.target_end_time)
  91. }
  92. list.push(realRingBig)
  93. }
  94. if (stageList[2]) {
  95. const realRingBig: RealRing = {
  96. color: global.fastColor ? global.fastColor : ColorType.fast,
  97. startArc: startArc(detail.sleep.target_end_time),
  98. durationArc: durationArc(detail.sleep.target_end_time, detail.fast.target_end_time)
  99. }
  100. list.push(realRingBig)
  101. }
  102. }
  103. if (!isStageMode) {
  104. list = []
  105. }
  106. return <Rings common={common} bgRing={bgRing} currentDot={isStageMode ? null : currentDot1} stageList={list} realRing={realRing1} canvasId={props.type + props.time + 'big'} />
  107. }
  108. var realRing1 = getReal(record, true, false)
  109. return <Rings common={common} bgRing={bgRing} realRing={realRing1} currentDot={currentDot1} targetRing={targetBigRing1} canvasId={props.type + props.time + 'big'} />
  110. }
  111. function smallRing() {
  112. var common = getCommon(null, false)
  113. common.radius = 28;
  114. common.lineWidth = 9;
  115. var bgRing = getBgRing()
  116. var realRing = getReal(record, false, false)
  117. if (props.type == 'SLEEP' || props.type == 'FAST_SLEEP') {
  118. if (record.sleep.status == 'WAIT_FOR_END') {
  119. var targetBigRing1 = getTarget(record, false)
  120. targetBigRing1.color = ColorType.sleep + '66'
  121. var currentDot = getDot(record, false)
  122. realRing.durationArc = durationArc(record.sleep.target_start_time, (new Date()).getTime())
  123. return <Rings common={common} bgRing={bgRing} currentDot={currentDot} canvasId={props.type + props.time + 'small'} targetRing={targetBigRing1} realRing={realRing} />
  124. }
  125. else if (record.status == 'WAIT_FOR_START' || record.status == 'ONGOING1') {
  126. realRing = getSchedule(props.data.scenario, false, true, true)//getSchedule(record, false, true)
  127. var currentDot = getDot(record, false)
  128. if (dotIsOuterRange(true, record.sleep)) {
  129. currentDot.color = ColorType.ring
  130. }
  131. return <Rings common={common} bgRing={bgRing} currentDot={isStageMode ? null : currentDot} realRing={realRing} canvasId={props.type + props.time + 'small'} />
  132. }
  133. else if (record.sleep.status == 'NOT_COMPLETED') {
  134. realRing.durationArc = 0.01
  135. var currentDot = getDot(record, false)
  136. return <Rings common={common} bgRing={bgRing} currentDot={currentDot} canvasId={props.type + props.time + 'small'} realRing={realRing} />
  137. }
  138. else if (record.sleep.status == 'COMPLETED') {
  139. realRing = getReal(record, false, true)
  140. return <Rings common={common} bgRing={bgRing} canvasId={props.type + props.time + 'small'} realRing={realRing} />
  141. }
  142. else if (record.sleep.status == 'ONGOING2') {
  143. var currentDot = getDot(record, false)
  144. return <Rings common={common} bgRing={bgRing} currentDot={currentDot} canvasId={props.type + props.time + 'small'} />
  145. }
  146. return <Rings common={common} bgRing={bgRing} canvasId={props.type + props.time + 'small'} />
  147. }
  148. else {
  149. var currentDot = getDot(record, false)
  150. var targetRing = getTarget(record, false)
  151. if (record.status == 'ONGOING2') {
  152. var realRing = getReal(record, false, false)
  153. return <Rings common={common} bgRing={bgRing} realRing={realRing} currentDot={currentDot} targetRing={targetRing} canvasId={props.type + props.time + 'small'} />
  154. }
  155. if (record.status == 'ONGOING3') {
  156. currentDot.color = 'rgba(0, 255, 255, 0.5)'
  157. }
  158. return <Rings common={common} bgRing={bgRing} currentDot={currentDot} canvasId={props.type + props.time + 'small'} />
  159. }
  160. }
  161. function dayRing() {
  162. var common = getCommon(null, true)
  163. common.radius = 56;
  164. common.lineWidth = 9;
  165. var bgRing = getBgRing()
  166. const realRingBig: RealRing = {
  167. color: ColorType.night + '66',
  168. startArc: 0,
  169. durationArc: 2
  170. }
  171. var sunRise = 24 * 60 + 6 * 60
  172. var sunSet = 18 * 60
  173. if (dayNight.gpsInfo && user.test_user) {
  174. var sunRiseObj = dayNight.gpsInfo.daylights[0].sunrise
  175. var sunSetObj = dayNight.gpsInfo.daylights[0].sunset
  176. sunRise = 24 * 60 + parseInt(sunRiseObj.split(':')[0]) * 60 + parseInt(sunRiseObj.split(':')[1])
  177. sunSet = parseInt(sunSetObj.split(':')[0]) * 60 + parseInt(sunSetObj.split(':')[1])
  178. if (sunSetObj.indexOf('PM') != -1) {
  179. sunSet += 12 * 60
  180. }
  181. }
  182. var duration = sunRise - sunSet
  183. realRingBig.startArc = (sunSet * 60) / (24 * 3600) * 2 * Math.PI - Math.PI / 2.0;
  184. realRingBig.durationArc = (duration * 60) / (24 * 3600) * 2 * Math.PI;
  185. var currentDot = getDot(record, false)
  186. if (dotIsOuterRange(false, null, { sunrise: dayNight.sunRise, sunset: dayNight.sunSet })) {
  187. currentDot.color = ColorType.ring
  188. }
  189. else {
  190. currentDot.color = ColorType.night + '66'
  191. }
  192. return <Rings common={common} bgRing={bgRing} realRing={realRingBig} currentDot={currentDot} canvasId={props.type + props.time + 'day'} />
  193. }
  194. function rings() {
  195. return <View style={{ position: 'relative', zIndex: 1 }}>
  196. {
  197. bigRing()
  198. }
  199. {
  200. props.type == 'FAST_SLEEP' && <View style={{ display: 'flex', position: 'absolute', left: 0, right: 0, top: 0, bottom: 0, alignItems: 'center', justifyContent: 'center' }}>
  201. {
  202. smallRing()
  203. }
  204. </View>
  205. }
  206. {
  207. props.type == 'FAST_SLEEP' && !props.showStage && user.isLogin && global.showNightRing === true && <View style={{ display: 'flex', position: 'absolute', left: -14, top: -14, right: -14, bottom: -14 }}>
  208. {
  209. dayRing()
  210. }
  211. </View>
  212. }
  213. </View>
  214. }
  215. function getDuration(obj) {
  216. if (!obj) {
  217. }
  218. if (obj.status == 'NOT_STARTED' || obj.status == 'NOT_COMPLETED') {
  219. return ''
  220. }
  221. var start = obj.real_start_time
  222. var end = obj.real_end_time
  223. if (!end) {
  224. end = (new Date()).getTime()
  225. }
  226. if (obj.status == 'WAIT_FOR_START') {
  227. start = obj.target_start_time
  228. end = obj.target_end_time
  229. }
  230. return TimeFormatter.durationFormate(start, end)
  231. // return TimeFormatter.calculateTimeDifference(start, end)
  232. }
  233. function fastDuration() {
  234. if (record.fast.status == 'WAIT_FOR_END') {
  235. return TimeFormatter.formateTimeDifference(record.fast.real_start_time, new Date().getTime(), false)
  236. }
  237. if (isStageMode && record.scenario == 'FAST_SLEEP') {
  238. if (stageList[0]) {
  239. return TimeFormatter.durationFormate(record.fast.target_start_time, record.sleep.target_start_time)
  240. }
  241. if (stageList[1]) {
  242. return TimeFormatter.durationFormate(record.sleep.target_start_time, record.sleep.target_end_time)
  243. }
  244. if (stageList[2]) {
  245. return TimeFormatter.durationFormate(record.sleep.target_end_time, record.fast.target_end_time)
  246. }
  247. }
  248. return getDuration(record.fast)
  249. }
  250. function sleepDuration() {
  251. if (record.sleep.status == 'WAIT_FOR_END') {
  252. return TimeFormatter.formateTimeDifference(record.sleep.real_start_time, new Date().getTime(), false)
  253. }
  254. return getDuration(record.sleep)
  255. }
  256. function goClock() {
  257. if (!user.isLogin) {
  258. jumpPage('/pages/account/ChooseAuth', 'ChooseAuth', navigation)
  259. return
  260. }
  261. if (props.showStage) {
  262. return
  263. }
  264. var node = schedules()
  265. global.showIndexModal3(true, node, null);
  266. popTimer = setInterval(() => {
  267. var node = schedules()
  268. global.showIndexModal3(true, node, null);
  269. }, 1000)
  270. global.popTimer = popTimer
  271. }
  272. function nightDuration() {
  273. if (dayNight.gpsInfo && dayNight.isMember) {
  274. var sunRiseObj = dayNight.gpsInfo.daylights[0].sunrise
  275. var sunSetObj = dayNight.gpsInfo.daylights[0].sunset
  276. var sunRise = 24 * 60 + parseInt(sunRiseObj.split(':')[0]) * 60 + parseInt(sunRiseObj.split(':')[1])
  277. var sunSet = parseInt(sunSetObj.split(':')[0]) * 60 + parseInt(sunSetObj.split(':')[1])
  278. if (sunSetObj.indexOf('PM') != -1) {
  279. sunSet += 12 * 60
  280. }
  281. var duration = (sunRise - sunSet) * 60 * 1000
  282. return TimeFormatter.calculateTimeDifference(new Date().getTime(), new Date().getTime() + duration);
  283. } else {
  284. return '12小时'
  285. }
  286. }
  287. function schedules() {
  288. var timestamp = new Date().getTime()//props.data.first_real_check_time
  289. return <View style={{ display: 'flex', flexDirection: 'column' }}>
  290. <TimelineStage data={currentRecordTemp} title={t('feature.track_time_duration.record_fast_sleep.pop_title')}
  291. subTitle='今天' first_real_check_time={timestamp} />
  292. </View>
  293. }
  294. function fastPicker() {
  295. var node = schedules()
  296. global.showIndexModal2(true, node, null);
  297. popTimer = setInterval(() => {
  298. var node = schedules()
  299. global.showIndexModal2(true, node, null);
  300. }, 1000)
  301. global.popTimer = popTimer
  302. }
  303. function sleepPicker(e) {
  304. if (record.status == 'ONGOING3') {
  305. return;
  306. }
  307. if (record.status == 'WAIT_FOR_START') {
  308. Taro.showToast({
  309. title: t('feature.track_time_duration.common.start_fasting_first'),
  310. icon: 'none'
  311. })
  312. return;
  313. }
  314. var node = schedules()
  315. global.showIndexModal2(true, node, null);
  316. popTimer = setInterval(() => {
  317. var node = schedules()
  318. global.showIndexModal2(true, node, null);
  319. }, 1000)
  320. global.popTimer = popTimer
  321. }
  322. return <View className="time_operate_item">
  323. <View className="fast_sleep_item">
  324. {
  325. rings()
  326. }
  327. <View className="duration_bg">
  328. {
  329. props.type == 'FAST_SLEEP' && !props.showStage && user.isLogin && global.showNightRing === true &&
  330. <Text className="duration_title">{t('feature.common.overnight')}</Text>
  331. }
  332. {
  333. props.type == 'FAST_SLEEP' && !props.showStage && user.isLogin && global.showNightRing === true &&
  334. <Text className="duration_value" style={{ color: ColorType.night }}>{nightDuration()}</Text>
  335. }
  336. {
  337. (props.type == 'FAST' || props.type == 'FAST_SLEEP') && <Text className="duration_title" onClick={fastPicker}>{t('feature.track_time_duration.record_fast_sleep.item.fast')}</Text>
  338. }
  339. {
  340. (props.type == 'FAST' || props.type == 'FAST_SLEEP') && <Text className="duration_value" onClick={fastPicker} style={{ color: global.fastColor ? global.fastColor : ColorType.fast }}>{fastDuration()}</Text>
  341. }
  342. {
  343. (props.type == 'SLEEP' || props.type == 'FAST_SLEEP') && <Text className="duration_title" onClick={sleepPicker}>{t('feature.track_time_duration.record_fast_sleep.item.sleep')}</Text>
  344. }
  345. {
  346. (props.type == 'SLEEP' || props.type == 'FAST_SLEEP') && <Text className="duration_value" onClick={sleepPicker} style={{ color: global.sleepColor ? global.sleepColor : ColorType.sleep }}>{sleepDuration()}</Text>
  347. }
  348. </View>
  349. {/* <Image className="arrow1" src={require('@/assets/images/arrow.png')} /> */}
  350. <View className="record_arrow_bg" style={{ backgroundColor: global.isDebug ? 'red' : 'transparent' }} onClick={goClock}>
  351. <View style={{ flex: 1 }} />
  352. {/* <Text className='recordTime'>{getArrowText()}</Text> */}
  353. <Image className="arrow2" src={require('@/assets/images/arrow3.png')} />
  354. </View>
  355. {/* <t-popup></t-popup> */}
  356. </View>
  357. </View>
  358. }