TimelineFastSleep.tsx 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. import Timeline from "@/components/view/Timeline";
  2. import { TimeFormatter } from "@/utils/time_format";
  3. import { View, Text } from "@tarojs/components";
  4. import getStatus from "../hooks/Record";
  5. import { ColorType } from "@/context/themes/color";
  6. import { useTranslation } from "react-i18next";
  7. import { useEffect, useState } from "react";
  8. import { useSelector } from "react-redux";
  9. import './TimelineFastSleep.scss'
  10. import dayjs from 'dayjs'
  11. import { rpxToPx } from "@/utils/tools";
  12. import Taro from "@tarojs/taro";
  13. const utc = require('dayjs/plugin/utc')
  14. const timezone = require('dayjs/plugin/timezone')
  15. var advanced = require("dayjs/plugin/advancedFormat")
  16. dayjs.extend(utc)
  17. dayjs.extend(timezone)
  18. dayjs.extend(advanced)
  19. export default function TimelineFastSleep(props: {
  20. data: any,
  21. title?: string,
  22. first_real_check_time?: number,
  23. multiTimeZone?: boolean,
  24. diffTimeZone?: boolean,
  25. scenario?: any,
  26. }) {
  27. const { t } = useTranslation()
  28. const [diffTimeZone] = useState(props.diffTimeZone)
  29. const [multTimeZone] = useState(props.multiTimeZone)
  30. const scenario = props.scenario ? props.scenario : useSelector((state: any) => state.scenario);
  31. useEffect(() => {
  32. // var split = new Date().toString().split(' ');
  33. // var currentTZ = split[split.length - 2];
  34. // if (props.data.fast) {
  35. // if (props.data.fast.real_start_time_zone && props.data.fast.real_start_time_zone != currentTZ) {
  36. // setDiffTimeZone(true)
  37. // return
  38. // }
  39. // if (props.data.fast.real_end_time_zone && props.data.fast.real_end_time_zone != currentTZ) {
  40. // setDiffTimeZone(true)
  41. // return
  42. // }
  43. // }
  44. // if (props.data.sleep) {
  45. // if (props.data.sleep.real_start_time_zone && props.data.sleep.real_start_time_zone != currentTZ) {
  46. // setDiffTimeZone(true)
  47. // return
  48. // }
  49. // if (props.data.sleep.real_end_time_zone && props.data.sleep.real_end_time_zone != currentTZ) {
  50. // setDiffTimeZone(true)
  51. // return
  52. // }
  53. // }
  54. // setDiffTimeZone(false)
  55. }, [props.data])
  56. function formateTime(obj: any, isEnd: boolean, isFastMode?: boolean) {
  57. if (isEnd) {
  58. if (obj.real_end_time) {
  59. var newTimestamp = TimeFormatter.transferTimestamp(obj.real_end_time, obj.real_end_time_zone)
  60. return TimeFormatter.timelineFormatTime(newTimestamp)
  61. // return diffTimeZone ? TimeFormatter.timelineFullFormatTime(newTimestamp) : TimeFormatter.timelineFormatTime(obj.real_end_time)
  62. }
  63. else {
  64. var real_time_zone = props.data.last_time_zone
  65. var newTimestamp = TimeFormatter.transferTimestamp(obj.target_end_time, real_time_zone)
  66. return TimeFormatter.timelineFormatTime(newTimestamp)
  67. // return diffTimeZone ? TimeFormatter.timelineFullFormatTime(obj.target_end_time) : TimeFormatter.timelineFormatTime(obj.target_end_time)
  68. }
  69. }
  70. else {
  71. if (obj.real_start_time) {
  72. var newTimestamp = TimeFormatter.transferTimestamp(obj.real_start_time, obj.real_start_time_zone)
  73. return TimeFormatter.timelineFormatTime(newTimestamp)
  74. // return diffTimeZone ? TimeFormatter.timelineFullFormatTime(newTimestamp) : TimeFormatter.timelineFormatTime(obj.real_start_time)
  75. }
  76. else {
  77. var real_time_zone = props.data.last_time_zone
  78. var newTimestamp = TimeFormatter.transferTimestamp(obj.target_start_time, real_time_zone)
  79. return TimeFormatter.timelineFormatTime(newTimestamp)
  80. // return diffTimeZone ? TimeFormatter.timelineFullFormatTime(obj.target_start_time) : TimeFormatter.timelineFormatTime(obj.target_start_time)
  81. }
  82. }
  83. }
  84. function formateDate(currentStatus: string, obj: any, isEnd: boolean, isFastMode?: boolean) {
  85. var now = new Date()
  86. var seconds = now.getHours() * 3600 + now.getMinutes() * 60 + now.getSeconds()
  87. if (currentStatus == 'WAIT_FOR_START') {
  88. if (props.data.scenario == 'SLEEP') {
  89. if (isEnd) {
  90. var count = TimeFormatter.timestringToSeconds(scenario.schedule.sleep.start_time)
  91. var count2 = TimeFormatter.timestringToSeconds(scenario.schedule.sleep.end_time)
  92. if (count2 < count) {
  93. return global.language == 'en' ? 'Tomorrow' : '明天'
  94. }
  95. return global.language == 'en' ? 'Today' : '今天'
  96. }
  97. }
  98. else {
  99. var count = TimeFormatter.timestringToSeconds(scenario.schedule.fast.start_time)
  100. if (isFastMode) {
  101. if (isEnd) {
  102. var count2 = TimeFormatter.timestringToSeconds(scenario.schedule.fast.end_time)
  103. if (count2 < count) {
  104. return global.language == 'en' ? 'Tomorrow' : '明天'
  105. }
  106. }
  107. return global.language == 'en' ? 'Today' : '今天'
  108. }
  109. else {
  110. if (isEnd) {
  111. var count2 = TimeFormatter.timestringToSeconds(scenario.schedule.sleep.end_time)
  112. if (count2 < count) {
  113. return global.language == 'en' ? 'Tomorrow' : '明天'
  114. }
  115. }
  116. else {
  117. var count2 = TimeFormatter.timestringToSeconds(scenario.schedule.sleep.start_time)
  118. if (count2 < count) {
  119. return global.language == 'en' ? 'Tomorrow' : '明天'
  120. }
  121. }
  122. return global.language == 'en' ? 'Today' : '今天'
  123. }
  124. }
  125. }
  126. if (isEnd) {
  127. if (obj.real_end_time) {
  128. var newTimestamp = TimeFormatter.transferTimestamp(obj.real_end_time, obj.real_end_time_zone)
  129. if (diffTimeZone || multTimeZone) {
  130. return TimeFormatter.getMonthAndDayByTimestamp(newTimestamp, true) + ' '
  131. }
  132. return TimeFormatter.dateDescription(newTimestamp, true, diffTimeZone || multTimeZone)
  133. }
  134. else {
  135. var real_time_zone = props.data.last_time_zone
  136. var newTimestamp = TimeFormatter.transferTimestamp(obj.target_end_time, real_time_zone)
  137. if (diffTimeZone || multTimeZone) {
  138. return TimeFormatter.getMonthAndDayByTimestamp(newTimestamp, true) + ' '
  139. }
  140. return TimeFormatter.dateDescription(newTimestamp, true, diffTimeZone || multTimeZone)
  141. }
  142. }
  143. else {
  144. if (obj.real_start_time) {
  145. var newTimestamp = TimeFormatter.transferTimestamp(obj.real_start_time, obj.real_start_time_zone)
  146. if (diffTimeZone || multTimeZone) {
  147. return TimeFormatter.getMonthAndDayByTimestamp(newTimestamp, true) + ' '
  148. }
  149. return TimeFormatter.dateDescription(newTimestamp, true, diffTimeZone || multTimeZone)
  150. }
  151. else {
  152. var real_time_zone = props.data.last_time_zone
  153. var newTimestamp = TimeFormatter.transferTimestamp(obj.target_start_time, real_time_zone)
  154. if (diffTimeZone || multTimeZone) {
  155. return TimeFormatter.getMonthAndDayByTimestamp(newTimestamp, true) + ' '
  156. }
  157. return TimeFormatter.dateDescription(obj.target_start_time, true, diffTimeZone || multTimeZone)
  158. }
  159. }
  160. }
  161. var timelineItems: any = [];
  162. /*
  163. attention:
  164. status == 待开始时
  165. timeline的时间不以时间戳进行处理,而是以target时间字符串进行显示
  166. */
  167. if (props.data.fast && props.data.scenario != 'SLEEP') {
  168. var timeZone = ''
  169. if (props.data.fast.real_start_time_zone) {
  170. timeZone = ' ' + props.data.fast.real_start_time_zone
  171. }
  172. var desc = props.data.status == 'WAIT_FOR_START' ? '' : multTimeZone ? timeZone : ''
  173. if (props.data.status != 'WAIT_FOR_START' && props.data.status != 'COMPLETED' && diffTimeZone) {
  174. desc = timeZone
  175. }
  176. timelineItems.push(
  177. {
  178. status: getStatus(true, true, props.data),
  179. title: getStatus(true, true, props.data) == 'padding' ?
  180. t('feature.track_time_duration.common.start_fast') :
  181. t('feature.track_time_duration.common.started_fasting'),
  182. content: props.data.status == 'WAIT_FOR_START' ? formateDate(props.data.status, props.data.fast, false, true) + ' ' + scenario.schedule.fast.start_time : formateDate(props.data.status, props.data.fast, false, true) + ' ' + formateTime(props.data.fast, false, true),
  183. date: desc,
  184. // (diffTimeZone ? timeZone : showDate(props.data.fast, false) ? formateDate(props.data.fast, false) : ''),
  185. color: global.fastColor ? global.fastColor : ColorType.fast
  186. }
  187. )
  188. }
  189. if (props.data.sleep && props.data.scenario != 'FAST') {
  190. var status = getStatus(false, true, props.data)
  191. var strContent = props.data.status == 'WAIT_FOR_START' ? formateDate(props.data.status, props.data.sleep, false, false) + ' ' + scenario.schedule.sleep.start_time : formateDate(props.data.status, props.data.sleep, false, false) + ' ' + formateTime(props.data.sleep, false, false)
  192. var timeZone = ''
  193. if (props.data.sleep.real_start_time_zone) {
  194. timeZone = ' ' + props.data.sleep.real_start_time_zone
  195. }
  196. var strDate = multTimeZone ? timeZone : ''
  197. if (props.data.status != 'WAIT_FOR_START' && props.data.status != 'COMPLETED') {
  198. if ((!timeZone || timeZone.length == 0) && (multTimeZone || diffTimeZone)) {
  199. strDate = props.data.last_time_zone
  200. }
  201. }
  202. debugger
  203. timelineItems.push(
  204. {
  205. status: status,
  206. title: status == 'padding' ?
  207. t('feature.track_time_duration.common.start_sleep') :
  208. t('feature.track_time_duration.common.started_sleeping'),
  209. content: status == 'un_done' ? '' : strContent,
  210. date: status == 'un_done' ? '' : strDate,
  211. color: global.sleepColor ? global.sleepColor : ColorType.sleep
  212. }
  213. )
  214. }
  215. if (props.data.sleep && props.data.scenario != 'FAST') {
  216. var timeZone = ''
  217. if (props.data.sleep.real_end_time_zone) {
  218. timeZone = ' ' + props.data.sleep.real_end_time_zone
  219. }
  220. var status = getStatus(false, false, props.data)
  221. var strContent: string = props.data.status == 'WAIT_FOR_START' ? formateDate(props.data.status, props.data.sleep, true, false) + ' ' + scenario.schedule.sleep.end_time : formateDate(props.data.status, props.data.sleep, true) + ' ' + formateTime(props.data.sleep, true, false)
  222. var strDate = multTimeZone ? timeZone : ''
  223. if (props.data.status != 'WAIT_FOR_START' && props.data.status != 'COMPLETED') {
  224. if ((!timeZone || timeZone.length == 0) && (multTimeZone || diffTimeZone)) {
  225. strDate = props.data.last_time_zone
  226. }
  227. }
  228. // (diffTimeZone ? timeZone : showDate(props.data.sleep, true) ? formateDate(props.data.sleep, true) : '')
  229. timelineItems.push(
  230. {
  231. status: status,
  232. title: status == 'padding' ?
  233. t('feature.track_time_duration.common.end_sleep') :
  234. t('feature.track_time_duration.common.ended_sleeping'),
  235. content: status == 'un_done' ? '' : strContent,
  236. date: status == 'un_done' ? '' : strDate,
  237. color: global.sleepColor ? global.sleepColor : ColorType.sleep
  238. }
  239. )
  240. }
  241. if (props.data.fast && props.data.scenario != 'SLEEP') {
  242. var timeZone = ''
  243. if (props.data.fast.real_end_time_zone) {
  244. timeZone = ' ' + props.data.fast.real_end_time_zone
  245. }
  246. if (props.data.status != 'WAIT_FOR_START' && props.data.status != 'COMPLETED') {
  247. if ((!timeZone || timeZone.length == 0) && (multTimeZone || diffTimeZone)) {
  248. timeZone = props.data.last_time_zone
  249. }
  250. }
  251. if ((diffTimeZone && !multTimeZone) && props.data.status == 'COMPLETED') {
  252. timeZone = ''
  253. }
  254. if (!diffTimeZone && !multTimeZone && props.data.status == 'COMPLETED') {
  255. timeZone = ''
  256. }
  257. timelineItems.push(
  258. {
  259. status: getStatus(true, false, props.data),
  260. title: getStatus(true, false, props.data) == 'padding' ?
  261. t('feature.track_time_duration.common.end_fast') :
  262. t('feature.track_time_duration.common.ended_fasting'),
  263. content: props.data.status == 'WAIT_FOR_START' ? formateDate(props.data.status, props.data.fast, true, true) + ' ' + scenario.schedule.fast.end_time : formateDate(props.data.status, props.data.fast, true) + ' ' + formateTime(props.data.fast, true, true),
  264. // date: multTimeZone ? timeZone : '',
  265. date: timeZone,
  266. // (diffTimeZone ? timeZone : showDate(props.data.fast, true) ? formateDate(props.data.fast, true) : ''),
  267. color: global.fastColor ? global.fastColor : ColorType.fast
  268. }
  269. )
  270. }
  271. function getTZLocation() {
  272. if (props.data.fast) {
  273. if (props.data.fast.real_start_time_zone_id) {
  274. return `${dayjs().tz(props.data.fast.real_start_time_zone_id).format('z')} (${props.data.fast.real_start_time_zone_id})`
  275. }
  276. return props.data.fast.real_start_time_zone
  277. }
  278. else {
  279. if (props.data.sleep.real_start_time_zone_id) {
  280. return `${dayjs().tz(props.data.sleep.real_start_time_zone_id).format('z')} (${props.data.sleep.real_start_time_zone_id})`
  281. // return props.data.sleep.real_start_time_zone_id
  282. }
  283. return props.data.sleep.real_start_time_zone
  284. }
  285. }
  286. function getDeviceLocation(){
  287. if (Taro.getSystemInfoSync().platform == 'ios') {
  288. return `${dayjs().format('z')} (${dayjs.tz.guess()})`
  289. }
  290. return `${dayjs().format('z')}`
  291. }
  292. function getTZOffset() {
  293. let offset = 0;
  294. var current1 = dayjs()
  295. var current
  296. if (props.data.fast) {
  297. if (props.data.fast.real_start_time_zone_id) {
  298. current = dayjs().tz(props.data.fast.real_start_time_zone_id)
  299. offset = current.date() * 24 * 60 + current.hour() * 60 + current.minute() - current1.date() * 24 * 60 - current1.hour() * 60 - current1.minute()
  300. }
  301. else {
  302. offset = TimeFormatter.timeZoneOffset(props.data.fast.real_start_time_zone)
  303. }
  304. }
  305. else {
  306. if (props.data.sleep.real_start_time_zone_id) {
  307. current = dayjs().tz(props.data.sleep.real_start_time_zone_id)
  308. offset = current.date() * 24 * 60 + current.hour() * 60 + current.minute() - current1.date() * 24 * 60 - current1.hour() * 60 - current1.minute()
  309. }
  310. else {
  311. offset = TimeFormatter.timeZoneOffset(props.data.sleep.real_start_time_zone)
  312. }
  313. }
  314. // offset = current.date() * 24 * 60 + current.hour() * 60 + current.minute() - current1.date() * 24 * 60 - current1.hour() * 60 - current1.minute()
  315. var hour = Math.floor(Math.abs(offset) / 60)
  316. var minute = Math.abs(offset) % 60
  317. var time = ''
  318. if (global.language == 'en') {
  319. time = `${hour} h`
  320. if (minute > 0) {
  321. time += ` ${minute} m`
  322. }
  323. }
  324. else {
  325. time = `${hour}小时`
  326. if (minute > 0) {
  327. time += `${minute}分钟`
  328. }
  329. }
  330. return offset > 0 ? t('feature.day_night.ahead_desc', { time: time }) : t('feature.day_night.behind_desc', { time: time })
  331. }
  332. return <View style={{ display: 'flex', flexDirection: 'column' }}>
  333. <View style={{ display: 'flex', flexDirection: 'row' }}>
  334. <Timeline items={timelineItems} title={props.title} width={468} />
  335. <View>
  336. </View>
  337. </View>
  338. {
  339. multTimeZone && <Text className="tz_note_desc" style={{width:rpxToPx(538)}}>{t('feature.common.multi_tz_desc')}</Text>
  340. }
  341. {
  342. !multTimeZone && diffTimeZone && <Text className="tz_note_desc" style={{width:rpxToPx(538)}}>{t('feature.common.diff_tz_desc', { location: getTZLocation(), offset: getTZOffset(),device_location:getDeviceLocation() })}</Text>
  343. }
  344. </View>
  345. }