DayNightDetailPopup.tsx 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. import { View, Text } from '@tarojs/components'
  2. import '@/features/trackTimeDuration/components/CircadianDetailPopup.scss'
  3. import { useTranslation } from 'react-i18next'
  4. import { useEffect, useState } from 'react'
  5. import { getTimezone, getTimezoneName, kIsIOS, 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. import Taro from '@tarojs/taro'
  11. import dayjs, { Dayjs } from 'dayjs'
  12. import showAlert from '@/components/basic/Alert'
  13. import { AtActivityIndicator } from 'taro-ui'
  14. import showActionSheet from '@/components/basic/ActionSheet'
  15. const utc = require('dayjs/plugin/utc')
  16. const timezone = require('dayjs/plugin/timezone')
  17. dayjs.extend(utc)
  18. dayjs.extend(timezone)
  19. let LinearGradient, useActionSheet
  20. if (process.env.TARO_ENV == 'rn') {
  21. LinearGradient = require('react-native-linear-gradient').default
  22. useActionSheet = require('@expo/react-native-action-sheet').useActionSheet
  23. }
  24. export default function DayNightDetailPopup(props: {
  25. isNight: boolean,
  26. authInfo: any,
  27. nightDate: any,
  28. dayDate: any,
  29. onClose: Function,
  30. updateLocation: Function
  31. }) {
  32. const dayNight = useSelector((state: any) => state.night);
  33. const day = useSelector((state: any) => state.day);
  34. const user = useSelector((state: any) => state.user);
  35. const [tabIndex, setTabIndex] = useState(0)
  36. const [isLoading, setIsLoading] = useState(false)
  37. const { t } = useTranslation()
  38. let showActionSheetWithOptions;
  39. if (process.env.TARO_ENV == 'rn') {
  40. showActionSheetWithOptions = useActionSheet()
  41. }
  42. useEffect(() => {
  43. if (isCompleted()) {
  44. setTabIndex(1)
  45. }
  46. }, [])
  47. global.updateLocationLoading = (status) => {
  48. setIsLoading(status)
  49. }
  50. function localNow(now: Date) {
  51. if (props.authInfo && props.authInfo.timezone) {
  52. return new Date(TimeFormatter.transferTimestamp(now.getTime(), props.authInfo.timezone.gmt))
  53. }
  54. return now
  55. }
  56. function getTitle() {
  57. return props.isNight ? t('feature.day_night.night_popover') : t('feature.day_night.day_popover')
  58. }
  59. function getCompletedTitle() {
  60. if (props.isNight) {
  61. return TimeFormatter.getDayOfWeek(new Date(props.authInfo.night_completed.sunrise_ts).getDay(), true)
  62. }
  63. return TimeFormatter.getDayOfWeek(new Date(props.authInfo.night_completed.sunset_ts).getDay(), true)
  64. }
  65. function getSubTitle() {
  66. var now = new Date()
  67. if (props.isNight) {
  68. if (localNow(now).getTime() != now.getTime()) {
  69. return TimeFormatter.getMonthAndDayByTimestamp(props.authInfo.night_completed.sunrise_ts, true)
  70. }
  71. return TimeFormatter.dateDescription(props.authInfo.night_completed.sunrise_ts, true)
  72. }
  73. if (localNow(now).getTime() != now.getTime()) {
  74. return TimeFormatter.getMonthAndDayByTimestamp(props.authInfo.night_completed.sunset_ts, true)
  75. }
  76. return TimeFormatter.dateDescription(props.authInfo.night_completed.sunset_ts, true)
  77. }
  78. function isCompleted() {
  79. if (props.isNight) {
  80. if (props.authInfo && props.authInfo.night_completed && new Date().getTime() > props.authInfo.night_completed.sunrise_ts) {
  81. return true
  82. }
  83. }
  84. else {
  85. if (props.authInfo && props.authInfo.day_completed && new Date().getTime() > props.authInfo.day_completed.sunset_ts) {
  86. return true
  87. }
  88. }
  89. return false
  90. }
  91. function nightDuration() {
  92. if (isCompleted()) {
  93. return TimeFormatter.calculateTimeDifference(props.authInfo.night_completed.sunset_ts, props.authInfo.night_completed.sunrise_ts, true);
  94. }
  95. if (global.nightObj) {
  96. return TimeFormatter.calculateTimeDifference(global.nightObj.sunset.timestamp, global.nightObj.sunrise.timestamp, true);
  97. }
  98. return ''
  99. }
  100. function dayDuration() {
  101. debugger
  102. if (isCompleted()) {
  103. return TimeFormatter.calculateTimeDifference(props.authInfo.day_completed.sunrise_ts, props.authInfo.day_completed.sunset_ts, true);
  104. }
  105. if (global.dayObj) {
  106. return TimeFormatter.calculateTimeDifference(global.dayObj.sunrise.timestamp, global.dayObj.sunset.timestamp, true);
  107. }
  108. return ''
  109. }
  110. function showExtraData() {
  111. var now = new Date()
  112. if (props.isNight) {
  113. if (global.nightObj.sunset.timestamp > now.getTime()) {
  114. return false
  115. }
  116. return true
  117. }
  118. if (global.dayObj.sunrise.timestamp < now.getTime() && now.getTime() < global.dayObj.sunset.timestamp) {
  119. return true;
  120. }
  121. return false
  122. }
  123. function timeCount() {
  124. var now = new Date()
  125. if (props.isNight) {
  126. if (now.getTime() < global.nightObj.sunrise.timestamp) {
  127. return TimeFormatter.countdown(global.nightObj.sunset.timestamp, now.getTime(), true)
  128. }
  129. return TimeFormatter.countdown(global.nightObj.sunset.timestamp, now.getTime(), true)
  130. } else {
  131. if (now.getTime() < global.dayObj.sunset.timestamp) {
  132. return TimeFormatter.countdown(global.dayObj.sunrise.timestamp, now.getTime(), true)
  133. }
  134. return TimeFormatter.countdown(global.dayObj.sunrise.timestamp, now.getTime(), true)
  135. }
  136. }
  137. function timeCount2() {
  138. var now = new Date()
  139. if (props.isNight) {
  140. if (now.getTime() < global.nightObj.sunset.timestamp) {
  141. return TimeFormatter.countdown(global.nightObj.sunrise.timestamp, now.getTime(), true)
  142. }
  143. return TimeFormatter.countdown(global.nightObj.sunrise.timestamp, now.getTime(), true)
  144. } else {
  145. return TimeFormatter.countdown(global.dayObj.sunset.timestamp, now.getTime(), true)
  146. }
  147. }
  148. function timeDesc() {
  149. var now = new Date()
  150. if (props.isNight) {
  151. if (global.nightObj.sunset.timestamp < now.getTime()) {
  152. return t('feature.day_night.time_past_sunset')//'Time past Sunset'
  153. }
  154. return t('feature.day_night.time_to_sunset')//'Time to Sunset'
  155. }
  156. else {
  157. if (now.getTime() < global.dayObj.sunrise.timestamp) {
  158. return t('feature.day_night.time_to_sunrise')//'Time to Sunrise'
  159. }
  160. return t('feature.day_night.time_past_sunrise')//'Time past Sunrise'
  161. }
  162. }
  163. function timeDesc2() {
  164. if (props.isNight) {
  165. return t('feature.day_night.time_to_sunrise')//'Time to Sunrise'
  166. }
  167. return t('feature.day_night.time_to_sunset')//'Time to Sunset'
  168. }
  169. function overview() {
  170. return <View className='pop_ring_bg pop_overview_bg'>
  171. <Text className='pop_duration_title'>{props.isNight ? t('feature.day_night.night_duration') : t('feature.day_night.day_duration')}</Text>
  172. <View style={{ flexDirection: 'row', alignItems: 'center', marginTop: rpxToPx(8), display: 'flex', width: '100%' }}>
  173. <Text className='pop_duration_txt'>{props.isNight ? nightDuration() : dayDuration()}</Text>
  174. </View>
  175. {
  176. !isCompleted() && <View style={{ marginTop: rpxToPx(20), display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
  177. <View className='countdown_time_bg'>
  178. <Text className='title' style={{ color: '#fff', opacity: 0.4 }}>{timeDesc()}</Text>
  179. <Text className='value' style={{ color: props.isNight ? ColorType.night : ColorType.day }}>{timeCount()}</Text>
  180. </View>
  181. {
  182. showExtraData() && <View className='countdown_time_bg'>
  183. <Text className='title' style={{ color: '#fff', opacity: 0.4 }}>{timeDesc2()}</Text>
  184. <Text className='value' style={{ opacity: 0.4, color: props.isNight ? ColorType.night : ColorType.day }}>{timeCount2()}</Text>
  185. </View>
  186. }
  187. </View>
  188. }
  189. </View>
  190. }
  191. function nightDurationDesc() {
  192. if (!props.authInfo || !(props.authInfo as any).lat) {
  193. if (new Date().getHours() >= 6) {
  194. return [t('feature.day_night.tonight'), t('feature.day_night.tomorrow')]
  195. }
  196. return [t('feature.day_night.last_night'), t('feature.day_night.today')]
  197. }
  198. if (diffTimeZone()) {
  199. var sunriseDate = new Date(TimeFormatter.transferTimestamp(global.nightObj.sunrise.timestamp, props.authInfo.timezone.gmt))
  200. var sunsetDate = new Date(TimeFormatter.transferTimestamp(global.nightObj.sunset.timestamp, props.authInfo.timezone.gmt))
  201. return [
  202. (sunsetDate.getMonth() + 1) + '月' + sunsetDate.getDate() + '日',
  203. (sunriseDate.getMonth() + 1) + '月' + sunriseDate.getDate() + '日',
  204. ];
  205. }
  206. var strSunset = ''
  207. var strSunrise = '';
  208. if (global.nightObj) {
  209. if (new Date().getDate() == new Date(global.nightObj.sunset.timestamp).getDate()) {
  210. strSunset = t('feature.day_night.tonight')
  211. }
  212. else if (new Date().getDate() == new Date(global.nightObj.sunset.timestamp + 24 * 3600 * 1000).getDate()) {
  213. strSunset = t('feature.day_night.last_night')
  214. }
  215. else if (new Date().getDate() == new Date(global.nightObj.sunset.timestamp - 24 * 3600 * 1000).getDate()) {
  216. strSunset = t('feature.day_night.tomorrow')
  217. }
  218. else {
  219. strSunset = dayjs(global.nightObj.sunset.timestamp).format(global.language == 'en' ? 'MMM D' : 'M月D日')
  220. }
  221. if (new Date().getDate() == new Date(global.nightObj.sunrise.timestamp).getDate()) {
  222. strSunrise = t('feature.day_night.today')
  223. }
  224. else if (new Date().getDate() == new Date(global.nightObj.sunrise.timestamp + 24 * 3600 * 1000).getDate()) {
  225. strSunrise = t('feature.day_night.yesterday')
  226. }
  227. else if (new Date().getDate() == new Date(global.nightObj.sunrise.timestamp - 24 * 3600 * 1000).getDate()) {
  228. strSunrise = t('feature.day_night.tomorrow')
  229. }
  230. else {
  231. strSunrise = dayjs(global.nightObj.sunrise.timestamp).format(global.language == 'en' ? 'MMM D' : 'M月D日')
  232. }
  233. }
  234. return [strSunset, strSunrise];
  235. }
  236. function dayDurationDesc() {
  237. debugger
  238. if (!props.authInfo || !(props.authInfo as any).lat) {
  239. if (new Date().getHours() >= 18) {
  240. return [t('feature.day_night.tomorrow'), t('feature.day_night.tomorrow')]
  241. }
  242. return [t('feature.day_night.today'), t('feature.day_night.today')]
  243. }
  244. if (diffTimeZone()) {
  245. var sunriseDate = new Date(TimeFormatter.transferTimestamp(global.dayObj.sunrise.timestamp, props.authInfo.timezone.gmt))
  246. var sunsetDate = new Date(TimeFormatter.transferTimestamp(global.dayObj.sunset.timestamp, props.authInfo.timezone.gmt))
  247. return [
  248. (sunriseDate.getMonth() + 1) + '月' + sunriseDate.getDate() + '日',
  249. (sunsetDate.getMonth() + 1) + '月' + sunsetDate.getDate() + '日',
  250. ];
  251. }
  252. var strSunset = ''
  253. var strSunrise = '';
  254. if (global.dayObj) {
  255. if (new Date().getDate() == new Date(global.dayObj.sunset.timestamp).getDate()) {
  256. strSunset = t('feature.day_night.tonight')
  257. }
  258. else if (new Date().getDate() == new Date(global.dayObj.sunset.timestamp + 24 * 3600 * 1000).getDate()) {
  259. strSunset = t('feature.day_night.last_night')
  260. }
  261. else if (new Date().getDate() == new Date(global.dayObj.sunset.timestamp - 24 * 3600 * 1000).getDate()) {
  262. strSunset = t('feature.day_night.tomorrow')
  263. }
  264. else {
  265. strSunset = dayjs(global.dayObj.sunset.timestamp).format(global.language == 'en' ? 'MMM D' : 'M月D日')
  266. }
  267. if (new Date().getDate() == new Date(global.dayObj.sunrise.timestamp).getDate()) {
  268. strSunrise = t('feature.day_night.today')
  269. }
  270. else if (new Date().getDate() == new Date(global.dayObj.sunrise.timestamp + 24 * 3600 * 1000).getDate()) {
  271. strSunrise = t('feature.day_night.yesterday')
  272. }
  273. else if (new Date().getDate() == new Date(global.dayObj.sunrise.timestamp - 24 * 3600 * 1000).getDate()) {
  274. strSunrise = t('feature.day_night.tomorrow')
  275. }
  276. else {
  277. strSunrise = dayjs(global.dayObj.sunrise.timestamp).format(global.language == 'en' ? 'MMM D' : 'M月D日')
  278. }
  279. }
  280. return [strSunrise, strSunset];
  281. // if (props.dayDate.getDate() == new Date().getDate()) {
  282. // return [t('feature.day_night.today'),t('feature.day_night.today')]
  283. // }
  284. // return [t('feature.day_night.tomorrow'),t('feature.day_night.tomorrow')]
  285. }
  286. function diffTimeZone() {
  287. var now = new Date()
  288. if (props.authInfo && props.authInfo.timezone) {
  289. var t1 = TimeFormatter.tzLocalTime(now.getTime(), props.authInfo.timezone.id)//dayjs(now.getTime()).tz(props.authInfo.timezone.id)
  290. if (now.getHours() == t1.hour() && now.getMinutes() == t1.minute()) {
  291. return false
  292. }
  293. else {
  294. return true
  295. }
  296. }
  297. return false
  298. }
  299. function events() {
  300. let timelineItems: any = []
  301. const timeFormat = global.language == 'en' ? 'MMM D HH:mm' : 'M月D日 HH:mm'
  302. const timeFormat2 = global.language == 'en' ? 'MMM D' : 'M月D日'
  303. if (props.isNight) {
  304. if (isCompleted()) {
  305. var newT;
  306. if (props.authInfo.timezone) {
  307. newT = TimeFormatter.tzTimeFormateLocalTime(props.authInfo.night_completed.sunset_ts, props.authInfo.timezone.id, timeFormat)
  308. //dayjs(props.authInfo.night_completed.sunset_ts).tz(props.authInfo.timezone.id).format('M月D日 HH:mm')
  309. }
  310. else {
  311. newT = dayjs(props.authInfo.night_completed.sunset_ts).format(timeFormat)
  312. }
  313. var list = nightDurationDesc()
  314. timelineItems.push(
  315. {
  316. status: 'done',
  317. title: t('feature.day_night.sunset'),//list[0],
  318. // content: newT,
  319. content: diffTimeZone() ? newT : TimeFormatter.dateTimeFormate(props.authInfo.night_completed.sunset_ts, true),
  320. date: '',
  321. color: ColorType.night
  322. }
  323. )
  324. var newT2;
  325. if (props.authInfo.timezone) {
  326. newT2 = TimeFormatter.tzTimeFormateLocalTime(props.authInfo.night_completed.sunrise_ts, props.authInfo.timezone.id, timeFormat)
  327. //dayjs(props.authInfo.night_completed.sunrise_ts).tz(props.authInfo.timezone.id).format('M月D日 HH:mm')
  328. }
  329. else {
  330. newT2 = dayjs(props.authInfo.night_completed.sunrise_ts).format(timeFormat)
  331. }
  332. // var newT2 = dayjs(props.authInfo.night_completed.sunrise_ts).tz('GMT+0800').format('MM-DD HH:mm')//TimeFormatter.transferTimestamp(props.authInfo.night_completed.sunrise_ts, props.authInfo.timezone)
  333. timelineItems.push(
  334. {
  335. status: 'done',
  336. title: t('feature.day_night.sunrise'),//list[1],
  337. // content: newT2,//list[1] + ' ' + global.nightObj.sunrise.time.substring(0, 5),
  338. content: diffTimeZone() ? newT2 : TimeFormatter.dateTimeFormate(props.authInfo.night_completed.sunrise_ts, true),
  339. date: '',
  340. color: ColorType.night
  341. }
  342. )
  343. }
  344. else {
  345. var list = nightDurationDesc()
  346. if (diffTimeZone() && global.nightObj) {
  347. list[0] = TimeFormatter.tzTimeFormateLocalTime(global.nightObj.sunset.timestamp, props.authInfo.timezone.id, timeFormat2)
  348. list[1] = TimeFormatter.tzTimeFormateLocalTime(global.nightObj.sunrise.timestamp, props.authInfo.timezone.id, timeFormat2)
  349. // list[0] = dayjs(global.nightObj.sunset.timestamp).tz(props.authInfo.timezone.id).format('M月D日')
  350. // list[1] = dayjs(global.nightObj.sunrise.timestamp).tz(props.authInfo.timezone.id).format('M月D日')
  351. }
  352. timelineItems.push(
  353. {
  354. status: showExtraData() ? 'done' : 'padding',
  355. title: t('feature.day_night.sunset'),//list[0],
  356. content: list[0] + ' ' + global.nightObj.sunset.time.substring(0, 5),
  357. date: '',
  358. color: ColorType.night
  359. }
  360. )
  361. timelineItems.push(
  362. {
  363. status: 'padding',
  364. title: t('feature.day_night.sunrise'),//list[1],
  365. content: list[1] + ' ' + global.nightObj.sunrise.time.substring(0, 5),
  366. date: '',
  367. color: ColorType.night
  368. }
  369. )
  370. }
  371. }
  372. else {
  373. if (isCompleted()) {
  374. var newT;
  375. if (props.authInfo.timezone) {
  376. newT = TimeFormatter.tzTimeFormateLocalTime(props.authInfo.day_completed.sunrise_ts, props.authInfo.timezone.id, timeFormat)
  377. // newT = dayjs(props.authInfo.day_completed.sunrise_ts).tz(props.authInfo.timezone.id).format('M月D日 HH:mm')
  378. }
  379. else {
  380. newT = dayjs(props.authInfo.day_completed.sunrise_ts).format(timeFormat)
  381. }
  382. timelineItems.push(
  383. {
  384. status: 'done',
  385. title: t('feature.day_night.sunrise'),//list[0],
  386. content: diffTimeZone() ? newT : TimeFormatter.dateTimeFormate(props.authInfo.day_completed.sunrise_ts, true),
  387. date: '',
  388. color: ColorType.day
  389. }
  390. )
  391. var newT2;
  392. if (props.authInfo.timezone) {
  393. newT2 = TimeFormatter.tzTimeFormateLocalTime(props.authInfo.day_completed.sunset_ts, props.authInfo.timezone.id, timeFormat)
  394. // newT2 = dayjs(props.authInfo.day_completed.sunset_ts).tz(props.authInfo.timezone.id).format('M月D日 HH:mm')
  395. }
  396. else {
  397. newT2 = dayjs(props.authInfo.day_completed.sunset_ts).format(timeFormat)
  398. }
  399. timelineItems.push(
  400. {
  401. status: 'done',
  402. title: t('feature.day_night.sunset'),//list[1],
  403. content: diffTimeZone() ? newT2 : TimeFormatter.dateTimeFormate(props.authInfo.day_completed.sunset_ts, true),
  404. date: '',
  405. color: ColorType.day
  406. }
  407. )
  408. }
  409. else {
  410. var list = dayDurationDesc()
  411. if (diffTimeZone() && global.dayObj) {
  412. list[0] = TimeFormatter.tzTimeFormateLocalTime(global.dayObj.sunrise.timestamp, props.authInfo.timezone.id, timeFormat2)
  413. list[1] = TimeFormatter.tzTimeFormateLocalTime(global.dayObj.sunset.timestamp, props.authInfo.timezone.id, timeFormat2)
  414. // list[0] = dayjs(global.dayObj.sunrise.timestamp).tz(props.authInfo.timezone.id).format('M月D日')
  415. // list[1] = dayjs(global.dayObj.sunset.timestamp).tz(props.authInfo.timezone.id).format('M月D日')
  416. }
  417. timelineItems.push(
  418. {
  419. status: showExtraData() ? 'done' : 'padding',
  420. title: t('feature.day_night.sunrise'),//dayDurationDesc(),
  421. content: list[0] + ' ' + global.dayObj.sunrise.time.substring(0, 5),
  422. date: '',
  423. color: ColorType.day
  424. }
  425. )
  426. timelineItems.push(
  427. {
  428. status: 'padding',
  429. title: t('feature.day_night.sunset'),//dayDurationDesc(),
  430. content: list[1] + ' ' + global.dayObj.sunset.time.substring(0, 5),
  431. date: '',
  432. color: ColorType.day
  433. }
  434. )
  435. }
  436. }
  437. return <View><View style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }}>
  438. <Timeline items={timelineItems} title='' width={468} />
  439. </View>
  440. {
  441. diffTimeZone() && <Text className="tz_note_desc" style={{ color: '#FA5151', opacity: 0.4, marginBottom: 10 }}>{diffentTZDesc()}</Text>
  442. }
  443. </View>
  444. }
  445. function getTZLocation() {
  446. var name = props.authInfo.timezone.gmt
  447. if (props.authInfo.timezone.name) {
  448. name = `${name} (${props.authInfo.timezone.name})`
  449. }
  450. return name
  451. }
  452. function getDeviceLocation() {
  453. return `${getTimezone()} (${getTimezoneName()})`
  454. }
  455. function getTZOffset() {
  456. var current1 = dayjs()
  457. var current = TimeFormatter.tzLocalTime(new Date().getTime(), props.authInfo.timezone.id)//dayjs().tz(props.authInfo.timezone.id)
  458. var offset = current.date() * 24 * 60 + current.hour() * 60 + current.minute() - current1.date() * 24 * 60 - current1.hour() * 60 - current1.minute()
  459. var hour = Math.floor(Math.abs(offset) / 60)
  460. var minute = Math.abs(offset) % 60
  461. var time = ''
  462. if (global.language == 'en') {
  463. time = `${hour} h`
  464. if (minute > 0) {
  465. time += ` ${minute} m`
  466. }
  467. }
  468. else {
  469. time = `${hour}小时`
  470. if (minute > 0) {
  471. time += `${minute}分钟`
  472. }
  473. }
  474. return offset > 0 ? t('feature.day_night.ahead_desc', { time: time }) : t('feature.day_night.behind_desc', { time: time })
  475. }
  476. function diffentTZDesc() {
  477. var current1 = dayjs()
  478. var current = TimeFormatter.tzLocalTime(new Date().getTime(), props.authInfo.timezone.id)//dayjs().tz(props.authInfo.timezone.id)
  479. var offset = current.date() * 24 * 60 + current.hour() * 60 + current.minute() - current1.date() * 24 * 60 - current1.hour() * 60 - current1.minute()
  480. var hour = Math.floor(Math.abs(offset) / 60)
  481. var minute = Math.abs(offset) % 60
  482. var time = ''
  483. var type = ''
  484. if (global.language == 'en') {
  485. time = `${hour} h`
  486. type = offset > 0 ? t('feature.day_night.ahead_of') : t('feature.day_night.behind')
  487. if (minute > 0) {
  488. time += ` ${minute} m`
  489. }
  490. }
  491. else {
  492. time = `${hour}小时`
  493. type = offset > 0 ? t('feature.day_night.ahead_of') : t('feature.day_night.behind')
  494. if (minute > 0) {
  495. time += `${minute}分钟`
  496. }
  497. }
  498. return t('feature.common.diff_tz_desc', { location: getTZLocation(), device_location: getDeviceLocation(), offset: getTZOffset() })
  499. }
  500. function getLocation() {
  501. var city = ''
  502. if ((props.authInfo as any).address) {
  503. if ((props.authInfo as any).address.city.length > 0) {
  504. city = (props.authInfo as any).address.city
  505. }
  506. else if ((props.authInfo as any).address.province.length > 0) {
  507. city = (props.authInfo as any).address.province
  508. }
  509. else if ((props.authInfo as any).address.country.length > 0) {
  510. city = (props.authInfo as any).address.country
  511. }
  512. else {
  513. city = t('feature.track_time_duration.third_ring.unknown')
  514. }
  515. }
  516. else {
  517. city = t('feature.track_time_duration.third_ring.unknown')
  518. }
  519. // return city +' | '+parseInt(authInfo.lat)+'°'+ ' '+parseInt(authInfo.lng)
  520. return `${city} | ${Math.abs(parseInt(props.authInfo.lat))}°${parseInt(props.authInfo.lat) < 0 ? 'S' : 'N'} ${Math.abs(parseInt(props.authInfo.lng))}°${parseInt(props.authInfo.lng) < 0 ? 'W' : 'E'} | ${props.authInfo.timezone.gmt}`
  521. }
  522. function chooseLocation() {
  523. props.updateLocation()
  524. }
  525. function clickFooterBtn(e) {
  526. if (process.env.TARO_ENV == 'weapp') {
  527. e.stopPropagation()
  528. }
  529. // else {
  530. // props.onClose()
  531. // }
  532. //
  533. showAlert({
  534. title: t('feature.day_night.location_need'),
  535. content: props.isNight ? t('feature.day_night.location_need_content_night') : t('feature.day_night.location_need_content_day'),
  536. showCancel: true,
  537. cancelText: t('feature.day_night.later'),
  538. confirmText: t('feature.day_night.picker_now'),
  539. confirm: () => {
  540. props.updateLocation()
  541. }
  542. })
  543. }
  544. function testTapLocationIndex(index) {
  545. switch (index) {
  546. case 0:
  547. {
  548. global.uploadLocation({
  549. latitude: 40.697,
  550. longitude: -74.309
  551. })
  552. }
  553. break;
  554. case 1:
  555. {
  556. global.uploadLocation({
  557. latitude: 59.699,
  558. longitude: -179.463
  559. })
  560. }
  561. break;
  562. case 2:
  563. {
  564. global.uploadLocation({
  565. latitude: 64.4190338,
  566. longitude: 15.3812476
  567. })
  568. }
  569. break;
  570. case 3:
  571. {
  572. global.uploadLocation({
  573. latitude: -40.4221762,
  574. longitude: 164.4216501
  575. })
  576. }
  577. break;
  578. }
  579. }
  580. function testChangeLocation() {
  581. if (process.env.TARO_ENV == 'rn' && kIsIOS) {
  582. showActionSheet({
  583. showActionSheetWithOptions: showActionSheetWithOptions,
  584. itemList: [
  585. '纽约40.697,-74.309',
  586. '阿拉斯加59.699,-179.463',
  587. '芬兰64.4190338,15.3812476',
  588. '新西兰-40.4221762,164.4216501'
  589. ],
  590. success: (res) => {
  591. testTapLocationIndex(res)
  592. }
  593. });
  594. return
  595. }
  596. Taro.showActionSheet({
  597. itemList: [
  598. '纽约40.697,-74.309',
  599. '阿拉斯加59.699,-179.463',
  600. '芬兰64.4190338,15.3812476',
  601. '新西兰-40.4221762,164.4216501'
  602. ]
  603. })
  604. .then(res => {
  605. console.log(res.tapIndex)
  606. testTapLocationIndex(res.tapIndex)
  607. })
  608. .catch(err => {
  609. console.log(err.errMsg)
  610. })
  611. }
  612. return <View className='detail_container'>
  613. {/* {
  614. isCompleted() ? <Text className='detail_popup_title' >{getCompletedTitle()}<Text className='detail_popup_subttitle'> {getSubTitle()}</Text></Text> :
  615. <Text className='detail_popup_title' >{getTitle()}</Text>
  616. } */}
  617. <View style={{ display: 'flex', flexDirection: 'row', alignItems: 'flex-end' }}>
  618. <Text className='detail_popup_title'>{isCompleted() ? getCompletedTitle() : getTitle()}</Text>
  619. {
  620. isCompleted() && <Text className='detail_popup_subttitle'> {getSubTitle()}</Text>
  621. }
  622. </View>
  623. {
  624. user.test_user && <Text style={{ color: '#fff', fontSize: 20, fontWeight: 'bold' }} onClick={testChangeLocation}>位置更改测试</Text>
  625. }
  626. <View className='detail_tabbar'>
  627. <View onClick={() => { setTabIndex(0) }} className={tabIndex == 0 ? 'detail_tabitem_sel' : 'detail_tabitem_nor'}>{t('feature.day_night.overview')}</View>
  628. <View onClick={() => { setTabIndex(1) }} className={tabIndex == 1 ? 'detail_tabitem_sel' : 'detail_tabitem_nor'}>{t('feature.day_night.events')}</View>
  629. </View>
  630. <View className='detail_content'>
  631. {
  632. tabIndex == 0 ? overview() : events()
  633. }
  634. </View>
  635. {
  636. (props.authInfo && props.authInfo.lat) ?
  637. <View style={{ display: 'flex', flexDirection: 'column' }}>
  638. <Text className='day_night_pop_location'>{getLocation()}</Text>
  639. <View style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
  640. <Text className='day_night_pop_desc'>{t('feature.track_time_duration.third_ring.base_location_desc')}</Text>
  641. <View onClick={chooseLocation}>
  642. <Text className='day_night_pop_choose' style={{ color: props.isNight ? ColorType.night : ColorType.day }}>{t('feature.track_time_duration.third_ring.update_my_location')}</Text>
  643. </View>
  644. </View>
  645. </View> :
  646. <View className='detail_bottom'>{
  647. process.env.TARO_ENV == 'weapp' ?
  648. <View className='detail_bottom_btn' style={{ color: '#000' }} onClick={(e) => {
  649. clickFooterBtn(e)
  650. }}>{props.isNight ? t('feature.day_night.get_local_time') : t('feature.day_night.get_local_time_sunrise')}</View> :
  651. <View onClick={(e) => {
  652. clickFooterBtn(e)
  653. }}>
  654. <LinearGradient
  655. style={{
  656. width: 300,
  657. height: 50,
  658. borderRadius: 25,
  659. alignItems: 'center',
  660. justifyContent: 'center',
  661. flexDirection: 'row'
  662. }}
  663. colors={[ColorType.fast, ColorType.sleep]}
  664. start={{ x: 0, y: 0 }}
  665. end={{ x: 1, y: 0 }}
  666. >
  667. {
  668. isLoading && <View style={{ display: 'flex', overflow: 'hidden', height: 20, marginRight: 5 }}><AtActivityIndicator mode="center" color="#000" /></View>
  669. }
  670. <Text style={{ fontWeight: 'bold', fontSize: 18, color: '#000', opacity: isLoading ? 0.6 : 1.0 }}>{props.isNight ? t('feature.day_night.get_local_time') : t('feature.day_night.get_local_time_sunrise')}</Text>
  671. </LinearGradient>
  672. </View>
  673. }
  674. </View>
  675. }
  676. </View>
  677. }