Clock.weapp.tsx 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. import { Component, PropsWithChildren, useEffect, useRef, useState } from 'react'
  2. import { View, Text, Button, Input, Picker, Swiper, SwiperItem, Icon } from '@tarojs/components'
  3. import '../index/index.scss'
  4. import './Clock.scss'
  5. // import './context/locales/index'
  6. import '@/context/locales/index'
  7. import Taro, { useDidShow, usePageScroll, useReady, useRouter, useShareAppMessage } from '@tarojs/taro'
  8. // import ComponentA from './component'
  9. import { useDispatch, useSelector } from 'react-redux';
  10. import { getInfoSuccess, logoutSuccess } from '@/store/user';
  11. import { wxPubFollow } from '@/services/permission';
  12. import { gobalConfigs, staticResources, uploadSessionKey } from '@/services/common';
  13. import Clocks from '@/features/trackTimeDuration/components/Clock';
  14. import Console from '@/features/trackTimeDuration/components/Console';
  15. import Schedule from '@/features/trackTimeDuration/components/Schedule';
  16. import { getChecks, getClocks } from '@/services/trackTimeDuration';
  17. import { setScenario } from '@/store/scenario';
  18. import { setSpecifiedStatus, setSpecifiedState, machine } from '@/store/trackTimeMachine';
  19. import trackTimeService from '@/store/trackTimeMachine';
  20. import { setWXFollow } from '@/store/permission';
  21. import Tooltip from '@/components/view/Tooltip'
  22. import RequestType, { thirdPartRequest } from '@/services/thirdPartRequest'
  23. import { setConfigs } from '@/store/common'
  24. import RecordFastSleep from '@/features/trackTimeDuration/components/RecordFastSleep'
  25. import Box from '@/components/layout/Box'
  26. import Layout from '@/components/layout/layout'
  27. import { CheckBoxType, NaviBarTitleShowType, TemplateType } from '@/utils/types'
  28. import { updateScenario } from '@/store/time'
  29. import { showModal } from '@/store/modal'
  30. import { ConsoleType, changeConsoleStatus } from '@/store/console'
  31. import TitleView from '@/features/trackTimeDuration/components/TitleView'
  32. import StatusIndicator from '@/features/trackTimeDuration/components/StatusIndicator'
  33. import { useTranslation } from 'react-i18next'
  34. import TableCellHeader from '@/components/layout/TableCellHeader'
  35. import SectionHeader from '@/components/layout/SectionHeader'
  36. import Header from '@/components/layout/Header'
  37. import { TimeFormatter } from '@/utils/time_format'
  38. import NoData from '@/components/view/NoData'
  39. import { ColorType } from '@/context/themes/color'
  40. import { jumpPage } from '@/features/trackTimeDuration/hooks/Common'
  41. // import TabBar from '../../components/Tabbar';
  42. // import Rings from '@components/view/Rings';
  43. let useNavigation;
  44. if (process.env.TARO_ENV == 'rn') {
  45. useNavigation = require("@react-navigation/native").useNavigation
  46. }
  47. export default function IndexPage() {
  48. const dispatch = useDispatch();
  49. const { t } = useTranslation()
  50. const [checkData, setCheckData] = useState(null)
  51. const user = useSelector((state: any) => state.user);
  52. const time = useSelector((state: any) => state.time);
  53. const common = useSelector((state: any) => state.common);
  54. const consoleData = useSelector((state: any) => state.console);
  55. const [counter, setCounter] = useState(0)
  56. const [timerId, setTimerId] = useState(null)
  57. const [needShowAddTip, setNeedShowAddTip] = useState(false)
  58. const [showErrorPage, setErrorPage] = useState(false)
  59. const [swiperIndex, setSwiperIndex] = useState(0)
  60. const [autoPlay, setAutoPlay] = useState(false)
  61. const [showModal, setShowModal] = useState(false)
  62. const [modalDetail, setModalDetail] = useState<any>({})
  63. const [showModal2, setShowModal2] = useState(false)
  64. const [modalDetail2, setModalDetail2] = useState<any>({})
  65. const [showSingleFastEnd, setShowSingleFastEnd] = useState(false)
  66. const [consoleStatus, setConsoleStatus] = useState(consoleData.status)
  67. let navigation;
  68. if (useNavigation) {
  69. navigation = useNavigation()
  70. }
  71. global.dispatch = dispatch;
  72. global.checkData = () => {
  73. console.log('refresh clock data')
  74. getCheckData()
  75. }
  76. useEffect(() => {
  77. global.consoleType = 'idle'
  78. dispatch(staticResources() as any);
  79. // dispatch(gobalConfigs() as any);
  80. trackTimeService.onTransition(state => {
  81. if ((state.value as any).FAST_SLEEP == 'COMPLETED' ||
  82. (state.value as any).FAST == 'ONGOING' ||
  83. (state.value as any).SLEEP == 'ONGOING' ||
  84. (state.value as any).FAST_SLEEP == 'ONGOING1' ||
  85. (state.value as any).FAST_SLEEP == 'ONGOING2' ||
  86. (state.value as any).FAST_SLEEP == 'ONGOING3' ||
  87. (state.value as any).FAST == 'COMPLETED' ||
  88. (state.value as any).SLEEP == 'COMPLETED') {
  89. getCheckData()
  90. }
  91. })
  92. }, [])
  93. useEffect(() => {
  94. setConsoleStatus(consoleData.status)
  95. switch (consoleData.status) {
  96. // case ConsoleType.going:
  97. // setShowSingleFastEnd(true)
  98. // setTimeout(() => {
  99. // setShowSingleFastEnd(false)
  100. // setSwiperIndex(1)
  101. // setAutoPlay(true)
  102. // dispatch(changeConsoleStatus({ status: ConsoleType.end }))
  103. // }, 2000)
  104. // break
  105. case ConsoleType.end:
  106. setTimeout(() => {
  107. dispatch(changeConsoleStatus({ status: ConsoleType.idle }))
  108. }, 2000)
  109. break
  110. }
  111. }, [consoleData.status])
  112. useEffect(() => {
  113. if (user.isLogin) {
  114. //检查用户是否添加过小程序
  115. checkAddToMini();
  116. //检查session是否过期
  117. checkSession()
  118. getCheckData()
  119. }
  120. }, [user.isLogin])
  121. function checkSession() {
  122. if (process.env.TARO_ENV === 'weapp') {
  123. thirdPartRequest(RequestType.RequestTypeCheckSession).then(res => {
  124. }).catch(err => {
  125. console.log('session_key 已经失效,需要更新登录code')
  126. thirdPartRequest(RequestType.RequestTypeWXLogin).then(result => {
  127. uploadSessionKey({ type: 'WX_MP', code: (result as any).code });
  128. })
  129. })
  130. }
  131. }
  132. function checkAddToMini() {
  133. process.env.TARO_ENV == 'weapp' &&
  134. wx.checkIsAddedToMyMiniProgram({
  135. success: (res) => {
  136. if (!res.added) {
  137. setNeedShowAddTip(true)
  138. }
  139. },
  140. fail: (e) => {
  141. }
  142. });
  143. }
  144. useEffect(() => {
  145. startTimer();
  146. return () => {
  147. // 在组件卸载时清除定时器
  148. if (timerId) {
  149. clearInterval(timerId);
  150. }
  151. };
  152. }, [timerId]);
  153. const startTimer = () => {
  154. // 避免重复启动定时器
  155. if (timerId) {
  156. return;
  157. }
  158. const id = setInterval(() => {
  159. setCounter((prevCounter) => prevCounter + 1);
  160. //每天0点刷新一下打卡数据
  161. var now = new Date()
  162. if (now.getHours() == 0 && now.getMinutes() == 0) {
  163. getCheckData()
  164. }
  165. }, 1000);
  166. setTimerId(id as any);
  167. };
  168. useReady(async () => {
  169. const userData = await getStorage('userData');
  170. if (userData) {
  171. dispatch(getInfoSuccess(JSON.parse(userData as string)) as any);
  172. setTimeout(() => {
  173. checkWXPubFollow()
  174. getCheckData()
  175. }, 200)
  176. }
  177. })
  178. if (process.env.TARO_ENV == 'weapp') {
  179. useShareAppMessage((e) => {
  180. return {
  181. title: t('share.title'),
  182. path: 'pages/clock/Clock'
  183. }
  184. })
  185. }
  186. function clearTempScenarioCache() {
  187. global.schedule_fast = null
  188. global.schedule_sleep = null
  189. Taro.removeStorage({
  190. key: 'tempScenario',
  191. success: function (res) {
  192. }
  193. })
  194. }
  195. usePageScroll((e) => {
  196. })
  197. useDidShow(() => {
  198. global.updateTab(0)
  199. if (user.isLogin) {
  200. checkWXPubFollow()
  201. // getCheckData();
  202. }
  203. clearTempScenarioCache()
  204. })
  205. global.refreshTime = () => {
  206. getCheckData()
  207. }
  208. global.showSingleFastEnd = () => {
  209. setShowSingleFastEnd(true)
  210. }
  211. function tapClock() {
  212. if (!user.isLogin) {
  213. jumpPage('/pages/account/ChooseAuth', 'ChooseAuth', navigation)
  214. }
  215. }
  216. function getCheckData() {
  217. getClocks().then(res => {
  218. setErrorPage(false)
  219. dispatch(updateScenario((res as any).current_record))
  220. dispatch(setConfigs((res as any).time_input_schema));
  221. dispatch(setScenario((res as any).scenario));
  222. if ((res as any).theme_color) {
  223. global.fastColor = (res as any).theme_color.fast
  224. global.sleepColor = (res as any).theme_color.sleep
  225. }
  226. machine.context.checkData = res as any;
  227. global.scenario = (res as any).current_record.scenario;
  228. const currentState = trackTimeService.getSnapshot();
  229. let json = {};
  230. var key = (res as any).current_record.scenario
  231. var status = (res as any).current_record.status
  232. json[key] = status
  233. currentState.value = json;
  234. machine.context.currentStatus = `${key}.${status}`;//'mixed.ON_GOING2'
  235. setCheckData(res as any)
  236. if ((res as any).current_record.status != 'ONGOING1') {
  237. setSwiperIndex(0)
  238. }
  239. else {
  240. if (global.consoleType == 'going') {
  241. setShowSingleFastEnd(true)
  242. setTimeout(() => {
  243. setShowSingleFastEnd(false)
  244. setSwiperIndex(1)
  245. setAutoPlay(true)
  246. global.consoleType = 'end'
  247. dispatch(changeConsoleStatus({ status: ConsoleType.end }))
  248. setTimeout(() => {
  249. global.consoleType = 'idle'
  250. }, 2000)
  251. }, 500)
  252. }
  253. else {
  254. }
  255. }
  256. }).catch(e => {
  257. console.log('aaa')
  258. if (!checkData) {
  259. console.log('this is a test')
  260. setErrorPage(true)
  261. }
  262. else {
  263. console.log('sss')
  264. }
  265. })
  266. }
  267. function checkWXPubFollow() {
  268. var params;
  269. if (global.forceRefreshWXPub) {
  270. params = {
  271. force_refresh: true
  272. }
  273. }
  274. global.forceRefreshWXPub = false
  275. wxPubFollow(params).then(res => {
  276. dispatch(setWXFollow((res as any).wx_pub_followed));
  277. console.log('当前的关注状态' + (res as any).wx_pub_followed);
  278. })
  279. }
  280. async function getStorage(key: string) {
  281. try {
  282. const res = await Taro.getStorage({ key });
  283. return res.data;
  284. } catch {
  285. return '';
  286. }
  287. }
  288. function schedule() {
  289. if (!user.isLogin) {
  290. return <View />
  291. }
  292. return <Schedule data={(checkData as any).current_record} />
  293. }
  294. function needSwiper() {
  295. var isNeed = time.scenario == 'FAST_SLEEP' &&
  296. (time.status == 'WAIT_FOR_START' ||
  297. time.status == 'ONGOING1' ||
  298. time.status == 'ONGOING2')
  299. if (showSingleFastEnd) {
  300. return false;
  301. }
  302. return isNeed
  303. }
  304. global.showClockModal = (isShow: boolean, detail: any) => {
  305. setShowModal(isShow)
  306. setModalDetail(detail)
  307. }
  308. global.showClockModal2 = (isShow: boolean, detail: any) => {
  309. setShowModal2(isShow)
  310. setModalDetail2(detail)
  311. }
  312. function headerView() {
  313. return <TitleView title={t('page.clock.title')} showAddBtn={true}>
  314. <StatusIndicator />
  315. </TitleView>
  316. }
  317. function errorView() {
  318. if (showErrorPage) {
  319. return <NoData refresh={() => { getCheckData() }} />
  320. }
  321. return <View />
  322. }
  323. function consoleView() {
  324. if (!checkData) {
  325. return <View />
  326. }
  327. return <View className='console_bg'>
  328. {
  329. needSwiper() ? <Swiper className='swiper' indicatorColor='#333'
  330. indicatorActiveColor='#999'
  331. current={swiperIndex}
  332. autoplay={autoPlay}
  333. duration={300}
  334. interval={300}
  335. // indicator-margin={30}
  336. indicator-offset={[0, -30]}
  337. indicator-height={30}
  338. indicatorDots={global.consoleType == 'idle'}
  339. onChange={(e) => {
  340. setSwiperIndex(e.detail.current)
  341. if (e.detail.current == 0)
  342. setAutoPlay(false)
  343. }}
  344. >
  345. <SwiperItem className='swiperItem'>
  346. <Console />
  347. </SwiperItem>
  348. <SwiperItem className='swiperItem'>
  349. <Console isNextStep={true} />
  350. </SwiperItem>
  351. </Swiper> :
  352. <Console isNextStep={showSingleFastEnd} />
  353. }
  354. </View>
  355. }
  356. function detail() {
  357. return (
  358. <Layout type={TemplateType.customHeader} header={headerView()} title={t('page.clock.title')} titleShowStyle={NaviBarTitleShowType.scrollToShow}>
  359. <View style={{ flex: 1, flexDirection: 'column', display: 'flex', backgroundColor: '#000', color: '#fff' }}>
  360. {
  361. needShowAddTip && <Tooltip title="添加到我的小程序" closeTip={() => { setNeedShowAddTip(false) }} />
  362. }
  363. <Box>
  364. <View className='clock_bg' onClick={tapClock}>
  365. <Clocks />
  366. </View>
  367. </Box>
  368. {
  369. errorView()
  370. }
  371. {
  372. user.isLogin && consoleView()
  373. }
  374. {
  375. user.isLogin && checkData && schedule()
  376. }
  377. {
  378. user.isLogin && <View style={{ backgroundColor: global.isDebug ? 'pink' : 'transparent' }}>
  379. {
  380. checkData && (checkData as any).latest_record &&
  381. <SectionHeader top={48} bottom={24} title={t('feature.track_time_duration.record_fast_sleep.header.latest_record')}>
  382. <Header title='' action={() => {
  383. jumpPage('/pages/common/RecordsHistory?type=time&title=time')
  384. }} />
  385. </SectionHeader>
  386. }
  387. </View>
  388. }
  389. {
  390. user.isLogin && checkData && (checkData as any).latest_record &&
  391. <RecordFastSleep type='latest' data={(checkData as any).latest_record} delSuccess={getCheckData} />
  392. }
  393. <View style={{ height: 100 }} />
  394. </View>
  395. {
  396. showModal && modalDetail
  397. }
  398. {
  399. showModal2 && modalDetail2
  400. }
  401. </Layout>
  402. )
  403. }
  404. if (process.env.TARO_ENV == 'rn')
  405. return <View />
  406. return detail()
  407. }