IndexItem.tsx 16 KB

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