ClockNew.tsx 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. import { View, ScrollView, Swiper, SwiperItem, Image } from "@tarojs/components";
  2. import './Clock.scss'
  3. import { useEffect, useRef, useState } from "react";
  4. import TabBar from "@/components/navigation/TabBar";
  5. import { compareVersion, getTimezone, rpxToPx } from "@/utils/tools";
  6. import MainSwiper from "@/features/health/MainSwiper";
  7. import MainConsole from "@/features/health/MainConsole";
  8. import MainHistory from "@/features/health/MainHistory";
  9. import { WindowType } from "@/utils/types";
  10. import { getLatestJournal, windows } from "@/services/health";
  11. import { useDispatch, useSelector } from "react-redux";
  12. import health, { setActiveArchived, setActiveArchivedTotal, setActiveTip, setEatArchived, setEatArchivedTotal, setEatTip, setFastWithSleep, setFinishSetup, setLongFast, setRefreshs, setTitle, setWindows } from "@/store/health";
  13. import dayjs from "dayjs";
  14. import { MainColorType } from "@/context/themes/color";
  15. import NewButton, { NewButtonType } from "@/_health/base/new_button";
  16. import { getThemeColor } from "@/features/health/hooks/health_hooks";
  17. import StatusIndicator, { StatusType } from "@/_health/base/status_indicator";
  18. import { useTranslation } from "react-i18next";
  19. import StickyDateList from "@/_health/components/sticky_date_list";
  20. import NoData from "@/_health/components/no_data";
  21. import Taro, { useDidShow } from "@tarojs/taro";
  22. import { IconClose } from "@/components/basic/Icons";
  23. import showAlert from "@/components/basic/Alert";
  24. import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
  25. let AppState;
  26. if (process.env.TARO_ENV == 'rn') {
  27. AppState = require("react-native").AppState
  28. }
  29. export default function ClockNew(props: { children: any, onScroll: any }) {
  30. const [count, setCount] = useState(0)
  31. const [loaded, setLoaded] = useState(false)
  32. const [showRetry, setShowRetry] = useState(false)
  33. const [scrollLeft, setScrollLeft] = useState(rpxToPx(750) * 0)
  34. const user = useSelector((state: any) => state.user);
  35. const health = useSelector((state: any) => state.health);
  36. const [type, setType] = useState(WindowType.day)
  37. const [needShowAddTip, setNeedShowAddTip] = useState(false)
  38. const [reminderAdd, setReminderAdd] = useState(true)
  39. const [showDate, setShowDate] = useState(false)
  40. const [date, setDate] = useState('')
  41. const [isPulling, setIsPulling] = useState(false)
  42. const healthRef = useRef(health)
  43. const historyRef2 = useRef()
  44. const dispatch = useDispatch();
  45. const { t } = useTranslation()
  46. global.dispatch = dispatch;
  47. const handleAppStateChange = (nextAppState) => {
  48. if (nextAppState != 'active') {
  49. return
  50. }
  51. if (nextAppState == 'active') {
  52. checkTimeZone()
  53. refreshData()
  54. }
  55. };
  56. useDidShow(() => {
  57. if (process.env.TARO_ENV == 'weapp') {
  58. checkTimeZone()
  59. }
  60. setTimeout(() => {
  61. checkVersionUpdate();
  62. }, 1000)
  63. })
  64. function refreshData() {
  65. global.refreshWindow()
  66. global.refreshHistory()
  67. }
  68. function checkTimeZone() {
  69. if (!user.isLogin) return
  70. var timeZoneFormatted = getTimezone()
  71. Taro.getStorage({
  72. key: 'last_tz',
  73. success: function (res) {
  74. if (res.data && res.data != timeZoneFormatted) {
  75. showAlert({
  76. title: t('feature.track_time_duration.change_tz_alert.title'),
  77. content: t('feature.track_time_duration.change_tz_alert.content', { tz: timeZoneFormatted }),
  78. showCancel: false,
  79. confirmText: t('feature.track_time_duration.change_tz_alert.confirm'),
  80. })
  81. // }
  82. }
  83. },
  84. complete: function () {
  85. Taro.setStorage({ key: 'last_tz', data: timeZoneFormatted })
  86. }
  87. })
  88. }
  89. useEffect(() => {
  90. healthRef.current = health;
  91. }, [health])
  92. // useEffect(() => {
  93. // archived()
  94. // }, [health.mode])
  95. useEffect(() => {
  96. if (process.env.TARO_ENV == 'rn') {
  97. AppState.addEventListener('change', handleAppStateChange);
  98. }
  99. Taro.onAppShow(() => {
  100. refreshData()
  101. })
  102. setInterval(() => {
  103. setCount(index => index + 1)
  104. healthRef.current.refreshs.map((item) => {
  105. const strTime = dayjs(item).format('YYYY-MM-DDTHH:mm:ss')
  106. const now = dayjs().format('YYYY-MM-DDTHH:mm:ss')
  107. if (strTime == now) {
  108. getWindows()
  109. if (global.refreshHistory) {
  110. global.refreshHistory()
  111. }
  112. }
  113. })
  114. }, 1000)
  115. setTimeout(() => {
  116. checkVersionUpdate();
  117. }, 1500)
  118. }, [])
  119. useEffect(() => {
  120. getWindows();
  121. if (global.refreshHistory) {
  122. global.refreshHistory()
  123. }
  124. }, [user.isLogin])
  125. global.refreshWindow = () => {
  126. getWindows();
  127. }
  128. function getWindows() {
  129. checkAddToMini()
  130. windows().then(res => {
  131. setLoaded(true)
  132. setShowRetry(false)
  133. if (!(res as any).windows.night_day.night.target) {
  134. var date = new Date()
  135. var hour = date.getHours()
  136. if (hour >= 6 && hour < 18) {
  137. var date1 = new Date()
  138. date1.setHours(6)
  139. date1.setMinutes(0)
  140. date1.setSeconds(0)
  141. var date2 = new Date()
  142. date2.setHours(18)
  143. date2.setMinutes(0)
  144. date2.setSeconds(0);
  145. (res as any).windows.night_day.day.target = {
  146. start_timestamp: date1.getTime(),
  147. end_timestamp: date2.getTime(),
  148. duration: 12 * 60 * 60 * 1000
  149. };
  150. (res as any).windows.night_day.night.target = {
  151. start_timestamp: date2.getTime(),
  152. end_timestamp: date2.getTime() + 12 * 60 * 60 * 1000,
  153. duration: 12 * 60 * 60 * 1000
  154. }
  155. }
  156. else {
  157. var date1 = new Date()
  158. date1.setHours(18)
  159. date1.setMinutes(0)
  160. date1.setSeconds(0);
  161. (res as any).windows.night_day.day.target = {
  162. start_timestamp: date1.getTime(),
  163. end_timestamp: date1.getTime() + 12 * 60 * 60 * 1000,
  164. duration: 12 * 60 * 60 * 1000
  165. };
  166. (res as any).windows.night_day.night.target = {
  167. start_timestamp: date1.getTime() + 12 * 60 * 60 * 1000,
  168. end_timestamp: date1.getTime() + 12 * 60 * 60 * 1000 + 12 * 60 * 60 * 1000,
  169. duration: 12 * 60 * 60 * 1000
  170. }
  171. }
  172. }
  173. dispatch(setFastWithSleep((res as any).fast_with_sleep))
  174. dispatch(setWindows((res as any).windows))
  175. dispatch(setLongFast((res as any).long_fast))
  176. dispatch(setRefreshs((res as any).refresh_timestamps))
  177. dispatch(setFinishSetup((res as any).finish_setup))
  178. setIsPulling(false)
  179. }).catch(e => {
  180. setShowRetry(true)
  181. })
  182. archived()
  183. }
  184. function archived() {
  185. return
  186. getLatestJournal(true, {
  187. window: 'EAT',
  188. }).then(res => {
  189. if (!(res as any).user_confirmed && (res as any).id) {
  190. global.eatTipId = (res as any).id
  191. dispatch(setEatTip(true))
  192. }
  193. })
  194. getLatestJournal(true, {
  195. window: 'ACTIVE'
  196. }).then(res => {
  197. if (!(res as any).user_confirmed && (res as any).id) {
  198. global.activeTipId = (res as any).id
  199. dispatch(setActiveTip(true))
  200. }
  201. })
  202. // if (health.mode == 'EAT' || health.mode == 'ACTIVE') {
  203. // getLatestJournal(true, health.mode).then(res => {
  204. // if (!(res as any).user_confirmed && (res as any).id) {
  205. // if (health.mode == 'EAT') {
  206. // // dispatch(setEatArchived((res as any).latest))
  207. // // dispatch(setEatArchivedTotal((res as any).archived_total))
  208. // dispatch(setEatTip(true))
  209. // }
  210. // else if (health.mode == 'ACTIVE') {
  211. // dispatch(setActiveTip(true))
  212. // // dispatch(setActiveArchived((res as any).latest))
  213. // // dispatch(setActiveArchivedTotal((res as any).archived_total))
  214. // }
  215. // }
  216. // })
  217. // // getArchived(health.mode).then(res => {
  218. // // if (health.mode == 'EAT') {
  219. // // dispatch(setEatArchived((res as any).latest))
  220. // // dispatch(setEatArchivedTotal((res as any).archived_total))
  221. // // }
  222. // // else if (health.mode == 'ACTIVE') {
  223. // // dispatch(setActiveArchived((res as any).latest))
  224. // // dispatch(setActiveArchivedTotal((res as any).archived_total))
  225. // // }
  226. // // })
  227. // }
  228. }
  229. function checkAddToMini() {
  230. if (process.env.TARO_ENV == 'weapp' && user.isLogin && reminderAdd) {
  231. const version = Taro.getAppBaseInfo().SDKVersion
  232. if (compareVersion(version, '2.30.3') >= 0) {
  233. wx.checkIsAddedToMyMiniProgram({
  234. success: (res) => {
  235. if (!res.added) {
  236. setNeedShowAddTip(true)
  237. }
  238. },
  239. fail: (e) => {
  240. }
  241. });
  242. }
  243. }
  244. }
  245. async function checkVersionUpdate() {
  246. if (!user.isLogin) {
  247. return
  248. }
  249. const showAlert1 = await getStorage('148alert') || false;
  250. Taro.setStorage({ key: '148alert', data: true })
  251. console.log('test abc')
  252. if (!showAlert1 && !health.finish_setup){
  253. jumpPage('/_health/pages/guide_begin')
  254. }
  255. }
  256. async function getStorage(key: string) {
  257. try {
  258. const res = await Taro.getStorage({ key });
  259. return res.data;
  260. } catch {
  261. return '';
  262. }
  263. }
  264. function tapScroll(index) {
  265. setScrollLeft(rpxToPx(750) * index)
  266. }
  267. function scroll(e) {
  268. console.log(e.detail.scrollLeft)
  269. }
  270. function pageChanged(index) {
  271. }
  272. function typeChanged(str) {
  273. }
  274. function pageTitle() {
  275. switch (health.mode) {
  276. case 'DAY':
  277. return t('health.window_day')
  278. case 'NIGHT':
  279. return t('health.night')
  280. case 'FAST':
  281. return t('health.fast')
  282. case 'EAT':
  283. return t('health.eat')
  284. case 'SLEEP':
  285. return t('health.sleep')
  286. case 'ACTIVE':
  287. return t('health.active')
  288. }
  289. }
  290. function detail() {
  291. // return <View>11111</View>
  292. if (!health.windows) {
  293. return <View />
  294. }
  295. return <StickyDateList
  296. isPulling={isPulling}
  297. showDate={showDate}
  298. date={date}
  299. disable={props.children}
  300. onRefresherRefresh={() => {
  301. global.refreshWindow()
  302. setIsPulling(true)
  303. if (global.refreshHistory) {
  304. global.refreshHistory()
  305. }
  306. }}
  307. loadMore={() => {
  308. if (historyRef2) {
  309. (historyRef2.current as any).more()
  310. }
  311. }}
  312. onScroll={e => {
  313. props.onScroll(e)
  314. if (e.detail.scrollTop > 240) {
  315. dispatch(setTitle(pageTitle()))
  316. }
  317. else {
  318. dispatch(setTitle(''))
  319. }
  320. if (historyRef2) {
  321. (historyRef2.current as any).onScroll(e)
  322. }
  323. }}
  324. >
  325. <View style={{ display: 'flex', flexDirection: 'column' }}>
  326. {
  327. needShowAddTip && reminderAdd && <View className="guide_tip h26">{t('health.add_mini_guide_tip')}
  328. <NewButton type={NewButtonType.img} btnStyle={{
  329. position: 'absolute',
  330. right: 0,
  331. top: 0,
  332. bottom: 0,
  333. width: rpxToPx(92)
  334. }} onClick={() => {
  335. setReminderAdd(false)
  336. console.log('ssssss')
  337. }}>
  338. <IconClose color={MainColorType.g01} width={rpxToPx(32)} height={rpxToPx(32)} />
  339. </NewButton>
  340. </View>
  341. }
  342. <MainSwiper count={count} pageChanged={pageChanged} typeChanged={typeChanged} />
  343. <MainConsole type={type} />
  344. <MainHistory ref={historyRef2} updateDate={(e) => {
  345. setShowDate(e.show)
  346. setDate(e.date)
  347. }} />
  348. <View style={{ height: user.isLogin ? 150 : 300 }} />
  349. {
  350. (health.mode == 'DAY' || health.mode == 'NIGHT') && <View style={{ height: 150, flexShrink: 0 }} />
  351. }
  352. {
  353. props.children
  354. }
  355. </View>
  356. </StickyDateList>
  357. }
  358. //https://blog.csdn.net/weixin_43525284/article/details/130182218
  359. if (!loaded && showRetry) return <NoData refresh={
  360. () => {
  361. getWindows();
  362. if (global.refreshHistory) {
  363. global.refreshHistory()
  364. }
  365. }
  366. } />
  367. return <View style={{ flex: 1, position: 'relative' }}>
  368. {
  369. process.env.TARO_ENV == 'weapp' ? detail() : <ScrollView style={{ flex: 1, backgroundColor: MainColorType.bg }} onScroll={e => {
  370. if (e.detail.scrollTop > 240) {
  371. dispatch(setTitle(health.mode))
  372. }
  373. else {
  374. dispatch(setTitle(''))
  375. }
  376. }}>
  377. {
  378. detail()
  379. }
  380. {
  381. props.children()
  382. }
  383. </ScrollView>
  384. }
  385. {
  386. process.env.TARO_ENV == 'weapp' && <TabBar index={0} />
  387. }
  388. </View>
  389. }