TimelineFastSleep.tsx 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  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 { getTimezone, getTimezoneName, 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. function formateTime(obj: any, isEnd: boolean, isFastMode?: boolean) {
  32. if (isEnd) {
  33. if (obj.real_end_time) {
  34. var newTimestamp = TimeFormatter.transferTimestamp(obj.real_end_time, obj.real_end_timezone.gmt)
  35. return TimeFormatter.timelineFormatTime(newTimestamp)
  36. // return diffTimeZone ? TimeFormatter.timelineFullFormatTime(newTimestamp) : TimeFormatter.timelineFormatTime(obj.real_end_time)
  37. }
  38. else {
  39. var real_time_zone = props.data.last_timezone ? props.data.last_timezone.gmt : ''
  40. var newTimestamp = TimeFormatter.transferTimestamp(obj.target_end_time, real_time_zone)
  41. return TimeFormatter.timelineFormatTime(newTimestamp)
  42. // return diffTimeZone ? TimeFormatter.timelineFullFormatTime(obj.target_end_time) : TimeFormatter.timelineFormatTime(obj.target_end_time)
  43. }
  44. }
  45. else {
  46. if (obj.real_start_time) {
  47. var newTimestamp = TimeFormatter.transferTimestamp(obj.real_start_time, obj.real_start_timezone.gmt)
  48. return TimeFormatter.timelineFormatTime(newTimestamp)
  49. // return diffTimeZone ? TimeFormatter.timelineFullFormatTime(newTimestamp) : TimeFormatter.timelineFormatTime(obj.real_start_time)
  50. }
  51. else {
  52. var real_time_zone = props.data.last_timezone ? props.data.last_timezone.gmt : ''
  53. var newTimestamp = TimeFormatter.transferTimestamp(obj.target_start_time, real_time_zone)
  54. return TimeFormatter.timelineFormatTime(newTimestamp)
  55. // return diffTimeZone ? TimeFormatter.timelineFullFormatTime(obj.target_start_time) : TimeFormatter.timelineFormatTime(obj.target_start_time)
  56. }
  57. }
  58. }
  59. function formateDate(currentStatus: string, obj: any, isEnd: boolean, isFastMode?: boolean) {
  60. if (currentStatus == 'WAIT_FOR_START') {
  61. if (props.data.scenario == 'SLEEP') {
  62. if (isEnd) {
  63. var count = TimeFormatter.timestringToSeconds(scenario.schedule.sleep.start_time)
  64. var count2 = TimeFormatter.timestringToSeconds(scenario.schedule.sleep.end_time)
  65. if (count2 < count) {
  66. return global.language == 'en' ? 'Tomorrow' : '明天'
  67. }
  68. return global.language == 'en' ? 'Today' : '今天'
  69. }
  70. }
  71. else {
  72. var count = TimeFormatter.timestringToSeconds(scenario.schedule.fast.start_time)
  73. if (isFastMode) {
  74. if (isEnd) {
  75. var count2 = TimeFormatter.timestringToSeconds(scenario.schedule.fast.end_time)
  76. if (count2 < count) {
  77. return global.language == 'en' ? 'Tomorrow' : '明天'
  78. }
  79. }
  80. return global.language == 'en' ? 'Today' : '今天'
  81. }
  82. else {
  83. if (isEnd) {
  84. var count2 = TimeFormatter.timestringToSeconds(scenario.schedule.sleep.end_time)
  85. if (count2 < count) {
  86. return global.language == 'en' ? 'Tomorrow' : '明天'
  87. }
  88. }
  89. else {
  90. var count2 = TimeFormatter.timestringToSeconds(scenario.schedule.sleep.start_time)
  91. if (count2 < count) {
  92. return global.language == 'en' ? 'Tomorrow' : '明天'
  93. }
  94. }
  95. return global.language == 'en' ? 'Today' : '今天'
  96. }
  97. }
  98. }
  99. if (isEnd) {
  100. if (obj.real_end_time) {
  101. var newTimestamp = TimeFormatter.transferTimestamp(obj.real_end_time, obj.real_end_timezone.gmt)
  102. if (diffTimeZone || multTimeZone) {
  103. return TimeFormatter.getMonthAndDayByTimestamp(newTimestamp, true) + ' '
  104. }
  105. return TimeFormatter.dateDescription(newTimestamp, true, diffTimeZone || multTimeZone)
  106. }
  107. else {
  108. var real_time_zone = props.data.last_timezone ? props.data.last_timezone.gmt : ''
  109. var newTimestamp = TimeFormatter.transferTimestamp(obj.target_end_time, real_time_zone)
  110. if (diffTimeZone || multTimeZone) {
  111. return TimeFormatter.getMonthAndDayByTimestamp(newTimestamp, true) + ' '
  112. }
  113. return TimeFormatter.dateDescription(newTimestamp, true, diffTimeZone || multTimeZone)
  114. }
  115. }
  116. else {
  117. if (obj.real_start_time) {
  118. var newTimestamp = TimeFormatter.transferTimestamp(obj.real_start_time, obj.real_start_timezone.gmt)
  119. if (diffTimeZone || multTimeZone) {
  120. return TimeFormatter.getMonthAndDayByTimestamp(newTimestamp, true) + ' '
  121. }
  122. return TimeFormatter.dateDescription(newTimestamp, true, diffTimeZone || multTimeZone)
  123. }
  124. else {
  125. var real_time_zone = props.data.last_timezone ? props.data.last_timezone.gmt : ''
  126. var newTimestamp = TimeFormatter.transferTimestamp(obj.target_start_time, real_time_zone)
  127. if (diffTimeZone || multTimeZone) {
  128. return TimeFormatter.getMonthAndDayByTimestamp(newTimestamp, true) + ' '
  129. }
  130. return TimeFormatter.dateDescription(obj.target_start_time, true, diffTimeZone || multTimeZone)
  131. }
  132. }
  133. }
  134. var timelineItems: any = [];
  135. /*
  136. attention:
  137. status == 待开始时
  138. timeline的时间不以时间戳进行处理,而是以target时间字符串进行显示
  139. */
  140. if (props.data.fast && props.data.scenario != 'SLEEP') {
  141. var timeZone = ''
  142. if (props.data.fast.real_start_timezone && props.data.fast.real_start_timezone.gmt) {
  143. timeZone = ' ' + props.data.fast.real_start_timezone.gmt
  144. }
  145. var desc = props.data.status == 'WAIT_FOR_START' ? '' : multTimeZone ? timeZone : ''
  146. if (props.data.status != 'WAIT_FOR_START' && props.data.status != 'COMPLETED' && diffTimeZone) {
  147. desc = timeZone
  148. }
  149. timelineItems.push(
  150. {
  151. status: getStatus(true, true, props.data),
  152. title: getStatus(true, true, props.data) == 'padding' ?
  153. t('feature.track_time_duration.common.start_fast') :
  154. t('feature.track_time_duration.common.started_fasting'),
  155. 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),
  156. date: desc,
  157. // (diffTimeZone ? timeZone : showDate(props.data.fast, false) ? formateDate(props.data.fast, false) : ''),
  158. color: global.fastColor ? global.fastColor : ColorType.fast
  159. }
  160. )
  161. }
  162. if (props.data.sleep && props.data.scenario != 'FAST') {
  163. var status = getStatus(false, true, props.data)
  164. 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)
  165. var timeZone = ''
  166. if (props.data.sleep.real_start_timezone && props.data.sleep.real_start_timezone.gmt) {
  167. timeZone = ' ' + props.data.sleep.real_start_timezone.gmt
  168. }
  169. var strDate = multTimeZone ? timeZone : ''
  170. if (props.data.status != 'WAIT_FOR_START' && props.data.status != 'COMPLETED') {
  171. if ((!timeZone || timeZone.length == 0) && (multTimeZone || diffTimeZone)) {
  172. strDate = props.data.last_timezone.gmt
  173. }
  174. }
  175. timelineItems.push(
  176. {
  177. status: status,
  178. title: status == 'padding' ?
  179. t('feature.track_time_duration.common.start_sleep') :
  180. t('feature.track_time_duration.common.started_sleeping'),
  181. content: status == 'un_done' ? '' : strContent,
  182. date: status == 'un_done' ? '' : strDate,
  183. color: global.sleepColor ? global.sleepColor : ColorType.sleep
  184. }
  185. )
  186. }
  187. if (props.data.sleep && props.data.scenario != 'FAST') {
  188. var timeZone = ''
  189. if (props.data.sleep.real_end_timezone && props.data.sleep.real_end_timezone.gmt) {
  190. timeZone = ' ' + props.data.sleep.real_end_timezone.gmt
  191. }
  192. var status = getStatus(false, false, props.data)
  193. 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)
  194. var strDate = multTimeZone ? timeZone : ''
  195. if (props.data.status != 'WAIT_FOR_START' && props.data.status != 'COMPLETED') {
  196. if ((!timeZone || timeZone.length == 0) && (multTimeZone || diffTimeZone)) {
  197. strDate = props.data.last_timezone.gmt
  198. }
  199. }
  200. // (diffTimeZone ? timeZone : showDate(props.data.sleep, true) ? formateDate(props.data.sleep, true) : '')
  201. timelineItems.push(
  202. {
  203. status: status,
  204. title: status == 'padding' ?
  205. t('feature.track_time_duration.common.end_sleep') :
  206. t('feature.track_time_duration.common.ended_sleeping'),
  207. content: status == 'un_done' ? '' : strContent,
  208. date: status == 'un_done' ? '' : strDate,
  209. color: global.sleepColor ? global.sleepColor : ColorType.sleep
  210. }
  211. )
  212. }
  213. if (props.data.fast && props.data.scenario != 'SLEEP') {
  214. var timeZone = ''
  215. if (props.data.fast.real_end_timezone && props.data.fast.real_end_timezone.gmt) {
  216. timeZone = ' ' + props.data.fast.real_end_timezone.gmt
  217. }
  218. if (props.data.status != 'WAIT_FOR_START' && props.data.status != 'COMPLETED') {
  219. if ((!timeZone || timeZone.length == 0) && (multTimeZone || diffTimeZone)) {
  220. timeZone = props.data.last_timezone.gmt
  221. }
  222. }
  223. if ((diffTimeZone && !multTimeZone) && props.data.status == 'COMPLETED') {
  224. timeZone = ''
  225. }
  226. if (!diffTimeZone && !multTimeZone && props.data.status == 'COMPLETED') {
  227. timeZone = ''
  228. }
  229. timelineItems.push(
  230. {
  231. status: getStatus(true, false, props.data),
  232. title: getStatus(true, false, props.data) == 'padding' ?
  233. t('feature.track_time_duration.common.end_fast') :
  234. t('feature.track_time_duration.common.ended_fasting'),
  235. 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),
  236. // date: multTimeZone ? timeZone : '',
  237. date: timeZone,
  238. // (diffTimeZone ? timeZone : showDate(props.data.fast, true) ? formateDate(props.data.fast, true) : ''),
  239. color: global.fastColor ? global.fastColor : ColorType.fast
  240. }
  241. )
  242. }
  243. function getTZLocation() {
  244. if (props.data.fast) {
  245. var name = props.data.fast.real_start_timezone ? props.data.fast.real_start_timezone.gmt : ''
  246. if (props.data.fast.real_start_timezone && props.data.fast.real_start_timezone.name) {
  247. name = `${name} (${props.data.fast.real_start_timezone.name})`
  248. }
  249. return name
  250. }
  251. else {
  252. var name = props.data.sleep.real_start_timezone ? props.data.sleep.real_start_timezone.gmt : ''
  253. if (props.data.sleep.real_start_timezone && props.data.sleep.real_start_timezone.name) {
  254. name = `${name} (${props.data.sleep.real_start_timezone.name})`
  255. }
  256. return name
  257. }
  258. }
  259. function getDeviceLocation() {
  260. return `${getTimezone()} (${getTimezoneName()})`
  261. }
  262. function getTZOffset() {
  263. let offset = 0;
  264. var current1 = dayjs()
  265. var current
  266. if (props.data.fast) {
  267. if (props.data.fast.real_start_timezone && props.data.fast.real_start_timezone.id) {
  268. current = TimeFormatter.tzLocalTime(new Date().getTime(),props.data.fast.real_start_timezone.id)//dayjs().tz(props.data.fast.real_start_timezone.id)
  269. offset = current.date() * 24 * 60 + current.hour() * 60 + current.minute() - current1.date() * 24 * 60 - current1.hour() * 60 - current1.minute()
  270. }
  271. else {
  272. offset = TimeFormatter.timeZoneOffset(props.data.fast.real_start_timezone.gmt)
  273. }
  274. }
  275. else {
  276. if (props.data.sleep.real_start_timezone && props.data.sleep.real_start_timezone.id) {
  277. current = TimeFormatter.tzLocalTime(new Date().getTime(),props.data.sleep.real_start_timezone.id)//dayjs().tz(props.data.sleep.real_start_timezone.id)
  278. offset = current.date() * 24 * 60 + current.hour() * 60 + current.minute() - current1.date() * 24 * 60 - current1.hour() * 60 - current1.minute()
  279. }
  280. else {
  281. offset = TimeFormatter.timeZoneOffset(props.data.sleep.real_start_timezone.gmt)
  282. }
  283. }
  284. // offset = current.date() * 24 * 60 + current.hour() * 60 + current.minute() - current1.date() * 24 * 60 - current1.hour() * 60 - current1.minute()
  285. var hour = Math.floor(Math.abs(offset) / 60)
  286. var minute = Math.abs(offset) % 60
  287. var time = ''
  288. if (global.language == 'en') {
  289. time = `${hour} h`
  290. if (minute > 0) {
  291. time += ` ${minute} m`
  292. }
  293. }
  294. else {
  295. time = `${hour}小时`
  296. if (minute > 0) {
  297. time += `${minute}分钟`
  298. }
  299. }
  300. return offset > 0 ? t('feature.day_night.ahead_desc', { time: time }) : t('feature.day_night.behind_desc', { time: time })
  301. }
  302. return <View style={{ display: 'flex', flexDirection: 'column' }}>
  303. <View style={{ display: 'flex', flexDirection: 'row' }}>
  304. <Timeline items={timelineItems} title={props.title} width={468} />
  305. <View>
  306. </View>
  307. </View>
  308. {
  309. multTimeZone && <Text className="tz_note_desc" style={{ width: rpxToPx(538) }}>{t('feature.common.multi_tz_desc')}</Text>
  310. }
  311. {
  312. !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>
  313. }
  314. </View>
  315. }