DayNightDetailPopup.tsx 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. import { View, Text } from '@tarojs/components'
  2. import './CircadianDetailPopup.scss'
  3. import { useTranslation } from 'react-i18next'
  4. import { useEffect, useState } from 'react'
  5. import { rpxToPx } from '@/utils/tools'
  6. import { TimeFormatter } from '@/utils/time_format'
  7. import { useSelector } from 'react-redux'
  8. import { ColorType } from '@/context/themes/color'
  9. import Timeline from '@/components/view/Timeline'
  10. export default function DayNightDetailPopup(props: {
  11. isNight: boolean,
  12. authInfo: any,
  13. sunsetDate: any,
  14. sunriseDate: any,
  15. sunriseTmrDate: any,
  16. sunsetTime: any,
  17. sunriseTime: any,
  18. sunriseTmrTime: any,
  19. nightDate: any,
  20. dayDate: any,
  21. onClose: Function,
  22. }) {
  23. const dayNight = useSelector((state: any) => state.night);
  24. const day = useSelector((state: any) => state.day);
  25. const [tabIndex, setTabIndex] = useState(0)
  26. const { t } = useTranslation()
  27. useEffect(() => {
  28. if (isCompleted()) {
  29. setTabIndex(1)
  30. }
  31. }, [])
  32. function getTitle() {
  33. return props.isNight ? t('feature.day_night.night_popover') : t('feature.day_night.day_popover')
  34. }
  35. function getCompletedTitle(){
  36. if (props.isNight){
  37. return TimeFormatter.getDayOfWeek(new Date(props.authInfo.night_completed.sunset_ts).getDay(),true)
  38. }
  39. return TimeFormatter.getDayOfWeek(new Date(props.authInfo.night_completed.sunrise_ts).getDay(),true)
  40. }
  41. function getSubTitle(){
  42. if (props.isNight){
  43. return TimeFormatter.getMonthAndDayByTimestamp(props.authInfo.night_completed.sunset_ts)
  44. }
  45. return TimeFormatter.getMonthAndDayByTimestamp(props.authInfo.night_completed.sunrise_ts)
  46. }
  47. function isCompleted() {
  48. if (props.isNight) {
  49. if (props.authInfo && props.authInfo.night_completed && new Date().getTime() > props.authInfo.night_completed.sunrise_ts) {
  50. return true
  51. }
  52. }
  53. else {
  54. if (props.authInfo && props.authInfo.day_completed && new Date().getTime() > props.authInfo.day_completed.sunset_ts) {
  55. return true
  56. }
  57. }
  58. return false
  59. }
  60. function nightDuration() {
  61. if (isCompleted()) {
  62. return TimeFormatter.calculateTimeDifference(props.authInfo.night_completed.sunset_ts, props.authInfo.night_completed.sunrise_ts);
  63. }
  64. var sunRiseObj = dayNight.nightRingSunrise
  65. var sunSetObj = dayNight.nightRingSunset
  66. var sunRise = 24 * 60 + parseInt(sunRiseObj.split(':')[0]) * 60 + parseInt(sunRiseObj.split(':')[1])
  67. var sunSet = parseInt(sunSetObj.split(':')[0]) * 60 + parseInt(sunSetObj.split(':')[1])
  68. if (sunSetObj.indexOf('PM') != -1) {
  69. sunSet += 12 * 60
  70. }
  71. var duration = (sunRise - sunSet) * 60 * 1000
  72. return TimeFormatter.calculateTimeDifference(new Date().getTime(), new Date().getTime() + duration);
  73. }
  74. function dayDuration() {
  75. if (isCompleted()) {
  76. return TimeFormatter.calculateTimeDifference(props.authInfo.day_completed.sunrise_ts, props.authInfo.day_completed.sunset_ts);
  77. }
  78. var sunRiseObj = day.dayRingSunrise
  79. var sunSetObj = day.dayRingSunset
  80. var sunRise = parseInt(sunRiseObj.split(':')[0]) * 60 + parseInt(sunRiseObj.split(':')[1])
  81. var sunSet = parseInt(sunSetObj.split(':')[0]) * 60 + parseInt(sunSetObj.split(':')[1])
  82. if (sunSetObj.indexOf('PM') != -1) {
  83. sunSet += 12 * 60
  84. }
  85. var duration = (sunSet - sunRise) * 60 * 1000
  86. return TimeFormatter.calculateTimeDifference(new Date().getTime(), new Date().getTime() + duration);
  87. }
  88. function showExtraData() {
  89. var now = new Date()
  90. if (props.isNight) {
  91. if (props.sunsetDate.getTime() > now.getTime()) {
  92. return false
  93. }
  94. return true
  95. }
  96. if (props.sunriseDate.getTime() < now.getTime() && now.getTime() < props.sunsetDate.getTime()) {
  97. return true;
  98. }
  99. return false
  100. }
  101. function timeCount() {
  102. var now = new Date()
  103. if (props.isNight) {
  104. if (now.getTime() < props.sunriseTmrDate.getTime()) {
  105. return TimeFormatter.countdown(props.sunsetDate.getTime())
  106. }
  107. return TimeFormatter.countdown(props.sunsetDate.getTime())
  108. } else {
  109. if (now.getTime() < props.sunsetDate.getTime()) {
  110. return TimeFormatter.countdown(props.sunriseDate.getTime())
  111. }
  112. return TimeFormatter.countdown(props.sunriseTmrDate.getTime())
  113. }
  114. }
  115. function timeCount2() {
  116. var now = new Date()
  117. if (props.isNight) {
  118. if (now.getTime() < props.sunsetDate.getTime()) {
  119. return TimeFormatter.countdown(props.sunriseTmrDate.getTime())
  120. }
  121. return TimeFormatter.countdown(props.sunriseTmrDate.getTime())
  122. } else {
  123. return TimeFormatter.countdown(props.sunsetDate.getTime())
  124. }
  125. }
  126. function timeDesc() {
  127. var now = new Date()
  128. if (props.isNight) {
  129. var list = props.sunsetTime.split(':')
  130. var hour = parseInt(list[0])
  131. var min = parseInt(list[1])
  132. var second = list.length == 3 ? parseInt(list[2]) : 0
  133. now.setHours(hour)
  134. now.setMinutes(min)
  135. now.setSeconds(second)
  136. var sunriseDate = new Date()
  137. var list2 = props.sunriseTmrTime.split(':')
  138. var hour2 = parseInt(list2[0])
  139. var min2 = parseInt(list2[1])
  140. var second2 = list2.length == 3 ? parseInt(list2[2]) : 0
  141. sunriseDate.setHours(hour2)
  142. sunriseDate.setMinutes(min2)
  143. sunriseDate.setSeconds(second2)
  144. if (sunriseDate.getTime() > new Date().getTime()) {
  145. return t('feature.day_night.time_past_sunset')//'Time past Sunset'
  146. }
  147. if (now.getTime() < new Date().getTime()) {
  148. return t('feature.day_night.time_past_sunset')//'Time past Sunset'
  149. }
  150. return t('feature.day_night.time_to_sunset')//'Time to Sunset'
  151. }
  152. else {
  153. var list = props.sunriseTime.split(':')
  154. var hour = parseInt(list[0])
  155. var min = parseInt(list[1])
  156. var second = list.length == 3 ? parseInt(list[2]) : 0
  157. now.setHours(hour)
  158. now.setMinutes(min)
  159. now.setSeconds(second)
  160. var sunsetDate = new Date()
  161. var list2 = props.sunsetTime.split(':')
  162. var hour2 = parseInt(list2[0])
  163. var min2 = parseInt(list2[1])
  164. var second2 = list2.length == 3 ? parseInt(list2[2]) : 0
  165. sunsetDate.setHours(hour2)
  166. sunsetDate.setMinutes(min2)
  167. sunsetDate.setSeconds(second2)
  168. if (new Date().getTime() > sunsetDate.getTime()) {
  169. return t('feature.day_night.time_to_sunrise')//'Time to Sunrise'
  170. }
  171. if (now.getTime() < new Date().getTime()) {
  172. return t('feature.day_night.time_past_sunrise')//'Time past Sunrise'
  173. }
  174. return t('feature.day_night.time_to_sunrise')//'Time to Sunrise'
  175. }
  176. }
  177. function timeDesc2() {
  178. if (props.isNight) {
  179. return t('feature.day_night.time_to_sunrise')//'Time to Sunrise'
  180. }
  181. return t('feature.day_night.time_to_sunset')//'Time to Sunset'
  182. }
  183. function overview() {
  184. return <View className='pop_ring_bg pop_overview_bg'>
  185. <Text className='pop_duration_title'>{props.isNight ? t('feature.day_night.night_duration') : t('feature.day_night.day_duration')}</Text>
  186. <View style={{ flexDirection: 'row', alignItems: 'center', marginTop: rpxToPx(8), display: 'flex', width: '100%' }}>
  187. <Text className='pop_duration_txt'>{props.isNight ? nightDuration() : dayDuration()}</Text>
  188. </View>
  189. {
  190. !isCompleted() && <View style={{ marginTop: rpxToPx(20), display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
  191. <View className='countdown_time_bg'>
  192. <Text className='title'>{timeDesc()}</Text>
  193. <Text className='value' style={{ color: props.isNight ? ColorType.night : ColorType.day }}>{timeCount()}</Text>
  194. </View>
  195. {
  196. showExtraData() && <View className='countdown_time_bg'>
  197. <Text className='title'>{timeDesc2()}</Text>
  198. <Text className='value' style={{ opacity: 0.4, color: props.isNight ? ColorType.night : ColorType.day }}>{timeCount2()}</Text>
  199. </View>
  200. }
  201. </View>
  202. }
  203. </View>
  204. }
  205. function nightDurationDesc() {
  206. if (!props.authInfo || !(props.authInfo as any).lat) {
  207. if (new Date().getHours() >= 6) {
  208. return [t('feature.day_night.tonight'), t('feature.day_night.tomorrow_morning')]
  209. }
  210. return [t('feature.day_night.last_night'), t('feature.day_night.this_morning')]
  211. // return `Yesterday ${sunsetTime} - Today ${sunriseTmrTime}`
  212. }
  213. if (props.nightDate.getDate() == new Date().getDate()) {
  214. return [t('feature.day_night.tonight'), t('feature.day_night.tomorrow_morning')]
  215. }
  216. return [t('feature.day_night.last_night'), t('feature.day_night.this_morning')]
  217. //`Yesterday ${sunsetTime} - Today ${sunriseTmrTime}`
  218. }
  219. function dayDurationDesc() {
  220. if (!props.authInfo || !(props.authInfo as any).lat) {
  221. if (new Date().getHours() >= 18) {
  222. return `${t('feature.day_night.tomorrow')}`
  223. // return `Tomorrow ${sunriseTime} - ${sunsetTime}`
  224. }
  225. return `${t('feature.day_night.today')}`
  226. // return `Today ${sunriseTime} - ${sunsetTime}`
  227. }
  228. if (props.dayDate.getDate() == new Date().getDate()) {
  229. return `${t('feature.day_night.today')}`
  230. // return `Today ${sunriseTime} - ${sunsetTime}`
  231. }
  232. return `${t('feature.day_night.tomorrow')}`
  233. // return `Tomorrow ${sunriseTime} - ${sunsetTime}`
  234. }
  235. function events() {
  236. let timelineItems: any = []
  237. if (props.isNight) {
  238. if (isCompleted()) {
  239. timelineItems.push(
  240. {
  241. status: 'done',
  242. title: '日落',//list[0],
  243. content: TimeFormatter.dateTimeFormate(props.authInfo.night_completed.sunset_ts, true),
  244. date: '',
  245. color: ColorType.night
  246. }
  247. )
  248. timelineItems.push(
  249. {
  250. status: 'done',
  251. title: '日出',//list[1],
  252. content: TimeFormatter.dateTimeFormate(props.authInfo.night_completed.sunrise_ts, true),
  253. date: '',
  254. color: ColorType.night
  255. }
  256. )
  257. }
  258. else {
  259. var list = nightDurationDesc()
  260. timelineItems.push(
  261. {
  262. status: showExtraData() ? 'done' : 'padding',
  263. title: '日落',//list[0],
  264. content: list[0] + ' ' + props.sunsetTime,
  265. date: '',
  266. color: ColorType.night
  267. }
  268. )
  269. timelineItems.push(
  270. {
  271. status: 'padding',
  272. title: '日出',//list[1],
  273. content: list[1] + ' ' + props.sunriseTmrTime,
  274. date: '',
  275. color: ColorType.night
  276. }
  277. )
  278. }
  279. }
  280. else {
  281. if (isCompleted()) {
  282. timelineItems.push(
  283. {
  284. status: 'done',
  285. title: '日落',//list[0],
  286. content: TimeFormatter.dateTimeFormate(props.authInfo.day_completed.sunrise_ts, true),
  287. date: '',
  288. color: ColorType.night
  289. }
  290. )
  291. timelineItems.push(
  292. {
  293. status: 'done',
  294. title: '日出',//list[1],
  295. content: TimeFormatter.dateTimeFormate(props.authInfo.day_completed.sunset_ts, true),
  296. date: '',
  297. color: ColorType.night
  298. }
  299. )
  300. }
  301. else {
  302. timelineItems.push(
  303. {
  304. status: showExtraData() ? 'done' : 'padding',
  305. title: '日出',//dayDurationDesc(),
  306. content: dayDurationDesc() + ' ' + props.sunriseTime,
  307. date: '',
  308. color: ColorType.day
  309. }
  310. )
  311. timelineItems.push(
  312. {
  313. status: 'padding',
  314. title: '日落',//dayDurationDesc(),
  315. content: dayDurationDesc() + ' ' + props.sunsetTime,
  316. date: '',
  317. color: ColorType.day
  318. }
  319. )
  320. }
  321. }
  322. return <View style={{ display: 'flex', flexDirection: 'row' }}>
  323. <Timeline items={timelineItems} title='' width={468} />
  324. </View>
  325. }
  326. return <View className='detail_container'>
  327. {
  328. isCompleted()?<Text className='detail_popup_title'>{getCompletedTitle()}<Text className='detail_popup_subttitle'> {getSubTitle()}</Text></Text>:
  329. <Text className='detail_popup_title'>{getTitle()}</Text>
  330. }
  331. <View className='detail_tabbar'>
  332. <View onClick={() => { setTabIndex(0) }} className={tabIndex == 0 ? 'detail_tabitem_sel' : 'detail_tabitem_nor'}>{t('feature.day_night.overview')}</View>
  333. <View onClick={() => { setTabIndex(1) }} className={tabIndex == 1 ? 'detail_tabitem_sel' : 'detail_tabitem_nor'}>{t('feature.day_night.events')}</View>
  334. </View>
  335. <View className='detail_content'>
  336. {
  337. tabIndex == 0 ? overview() : events()
  338. }
  339. </View>
  340. <View className='detail_bottom'>
  341. <View className='detail_bottom_btn' onClick={(e) => {
  342. if (process.env.TARO_ENV == 'weapp') {
  343. e.stopPropagation()
  344. }
  345. props.onClose();
  346. }}>{t('feature.track_time_duration.common.okay')}</View>
  347. </View>
  348. </View>
  349. }