RecordFastSleep的副本.tsx 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. import Box from "@/components/layout/Box";
  2. import Header from "@/components/layout/Header";
  3. import Modal from "@/components/layout/Modal";
  4. import RecordItem from "@/features/common/RecordItem";
  5. import { delRecord } from "@/services/trackTimeDuration";
  6. import { ModalType } from "@/utils/types";
  7. import { View, Text, Image } from "@tarojs/components";
  8. import Taro from "@tarojs/taro";
  9. import { useEffect, useState } from "react";
  10. import TimelineFastSleep from "./TimelineFastSleep";
  11. import { TimeFormatter } from "@/utils/time_format";
  12. import './RecordFastSleep.scss'
  13. import { bigRingRadius, getBgRing, getCommon, getDot, getReal, getTarget, ringWidth, smallRingRadius } from "../hooks/RingData";
  14. import Rings from "./Rings";
  15. import Segment from "@/components/navigation/Segment";
  16. import Stage from "./Stage";
  17. import CenterContentTitleModal from "@/features/common/CenterContentTitleModal";
  18. import { useTranslation } from "react-i18next";
  19. import { ColorType } from "@/context/themes/color";
  20. import TimelineStage from "./TimelineStage";
  21. import { jumpPage } from "../hooks/Common";
  22. // import { sqrt } from 'mathjs'
  23. let AppState;
  24. if (process.env.TARO_ENV == 'rn') {
  25. AppState = require("react-native").AppState
  26. }
  27. export default function RecordFastSleep(props: { data: any, type: string, delSuccess?: Function, index: number }) {
  28. const [showDetailModal, setShowDetailModal] = useState(false)
  29. const [segmentIndex, setSegmentIndex] = useState(0)
  30. const [diffTimeZone, setDiffTimeZone] = useState(false)
  31. const [multiTimeZone, setMultiTimeZone] = useState(false)
  32. const { t } = useTranslation()
  33. var canvasId = props.data.id
  34. const record = props.data;
  35. const handleAppStateChange = (nextAppState) => {
  36. checkTimezone()
  37. };
  38. useEffect(() => {
  39. checkTimezone()
  40. if (process.env.TARO_ENV == 'rn') {
  41. AppState.addEventListener('change', handleAppStateChange);
  42. }
  43. // console.log(sqrt(-4).toString())
  44. }, [props.data])
  45. function checkTimezone() {
  46. var split = new Date().toString().split(' ');
  47. var currentTZ = split[split.length - 2];
  48. var isDiff = false;
  49. var isMulti = false;
  50. var tempTZ = '';
  51. if (props.data.fast) {
  52. if (props.data.fast.real_start_time_zone) {
  53. tempTZ = props.data.fast.real_start_time_zone
  54. if (props.data.fast.real_start_time_zone != currentTZ) {
  55. isDiff = true
  56. }
  57. }
  58. if (props.data.fast.real_end_time_zone) {
  59. if (tempTZ != props.data.fast.real_end_time_zone) {
  60. isMulti = true
  61. }
  62. if (props.data.fast.real_end_time_zone != currentTZ) {
  63. isDiff = true
  64. }
  65. }
  66. }
  67. if (props.data.sleep) {
  68. if (props.data.sleep.real_start_time_zone) {
  69. if (tempTZ == '') {
  70. tempTZ = props.data.sleep.real_start_time_zone
  71. }
  72. else if (tempTZ != props.data.sleep.real_start_time_zone) {
  73. isMulti = true
  74. }
  75. if (props.data.sleep.real_start_time_zone != currentTZ) {
  76. isDiff = true
  77. }
  78. }
  79. if (props.data.sleep.real_end_time_zone) {
  80. if (tempTZ != props.data.sleep.real_end_time_zone) {
  81. isMulti = true
  82. }
  83. if (props.data.sleep.real_end_time_zone != currentTZ) {
  84. isDiff = true
  85. }
  86. }
  87. }
  88. setDiffTimeZone(isDiff)
  89. setMultiTimeZone(isMulti)
  90. }
  91. function del() {
  92. var id = props.data.id
  93. delRecord(id
  94. ).then(res => {
  95. global.refreshTime()
  96. Taro.showToast({
  97. title: t('page.records_history.del_success')
  98. })
  99. props.delSuccess && props.delSuccess(props.data)
  100. // Taro.navigateBack()
  101. })
  102. }
  103. function subTitle(timestamp) {
  104. if (multiTimeZone) {
  105. return t('feature.common.multi_timezones')
  106. }
  107. if (diffTimeZone) {
  108. return t('feature.common.different_timezone')
  109. }
  110. return TimeFormatter.getDateAndWeek(timestamp)
  111. }
  112. function schedules() {
  113. var timestamp = props.data.first_real_check_time
  114. return <View style={{ display: 'flex', flexDirection: 'column' }}>
  115. <TimelineStage data={props.data} title={t('feature.track_time_duration.record_fast_sleep.pop_title')}
  116. subTitle={subTitle(timestamp)} first_real_check_time={timestamp} />
  117. </View>
  118. }
  119. function showDetail(e) {
  120. if (props.type == 'latest') {
  121. setSegmentIndex(0)
  122. global.segmentIndex = 0
  123. setShowDetailModal(true)
  124. return;
  125. }
  126. setShowDetailModal(true)
  127. }
  128. function getDuration(obj) {
  129. if (!obj) {
  130. }
  131. if (obj.status == 'NOT_STARTED' || obj.status == 'NOT_COMPLETED') {
  132. return ''
  133. }
  134. var start = obj.real_start_time
  135. var end = obj.real_end_time
  136. if (!end) {
  137. end = (new Date()).getTime()
  138. }
  139. return TimeFormatter.durationFormate(start, end)
  140. // return TimeFormatter.calculateTimeDifference(start, end)
  141. }
  142. function durationArc(start_time: number, end_time: number) {
  143. var duration = (end_time - start_time) / 1000;
  144. return duration / (24 * 3600) * 2 * Math.PI;
  145. }
  146. function bigRing() {
  147. var common = getCommon(null, true)
  148. common.radius = bigRingRadius;
  149. common.lineWidth = ringWidth;
  150. var bgRing = getBgRing()
  151. if (props.type == 'record' || props.type == 'latest') {
  152. var realRing = getReal(record, true, true)
  153. if (props.data.status == 'ONGOING3') {
  154. realRing.color = 'rgba(0,0,0,0)'
  155. }
  156. return <Rings common={common} bgRing={bgRing} canvasId={props.index} realRing={realRing} />
  157. }
  158. else {
  159. var currentDot1 = getDot(record, true)
  160. var targetBigRing1 = getTarget(record, true)
  161. if (record.status == 'ONGOING') {
  162. var realRing1 = getReal(record, true, false)
  163. return <Rings common={common} bgRing={bgRing} currentDot={currentDot1} realRing={realRing1} targetRing={targetBigRing1} canvasId={canvasId} />
  164. }
  165. if (record.status == 'WAIT_FOR_START') {
  166. return <Rings common={common} bgRing={bgRing} currentDot={currentDot1} canvasId={canvasId} />
  167. }
  168. var realRing1 = getReal(record, true, false)
  169. return <Rings common={common} bgRing={bgRing} realRing={realRing1} currentDot={currentDot1} targetRing={targetBigRing1} canvasId={canvasId} />
  170. }
  171. }
  172. function smallRing() {
  173. if (record.scenario == 'FAST_SLEEP') {
  174. var common = getCommon(null, false)
  175. common.radius = smallRingRadius;
  176. common.lineWidth = ringWidth;
  177. var bgRing = getBgRing()
  178. var realRing = getReal(record, false, false)
  179. if (props.type == 'record' || props.type == 'latest') {
  180. var showReal = false;
  181. if (record.sleep.status == 'WAIT_FOR_END') {
  182. realRing.durationArc = durationArc(record.sleep.target_start_time, (new Date()).getTime())
  183. showReal = true
  184. // return <Rings common={common} bgRing={bgRing} canvasId={canvasId + 'small'} realRing={realRing} />
  185. }
  186. else if (record.sleep.status == 'NOT_COMPLETED') {
  187. realRing.durationArc = 0.01
  188. showReal = true
  189. // return <Rings common={common} bgRing={bgRing} canvasId={canvasId + 'small'} realRing={realRing} />
  190. }
  191. else if (record.sleep.status == 'COMPLETED') {
  192. realRing = getReal(record, false, true)
  193. showReal = true
  194. // return <Rings common={common} bgRing={bgRing} canvasId={canvasId + 'small'} realRing={realRing} />
  195. }
  196. return <Rings common={common} bgRing={bgRing} canvasId={props.index + 'small'} realRing={showReal ? realRing : null} />
  197. // if (record.sleep.status == 'WAIT_FOR_END') {
  198. // realRing.durationArc = durationArc(record.sleep.target_start_time, (new Date()).getTime())
  199. // return <Rings common={common} bgRing={bgRing} canvasId={canvasId + 'small'} realRing={realRing} />
  200. // }
  201. // else if (record.sleep.status == 'NOT_COMPLETED') {
  202. // realRing.durationArc = 0.01
  203. // return <Rings common={common} bgRing={bgRing} canvasId={canvasId + 'small'} realRing={realRing} />
  204. // }
  205. // else if (record.sleep.status == 'COMPLETED') {
  206. // realRing = getReal(record, false, true)
  207. // return <Rings common={common} bgRing={bgRing} canvasId={canvasId + 'small'} realRing={realRing} />
  208. // }
  209. // return <Rings common={common} bgRing={bgRing} canvasId={canvasId + 'small'} />
  210. }
  211. else {
  212. var currentDot = getDot(record, false)
  213. var targetRing = getTarget(record, false)
  214. if (record.status == 'ONGOING2') {
  215. var realRing = getReal(record, false, false)
  216. return <Rings common={common} bgRing={bgRing} realRing={realRing} currentDot={currentDot} targetRing={targetRing} canvasId={canvasId + 'small'} />
  217. }
  218. if (record.status == 'ONGOING3') {
  219. currentDot.color = 'rgba(0, 255, 255, 0.5)'
  220. }
  221. return <Rings common={common} bgRing={bgRing} currentDot={currentDot} canvasId={canvasId + 'small'} />
  222. }
  223. }
  224. return null
  225. }
  226. function rings() {
  227. return <View style={{ position: 'relative', zIndex: 1 }}>
  228. {
  229. bigRing()
  230. }
  231. <View style={{ display: 'flex', position: 'absolute', left: 0, right: 0, top: 0, bottom: 0, alignItems: 'center', justifyContent: 'center' }}>
  232. {
  233. smallRing()
  234. }
  235. </View>
  236. </View>
  237. }
  238. function recordTime() {
  239. var timestamp = props.data.first_real_check_time
  240. if (props.data.first_time_zone) {
  241. timestamp = TimeFormatter.transferTimestamp(timestamp, props.data.first_time_zone)
  242. }
  243. return TimeFormatter.dateDescription(timestamp, true)
  244. }
  245. function getArrowText() {
  246. if (multiTimeZone) {
  247. return t('feature.common.multi_timezones')
  248. }
  249. if (diffTimeZone) {
  250. return t('feature.common.different_timezone')
  251. }
  252. return recordTime()
  253. }
  254. function recordDetail() {
  255. var fastDuration = ''
  256. var sleepDuration = ''
  257. var showFast = false;
  258. var showSleep = false;
  259. if (record.scenario == 'FAST_SLEEP') {
  260. fastDuration = getDuration(record.fast)
  261. sleepDuration = getDuration(record.sleep)
  262. if (record.status == 'ONGOING3') {
  263. fastDuration = t('feature.common.wait_for_end')
  264. }
  265. if (record.sleep.status == "NOT_STARTED") {
  266. sleepDuration = t('feature.common.not_started')
  267. }
  268. else if (record.sleep.status == 'NOT_COMPLETED') {
  269. sleepDuration = t('feature.common.not_completed')
  270. }
  271. showFast = true
  272. showSleep = true
  273. }
  274. else if (record.scenario == 'FAST') {
  275. fastDuration = getDuration(record.fast)
  276. showFast = true
  277. }
  278. else {
  279. sleepDuration = getDuration(record.sleep)
  280. showSleep = true
  281. }
  282. return <View className="fast_sleep_item">
  283. {
  284. rings()
  285. }
  286. <View className="duration_bg">
  287. {
  288. showFast && <Text className="duration_title">{t('feature.track_time_duration.record_fast_sleep.item.fast')}</Text>
  289. }
  290. {
  291. showFast && <Text className="duration_value" style={{ color: global.fastColor ? global.fastColor : ColorType.fast }}>{fastDuration}</Text>
  292. }
  293. {
  294. showSleep && <Text className="duration_title">{t('feature.track_time_duration.record_fast_sleep.item.sleep')}</Text>
  295. }
  296. {
  297. showSleep && <Text className="duration_value" style={{ color: global.sleepColor ? global.sleepColor : ColorType.sleep }}>{sleepDuration}</Text>
  298. }
  299. </View>
  300. {/* <Image className="arrow1" src={require('@/assets/images/arrow.png')} /> */}
  301. <View className="record_arrow_bg" style={{ backgroundColor: global.isDebug ? 'red' : 'transparent' }}>
  302. <View style={{ flex: 1 }} />
  303. <Text className='recordTime'>{getArrowText()}</Text>
  304. <Image className="arrow2" src={require('@/assets/images/arrow3.png')} />
  305. </View>
  306. </View>
  307. }
  308. return <View>
  309. <View className="time_operate_item">
  310. <RecordItem canDel={record.status == 'COMPLETED'} delete={del}
  311. onClick={showDetail}
  312. >{recordDetail()}
  313. </RecordItem>
  314. {
  315. showDetailModal && <Modal children={schedules()}
  316. modalType={ModalType.center}
  317. dismiss={() => setShowDetailModal(false)}
  318. confirm={() => { }} />
  319. }
  320. </View>
  321. </View>
  322. }