Clock.tsx 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948
  1. import { View, Text, Image, ScrollView, PageContainer, Swiper, SwiperItem, Switch } from "@tarojs/components";
  2. import Tabbar from "@/components/navigation/TabBar";
  3. import IndexItem from '@/features/trackTimeDuration/components/IndexItem';
  4. import Rings from "@/features/trackTimeDuration/components/Rings";
  5. import './Clock.scss'
  6. import { useDispatch, useSelector } from "react-redux";
  7. import { useDidHide, useDidShow, usePageScroll, useReady, useShareAppMessage } from "@tarojs/taro";
  8. import Taro from "@tarojs/taro";
  9. import { getInfoSuccess } from "@/store/user";
  10. import { clockHome, clockSummaryRecords, clockSummaryStats, getClockRecords, getClocks, getPlans } from "@/services/trackTimeDuration";
  11. import { updateScenario } from "@/store/time";
  12. import { setConfigs } from "@/store/common";
  13. import { setScenario, setStep } from "@/store/scenario";
  14. import { useEffect, useRef, useState } from "react";
  15. import { IconPlus, IconRadioCheck, IconRadioCross } from "@/components/basic/Icons";
  16. import { ColorType } from "@/context/themes/color";
  17. import { bigRingRadius, getBgRing, getCommon, getDot, getSchedule, ringWidth, smallRingRadius } from "@/features/trackTimeDuration/hooks/RingData";
  18. import { RealRing, CurrentDot } from "@/features/trackTimeDuration/components/Rings";
  19. import IndexConsole from "@/features/trackTimeDuration/components/IndexConsole";
  20. import Modal from '@/components/layout/Modal'
  21. import { compareVersion, getTimezone, getTimezoneId, getTimezoneName, rpxToPx } from "@/utils/tools";
  22. import RecordFastSleep from "@/features/trackTimeDuration/components/RecordFastSleep";
  23. import DayLight from "@/features/trackTimeDuration/components/DayLight";
  24. import { getInfo, latestLocation } from "@/services/user";
  25. import { TimeFormatter } from "@/utils/time_format";
  26. import WeekCalendar from "@/features/trackTimeDuration/components/WeekCalendar";
  27. import { useTranslation } from "react-i18next";
  28. import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
  29. import Layout from "@/components/layout/layout";
  30. import { ModalType, NaviBarTitleShowType, TemplateType } from "@/utils/types";
  31. import TitleView from "@/features/trackTimeDuration/components/TitleView";
  32. import ClockHeader from "@/features/trackTimeDuration/components/ClockHeader";
  33. import DurationPicker from "@/features/trackTimeDuration/components/DurationPicker";
  34. import SegmentPop from "@/features/trackTimeDuration/components/SegmentPop";
  35. import Box from "@/components/layout/Box";
  36. import DayNightCard from "@/features/daynight/DayNightCard";
  37. import StageSelector from "@/features/trackTimeDuration/components/StageSelector";
  38. import { ChooseScenarioBtn } from "@/features/common/SpecBtns";
  39. import { clearNightStore, showNight } from "@/store/night";
  40. import { showDay } from "@/store/day";
  41. import { clientInfo, staticResources, systemVersion } from "@/services/common";
  42. import { changeFastDuration, changeSleepDuration, setCurrentRecord, setSchedule } from "@/store/ring";
  43. import { checkAuthorized } from "@/utils/check_authorized";
  44. import NoData from "@/components/view/NoData";
  45. import { AtActivityIndicator } from "taro-ui";
  46. import Tooltip from "@/components/view/Tooltip";
  47. import AllRings from "@/features/daynight/AllRings";
  48. import Streaks from "@/features/trackTimeDuration/components/Streaks";
  49. import dayjs from 'dayjs'
  50. import DayNightSwiper from "@/features/daynight/DayNightSwiper";
  51. import showAlert from "@/components/basic/Alert";
  52. import { APP_VERSION, WX_VERSION } from "@/services/http/api";
  53. const utc = require('dayjs/plugin/utc')
  54. const timezone = require('dayjs/plugin/timezone')
  55. dayjs.extend(utc)
  56. dayjs.extend(timezone)
  57. let GradientText
  58. let useNavigation;
  59. let timer
  60. let pauseTimer = false;
  61. let AppState;
  62. let needScroll = false;
  63. let showUpdate = false;
  64. let Linking;
  65. let JPush;
  66. let checkNotification, uploadPermissions, NativeAppEventEmitter;
  67. let messaging;
  68. if (process.env.TARO_ENV == 'rn') {
  69. messaging = require('@react-native-firebase/messaging').default
  70. JPush = require('jpush-react-native').default;
  71. Linking = require('react-native').Linking;
  72. AppState = require("react-native").AppState
  73. NativeAppEventEmitter = require("react-native").NativeAppEventEmitter
  74. GradientText = require('@/components/basic/GradientText').default
  75. useNavigation = require("@react-navigation/native").useNavigation
  76. checkNotification = require('@/utils/native_permission_check').checkNotification;
  77. uploadPermissions = require('@/utils/native_permission_check').uploadPermissions;
  78. }
  79. const defaultValue = `[{"scenario":{"name":"FAST_SLEEP","count":0,"schedule":{"fast":{"start_time":"15:00","end_time":"08:00"},"sleep":{"start_time":"22:00","end_time":"07:00"}}},"current_record":{"scenario":"FAST_SLEEP","status":"WAIT_FOR_START","fast":{"status":"WAIT_FOR_START","target_start_time":1710514800000,"target_end_time":1710576000000},"sleep":{"status":"WAIT_FOR_START","target_start_time":1710540000000,"target_end_time":1710572400000}},"wx_pub_followed":false,"time_input_schema":{"min":60,"max":1380,"step":5},"theme_color":{"fast":"#00FFFF","sleep":"#8183FF"}},{"scenarios":[{"name":"FAST","count":0,"schedule":{"fast":{"start_time":"15:00","end_time":"08:00"}}},{"name":"SLEEP","count":0,"schedule":{"sleep":{"start_time":"22:00","end_time":"07:00"}}},{"name":"FAST_SLEEP","count":0,"schedule":{"fast":{"start_time":"15:00","end_time":"08:00"},"sleep":{"start_time":"22:00","end_time":"07:00"}}}],"select_count":0,"theme_color":{"fast":"#00FFFF","sleep":"#8183FF"}}]`
  80. let fcmUnsubscribe: any = null;
  81. export default function Page() {
  82. const dispatch = useDispatch();
  83. global.dispatch = dispatch;
  84. let navigation;
  85. if (useNavigation) {
  86. navigation = useNavigation()
  87. }
  88. const { t } = useTranslation()
  89. const user = useSelector((state: any) => state.user);
  90. const time = useSelector((state: any) => state.time);
  91. const [count, setCount] = useState(0)
  92. const [homeData, setHomeData] = useState(null)
  93. const [loaded, setLoaded] = useState(false)
  94. const [showErrorPage, setErrorPage] = useState(false)
  95. const [showModal, setShowModal] = useState(false)
  96. const [modalDetail, setModalDetail] = useState<any>(null)
  97. const [showModal2, setShowModal2] = useState(false)
  98. const [modalDetail2, setModalDetail2] = useState<any>(null)
  99. const [debugInfo, setDebugInfo] = useState(null)
  100. const [needShowAddTip, setNeedShowAddTip] = useState(false)
  101. const [showTip, setShowTip] = useState(false)
  102. const [records, setRecords] = useState([])
  103. const permission = useSelector((state: any) => state.permission);
  104. const common = useSelector((state: any) => state.common);
  105. const scrollRef = useRef(null);
  106. const nightStore = useSelector((state: any) => state.night);
  107. if (process.env.TARO_ENV == 'weapp') {
  108. useShareAppMessage((e) => {
  109. return {
  110. title: t('feature.track_time_duration.common.share_title'),
  111. path: 'pages/clock/Clock'
  112. }
  113. })
  114. }
  115. useEffect(() => {
  116. dispatch(staticResources() as any);
  117. timer = setInterval(() => {
  118. var now = new Date()
  119. if (now.getDay() == 0 && now.getHours() == 12 && now.getMinutes() == 0 && now.getSeconds() == 0) {
  120. if (global.refrehWeekly) {
  121. global.refrehWeekly()
  122. }
  123. }
  124. if (global.pauseIndexTimer || pauseTimer) {
  125. return
  126. }
  127. setCount((prevCounter) => prevCounter + 1)
  128. }, 1000)
  129. }, [])
  130. useEffect(() => {
  131. // Taro.request({
  132. // url:'https://api.fast.dev.liveplus.fun/api/static-resource-urls',
  133. // method:'GET',
  134. // data:{},
  135. // timeout:20000,
  136. // success(result) {
  137. // showAlert({
  138. // title:'success',
  139. // content:JSON.stringify(result)
  140. // })
  141. // },
  142. // fail(res) {
  143. // showAlert({
  144. // title:'fail',
  145. // content:JSON.stringify(res)
  146. // })
  147. // },
  148. // })
  149. if (process.env.TARO_ENV == 'weapp') {
  150. loadWXCache()
  151. }
  152. else {
  153. loadRNCache()
  154. }
  155. if (process.env.TARO_ENV == 'rn') {
  156. JPush.setBadge({
  157. badge: 0,
  158. appBadge: 0
  159. })
  160. JPush.isNotificationEnabled((res) => {
  161. if (res) {
  162. const test = require('@/utils/push').default
  163. test()
  164. }
  165. })
  166. AppState.addEventListener('change', handleAppStateChange);
  167. /*
  168. if (Taro.getSystemInfoSync().platform == 'ios') {
  169. setTimeout(() => {
  170. var Jto = require('react-native').NativeModules.NativeBridge;
  171. // Jto.authNotification()
  172. Jto.getNotificationAuthStatus()
  173. }, 5000)
  174. NativeAppEventEmitter.addListener('notificationResult', (data) => {
  175. console.log(data)
  176. showAlert({
  177. title:'notification status',
  178. content:data
  179. })
  180. })
  181. }*/
  182. }
  183. }, [])
  184. useEffect(() => {
  185. getCheckData()
  186. // global.pauseIndexTimer = !user.isLogin
  187. if (user.isLogin) {
  188. uploadUserClient();
  189. checkAuthorized();
  190. //检查用户是否添加过小程序
  191. checkAddToMini();
  192. if (process.env.TARO_ENV == 'rn') {
  193. if (Taro.getSystemInfoSync().platform == 'ios') {
  194. var Jto = require('react-native').NativeModules.NativeBridge;
  195. Jto.getNotificationAuthStatus()
  196. NativeAppEventEmitter.addListener('notificationResult', (data) => {
  197. global.notification = data;
  198. uploadPermissions()
  199. })
  200. }
  201. // uploadPermissions()
  202. JPush.isNotificationEnabled((res) => {
  203. if (res) {
  204. const test = require('@/utils/push').default
  205. test()
  206. }
  207. })
  208. checkVersionUpdate()
  209. }
  210. }
  211. else {
  212. dispatch(clearNightStore());
  213. }
  214. }, [user.isLogin])
  215. useReady(async () => {
  216. const userData = await getStorage('userData');
  217. if (userData) {
  218. dispatch(getInfoSuccess(JSON.parse(userData as string)) as any);
  219. getHistory()
  220. }
  221. })
  222. async function checkVersionUpdate() {
  223. if (!user.isLogin) {
  224. return
  225. }
  226. if (process.env.TARO_ENV == 'rn') {
  227. systemVersion().then(res => {
  228. if ((res as any).result == 'UPDATE' && !showUpdate) {
  229. showUpdate = true
  230. showAlert({
  231. title: (res as any).title,
  232. content: (res as any).description,
  233. showCancel: true,
  234. confirmText: '更新',
  235. confirm: () => {
  236. Linking.openURL((res as any).download_url)
  237. }
  238. })
  239. }
  240. else if ((res as any).result == 'FORCE_UPDATE') {
  241. showAlert({
  242. title: (res as any).title,
  243. content: (res as any).description,
  244. showCancel: false,
  245. confirmText: '更新',
  246. confirm: () => {
  247. Linking.openURL((res as any).download_url)
  248. }
  249. })
  250. }
  251. })
  252. return;
  253. }
  254. const showAlert1 = await getStorage('120alert') || false;
  255. if (!showAlert1) {
  256. showAlert({
  257. title: '版本更新提示',
  258. content: '「连续纪录」新增归零倒计时提示⏳\n别让连续记录终止, 将它们一直保持下去!',
  259. showCancel: false,
  260. confirmText: '我知道了'
  261. })
  262. }
  263. Taro.setStorage({ key: '120alert', data: true })
  264. }
  265. function checkAddToMini() {
  266. if (process.env.TARO_ENV == 'weapp') {
  267. const version = Taro.getAppBaseInfo().SDKVersion
  268. if (compareVersion(version, '2.30.3') >= 0) {
  269. wx.checkIsAddedToMyMiniProgram({
  270. success: (res) => {
  271. if (!res.added) {
  272. setNeedShowAddTip(true)
  273. }
  274. },
  275. fail: (e) => {
  276. }
  277. });
  278. }
  279. }
  280. }
  281. useDidShow(() => {
  282. checkTimeZone()
  283. setCount(pre => pre + 1)
  284. //resume timer
  285. pauseTimer = false
  286. if (user.isLogin) {
  287. if (global.refreshRecent) {
  288. global.refreshRecent()
  289. }
  290. }
  291. setTimeout(() => {
  292. checkVersionUpdate();
  293. updateNotificationStatus();
  294. }, 1000)
  295. })
  296. usePageScroll((e) => {
  297. if (e.scrollTop > 70) {
  298. setShowTip(true)
  299. }
  300. else {
  301. setShowTip(false)
  302. }
  303. })
  304. useDidHide(() => {
  305. //pause timer
  306. pauseTimer = true
  307. })
  308. global.refreshIndex = () => {
  309. setCount((prevCounter) => prevCounter + 1)
  310. }
  311. const handleAppStateChange = (nextAppState) => {
  312. console.log(nextAppState)
  313. if (nextAppState != 'active') {
  314. return
  315. }
  316. checkTimeZone()
  317. updateNotificationStatus()
  318. };
  319. function updateNotificationStatus() {
  320. if (process.env.TARO_ENV == 'rn') {
  321. if (user.isLogin) {
  322. if (Taro.getSystemInfoSync().platform == 'ios') {
  323. var Jto = require('react-native').NativeModules.NativeBridge;
  324. Jto.getNotificationAuthStatus()
  325. }
  326. }
  327. JPush.setBadge({
  328. badge: 0,
  329. appBadge: 0
  330. })
  331. }
  332. }
  333. function checkTimeZone() {
  334. setCount((prevCounter) => prevCounter + 1)
  335. var timeZoneFormatted = getTimezone()
  336. Taro.getStorage({
  337. key: 'last_tz',
  338. success: function (res) {
  339. if (res.data && res.data != timeZoneFormatted) {
  340. if (global.refrehWeekly) {
  341. global.refrehWeekly()
  342. }
  343. // if (global.refreshNight){
  344. // global.refreshNight()
  345. // }
  346. // if (global.refreshDay){
  347. // global.refreshDay()
  348. // }
  349. if (global.currentStatus != 'WAIT_FOR_START') {
  350. showAlert({
  351. title: t('feature.track_time_duration.change_tz_alert.title'),
  352. content: t('feature.track_time_duration.change_tz_alert.content', { tz: timeZoneFormatted }),
  353. showCancel: false,
  354. confirmText: t('feature.track_time_duration.change_tz_alert.confirm'),
  355. })
  356. }
  357. }
  358. },
  359. complete: function () {
  360. Taro.setStorage({ key: 'last_tz', data: timeZoneFormatted })
  361. }
  362. })
  363. }
  364. function uploadUserClient() {
  365. var systemInfo = Taro.getSystemInfoSync();
  366. console.log(systemInfo)
  367. var language: any = systemInfo.language
  368. if (process.env.TARO_ENV == 'rn') {
  369. var NativeModules = require('react-native').NativeModules;
  370. if (Taro.getSystemInfoSync().platform == 'ios') {
  371. // language = NativeModules.SettingsManager.settings.AppleLocale
  372. // languageList = NativeModules.SettingsManager.settings.AppleLanguages
  373. language = {
  374. AppleLocale: NativeModules.SettingsManager.settings.AppleLocale,
  375. AppleLanguages: NativeModules.SettingsManager.settings.AppleLanguages,
  376. NSLanguages: NativeModules.SettingsManager.settings.NSLanguages
  377. }
  378. }
  379. else {
  380. language = NativeModules.I18nManager.localeIdentifier
  381. }
  382. // iOS:
  383. // var locale = NativeModules.SettingsManager.settings.AppleLocale ||
  384. // NativeModules.SettingsManager.settings.AppleLanguages[0] // "fr_FR"
  385. // showAlert({
  386. // title: 'locale',
  387. // content: JSON.stringify(NativeModules.SettingsManager.settings)
  388. // })
  389. // Android:
  390. // locale = NativeModules.I18nManager.localeIdentifier // "fr_FR"
  391. }
  392. var timeZoneFormatted = getTimezone()
  393. var timeZoneId = ''
  394. var timeZoneName = ''
  395. if (Taro.getSystemInfoSync().platform == 'ios') {
  396. timeZoneId = getTimezoneId()
  397. timeZoneName = getTimezoneName()
  398. }
  399. clientInfo({
  400. client: {
  401. client_type: process.env.TARO_ENV == 'weapp' ? 'MP' : 'APP',
  402. client_version: process.env.TARO_ENV == 'weapp' ? WX_VERSION : APP_VERSION,//Taro.getAccountInfoSync().miniProgram.version : '1.0',//'1.0'
  403. wx_version: process.env.TARO_ENV == 'weapp' ? systemInfo.version : '_'
  404. },
  405. meta: {
  406. language: language,
  407. timezone: {
  408. gmt: timeZoneFormatted,
  409. id: timeZoneId,
  410. name: timeZoneName
  411. },
  412. },
  413. device: {
  414. brand: systemInfo.brand,
  415. model: systemInfo.model,
  416. platform: systemInfo.platform,
  417. system: systemInfo.system
  418. },
  419. perm: {
  420. wifi_enabled: systemInfo.wifiEnabled,
  421. location_authorized: systemInfo.locationAuthorized,
  422. location_enabled: systemInfo.locationEnabled
  423. }
  424. })
  425. }
  426. function loadWXCache() {
  427. var showDayRing = Taro.getStorageSync('showDayRing') || false;
  428. var showNightRing = Taro.getStorageSync('showNightRing') || false;
  429. dispatch(showDay(showDayRing))
  430. dispatch(showNight(showNightRing))
  431. var gps = Taro.getStorageSync('gps')
  432. if (gps) {
  433. global.locationDetail = JSON.parse(gps)
  434. }
  435. var userData = Taro.getStorageSync('userData')
  436. if (userData) {
  437. dispatch(getInfoSuccess(JSON.parse(userData)));
  438. }
  439. }
  440. async function loadRNCache() {
  441. var showDayRing = await getStorage('showDayRing') || false;
  442. var showNightRing = await getStorage('showNightRing') || false;
  443. dispatch(showDay(showDayRing))
  444. dispatch(showNight(showNightRing))
  445. var gps = await getStorage('gps')
  446. if (gps) {
  447. global.locationDetail = JSON.parse(gps)
  448. }
  449. var userData = await getStorage('userData')
  450. console.log(userData)
  451. if (userData) {
  452. dispatch(getInfoSuccess(JSON.parse(userData)));
  453. }
  454. // //测试直接登录
  455. // else {
  456. // userData = '{"metrics_times":0,"ongoing":false,"id":"fe6641e66a0e411937a52511e19851cd","mobile_bind":false,"mobile":"","avatar":"https://api.fast.dev.liveplus.fun/api/avatars/fast_441b5a21.svg","nickname":"fast_441b5a21","type":"GENERAL","lv":1,"invite_code":"LVQ5","input_invite_code":true,"reg_time":1712838856000,"login_bind":{"wx":false,"wx_mp":false,"wx_pub":false,"qq":false,"weibo":false},"test_user":true,"manager_user":false,"web_user":false,"rjv_balance":0,"day_level":1,"scenario_select_count":77,"push_enabled":false,"is_new_user":true,"lang":"en","timezone":{},"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJhY2NvdW50Iiwic3ViIjoiZmU2NjQxZTY2YTBlNDExOTM3YTUyNTExZTE5ODUxY2QiLCJpc3MiOiJmYXN0Iiwibmlja25hbWUiOiJmYXN0XzQ0MWI1YTIxIiwidHlwIjoiQmVhcmVyIiwic2Vzc2lvbl9zdGF0ZSI6IjA0NTcxOGYzN2Y5NTYzYjcxMTNkMWZhODI5NmE2MjQ2IiwiZXhwIjoxNzQ2Njg4NTYxLCJpYXQiOjE3MTUxNTI1NjF9.x1CguOILCTjT8lKcEdSEeuS9ACc5QK2G4Rxmcz9OMLQ","need_improve":false}'
  457. // dispatch(getInfoSuccess(JSON.parse(userData)));
  458. // }
  459. }
  460. function getCheckData() {
  461. Promise.all([getClocks(), getPlans()]).then((list) => {
  462. setErrorPage(false)
  463. setCheckData(list)
  464. if (needScroll) {
  465. needScroll = false
  466. if (process.env.TARO_ENV == 'weapp') {
  467. setTimeout(() => {
  468. Taro.createSelectorQuery().select('#latest').boundingClientRect((rect) => {
  469. Taro.pageScrollTo({
  470. scrollTop: (rect as any).top,
  471. duration: 150
  472. })
  473. }).exec()
  474. }, 100)
  475. }
  476. else {
  477. // debugger
  478. // (scrollRef.current as any).scrollTo({ y: rpxToPx(400), animated: true })
  479. }
  480. }
  481. setLoaded(true)
  482. }).catch((e) => {
  483. setErrorPage(true)
  484. var list = JSON.parse(defaultValue)
  485. setCheckData(list)
  486. needScroll = false
  487. setLoaded(true)
  488. })
  489. getHistory()
  490. }
  491. function setCheckData(list: any) {
  492. setHomeData(list[0])
  493. global.homeData = list[0]
  494. global.currentStatus = list[0].current_record.status;
  495. var array = list[1].scenarios
  496. var schedule = null
  497. array.map(item => {
  498. if (item.name == 'FAST_SLEEP') {
  499. schedule = item.schedule;
  500. }
  501. })
  502. if (user.isLogin) {
  503. dispatch(updateScenario(list[0].current_record))
  504. dispatch(setConfigs(list[0].time_input_schema));
  505. dispatch(setScenario(list[0].scenario));
  506. global.scenario = list[0].scenario.name;
  507. }
  508. dispatch(setCurrentRecord(list[0].current_record))
  509. dispatch(setSchedule(schedule))
  510. // setLoaded(true)
  511. }
  512. function getHistory() {
  513. if (user.isLogin)
  514. getClockRecords({
  515. page: 1,
  516. limit: 1,
  517. // part_completed: true
  518. completed: true
  519. }).then(res => {
  520. setRecords((res as any).data)
  521. })
  522. }
  523. global.indexPageRefresh = () => {
  524. getCheckData()
  525. if (global.swiperDayNightRefresh) {
  526. global.swiperDayNightRefresh()
  527. }
  528. }
  529. global.showIndexModal = (isShow: boolean, detail: any, debugNode?: any) => {
  530. global.showModal = isShow
  531. setDebugInfo(debugNode)
  532. setShowModal(isShow)
  533. setModalDetail(detail)
  534. }
  535. global.showIndexModal2 = (isShow: boolean, detail: any) => {
  536. setDebugInfo(null)
  537. global.showModal = isShow
  538. setShowModal2(isShow)
  539. setModalDetail2(detail)
  540. }
  541. global.changeTargetDuration = (duration: number, isFast: boolean) => {
  542. var obj = JSON.parse(JSON.stringify(homeData))
  543. var record = obj.current_record
  544. if (isFast) {
  545. record.fast.target_end_time = record.fast.target_start_time + duration * 60 * 1000
  546. }
  547. else {
  548. record.sleep.target_end_time = record.sleep.target_start_time + duration * 60 * 1000
  549. }
  550. setHomeData(obj)
  551. }
  552. global.updateFastSleepData = (data: any, schedule?: any) => {
  553. if (data.id == (homeData as any).current_record.id) {
  554. var obj = JSON.parse(JSON.stringify(homeData))
  555. obj.current_record = data
  556. if (schedule) {
  557. obj.scenario.schedule = schedule
  558. }
  559. setHomeData(obj)
  560. }
  561. switch (data.scenario) {
  562. case 'FAST':
  563. if (data.status == 'WAIT_FOR_START') {
  564. dispatch(changeFastDuration(data.fast.target_end_time - data.fast.target_start_time))
  565. }
  566. break;
  567. case 'SLEEP':
  568. if (data.status == 'WAIT_FOR_START') {
  569. dispatch(changeSleepDuration(data.sleep.target_end_time - data.sleep.target_start_time))
  570. }
  571. break;
  572. case 'FAST_SLEEP':
  573. if (data.status == 'WAIT_FOR_START') {
  574. dispatch(changeFastDuration(data.fast.target_end_time - data.fast.target_start_time))
  575. }
  576. else if (data.status == 'ONGOING1') {
  577. dispatch(changeSleepDuration(data.sleep.target_end_time - data.sleep.target_start_time))
  578. }
  579. break;
  580. }
  581. }
  582. global.popScheduleAlert = (scenario, startTime) => {
  583. if (process.env.TARO_ENV == 'weapp') {
  584. if (permission.wxPubFollow) {
  585. showAlert({
  586. title: t('feature.track_time_duration.reminders.schedule_title'),
  587. content: scenario.name == 'FAST' ?
  588. t('feature.track_time_duration.reminders.enable_schedule_fast_content', { time: startTime }) :
  589. t('feature.track_time_duration.reminders.enable_schedule_sleep_content', { time: startTime }),
  590. showCancel: false,
  591. confirmText: t('feature.track_time_duration.reminders.ok')
  592. })
  593. }
  594. else {
  595. showAlert({
  596. title: t('feature.track_time_duration.reminders.schedule_title'),
  597. content: scenario.name == 'FAST' ?
  598. t('feature.track_time_duration.reminders.schedule_fast_content', { time: startTime }) :
  599. t('feature.track_time_duration.reminders.schedule_sleep_content', { time: startTime }),
  600. cancelText: t('feature.track_time_duration.reminders.later'),
  601. confirmText: t('feature.track_time_duration.reminders.open'),
  602. showCancel: true,
  603. confirm: () => {
  604. followWxPub()
  605. }
  606. })
  607. }
  608. }
  609. else {
  610. JPush.isNotificationEnabled((res) => {
  611. if (res) {
  612. showAlert({
  613. title: t('feature.track_time_duration.reminders.schedule_title'),
  614. content: scenario.name == 'FAST' ?
  615. t('feature.track_time_duration.reminders.enable_schedule_fast_content', { time: startTime }) :
  616. t('feature.track_time_duration.reminders.enable_schedule_sleep_content', { time: startTime }),
  617. showCancel: false,
  618. confirmText: t('feature.track_time_duration.reminders.ok')
  619. })
  620. }
  621. else {
  622. showAlert({
  623. title: t('feature.track_time_duration.reminders.schedule_title'),
  624. content: scenario.name == 'FAST' ?
  625. t('feature.track_time_duration.reminders.schedule_fast_content', { time: startTime }) :
  626. t('feature.track_time_duration.reminders.schedule_sleep_content', { time: startTime }),
  627. cancelText: t('feature.track_time_duration.reminders.later'),
  628. confirmText: t('feature.track_time_duration.reminders.open'),
  629. showCancel: true,
  630. confirm: () => {
  631. checkNotification()
  632. // Linking.openURL('app-settings:notifications')
  633. }
  634. })
  635. }
  636. })
  637. }
  638. }
  639. global.popMixScheduleAlert = (time1, time2) => {
  640. if (process.env.TARO_ENV == 'weapp') {
  641. if (permission.wxPubFollow) {
  642. showAlert({
  643. title: t('feature.track_time_duration.reminders.schedule_title'),
  644. content: t('feature.track_time_duration.reminders.enable_schedule_mix_content', { time1: time1, time2: time2 }),
  645. showCancel: false,
  646. confirmText: t('feature.track_time_duration.reminders.ok')
  647. })
  648. }
  649. else {
  650. showAlert({
  651. title: t('feature.track_time_duration.reminders.schedule_title'),
  652. content:
  653. t('feature.track_time_duration.reminders.schedule_mix_content'),
  654. cancelText: t('feature.track_time_duration.reminders.later'),
  655. confirmText: t('feature.track_time_duration.reminders.open'),
  656. showCancel: true,
  657. confirm: () => {
  658. followWxPub()
  659. }
  660. })
  661. }
  662. }
  663. else {
  664. JPush.isNotificationEnabled((res) => {
  665. if (res) {
  666. showAlert({
  667. title: t('feature.track_time_duration.reminders.schedule_title'),
  668. content: t('feature.track_time_duration.reminders.enable_schedule_mix_content', { time1: time1, time2: time2 }),
  669. showCancel: false,
  670. confirmText: t('feature.track_time_duration.reminders.ok')
  671. })
  672. }
  673. else {
  674. showAlert({
  675. title: t('feature.track_time_duration.reminders.schedule_title'),
  676. content:
  677. t('feature.track_time_duration.reminders.schedule_mix_content'),
  678. cancelText: t('feature.track_time_duration.reminders.later'),
  679. confirmText: t('feature.track_time_duration.reminders.open'),
  680. showCancel: true,
  681. confirm: () => {
  682. checkNotification()
  683. // Linking.openURL('app-settings:notifications')
  684. }
  685. })
  686. }
  687. })
  688. }
  689. }
  690. function followWxPub() {
  691. const resource = common.resources.filter((item: any) => {
  692. return item.code == 'follow_wx_pub'
  693. })
  694. jumpPage('/pages/common/H5?title=fast16cc 关注服务号&url=' + resource[0].url)
  695. }
  696. function modalContent() {
  697. if (showModal || showModal2) {
  698. return <Modal
  699. testInfo={debugInfo}
  700. dismiss={() => {
  701. setDebugInfo(null)
  702. setShowModal(false);
  703. setShowModal2(false);
  704. global.pauseIndexTimer = false
  705. }}
  706. confirm={() => { }}>
  707. {
  708. showModal ? modalDetail : modalDetail2
  709. }
  710. </Modal>
  711. }
  712. return <View />
  713. }
  714. async function getStorage(key: string) {
  715. try {
  716. const res = await Taro.getStorage({ key });
  717. return res.data;
  718. } catch {
  719. return '';
  720. }
  721. }
  722. function more() {
  723. jumpPage('/pages/common/RecordsHistory?type=time&title=time', 'RecordsHistory', navigation, {
  724. type: 'time',
  725. title: 'time'
  726. })
  727. }
  728. function tapLogin() {
  729. if (!user.isLogin) {
  730. jumpPage('/pages/account/ChooseAuth', 'ChooseAuth', navigation)
  731. }
  732. }
  733. function headerView() {
  734. return <ClockHeader homeData={homeData} />
  735. }
  736. global.scrollToLatest = () => {
  737. needScroll = true;
  738. }
  739. var timestamp = new Date().getTime()
  740. function render() {
  741. if (!loaded) {
  742. return <Layout type={TemplateType.customHeader} header={headerView()} title={t('page.clock.title')} titleShowStyle={NaviBarTitleShowType.scrollToShow}>
  743. <View style={{ width: rpxToPx(750), height: rpxToPx(900), display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
  744. <AtActivityIndicator size={40} color="#fff" />
  745. {
  746. process.env.TARO_ENV == 'weapp' && <Tabbar index={0} />
  747. }
  748. </View>
  749. </Layout>
  750. }
  751. return <Layout type={TemplateType.customHeader} header={headerView()} title={t('page.clock.title')} titleShowStyle={NaviBarTitleShowType.scrollToShow}>
  752. <View className="index_container">
  753. {
  754. needShowAddTip && showTip && <Tooltip title="添加到我的小程序" closeTip={() => { setNeedShowAddTip(false) }} />
  755. }
  756. <Text className="count">{count}</Text>
  757. <Box>
  758. <View>
  759. <IndexItem type="FAST_SLEEP" data={homeData} time={timestamp} showStage={false} />
  760. {
  761. user.isLogin ? <IndexConsole record={homeData} /> : <StageSelector />
  762. }
  763. </View>
  764. </Box>
  765. {
  766. process.env.TARO_ENV == 'weapp' && <DayNightCard isNight={true} count={count} />
  767. }
  768. {
  769. process.env.TARO_ENV == 'rn' && <DayNightSwiper count={count} />
  770. }
  771. {
  772. process.env.TARO_ENV == 'rn' && <View style={{ height: rpxToPx(20) }} />
  773. }
  774. {user.isLogin && <AllRings data={homeData} time={timestamp} />}
  775. {
  776. user.isLogin && records.length > 0 && <View style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between', marginTop: rpxToPx(40), }}>
  777. {
  778. <Text className="discovery1" style={{ marginBottom: 0 }}>{t('feature.track_time_duration.record_fast_sleep.header.latest_record')}</Text>
  779. }
  780. {
  781. process.env.TARO_ENV == 'weapp' && <Text className="fast_sleep_more index_more" onClick={more}>{t('feature.track_time_duration.record_fast_sleep.header.btn_show_all')}</Text>
  782. }
  783. {
  784. process.env.TARO_ENV == 'rn' && <View onClick={more}>
  785. <GradientText style={{ fontSize: rpxToPx(32), fontWeight: 'bold', marginRight: rpxToPx(46) }}>{t('feature.track_time_duration.record_fast_sleep.header.btn_show_all')}</GradientText>
  786. </View>
  787. }
  788. </View>
  789. }
  790. {
  791. user.isLogin && records.length > 0 && <View id="latest" className="fast_sleep_item_bg">
  792. <RecordFastSleep data={records[0]} type='record' index={-20000} />
  793. </View>
  794. }
  795. {
  796. loaded && !user.isLogin && <View style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', marginTop: rpxToPx(36) }}>
  797. <ChooseScenarioBtn title={t('feature.auth.login.login_now')} background={ColorType.fast} onClick={tapLogin} />
  798. </View>
  799. }
  800. {
  801. user.isLogin && !showErrorPage && <View style={{ marginTop: rpxToPx(60), display: 'flex', flexDirection: 'column' }}>
  802. <Text className="discovery1" >{t('feature.track_time_duration.weekly.title')}</Text>
  803. <WeekCalendar />
  804. </View>
  805. }
  806. {
  807. user.isLogin && <Streaks count={count} />
  808. }
  809. {
  810. process.env.TARO_ENV == 'weapp' && <View style={{ height: 100 }} />
  811. }
  812. {
  813. modalContent()
  814. }
  815. {
  816. homeData && <SegmentPop data={homeData} />
  817. }
  818. {
  819. homeData && <DurationPicker record={(homeData as any).current_record} />
  820. }
  821. <Tabbar index={0} />
  822. </View>
  823. </Layout>
  824. }
  825. // if (process.env.TARO_ENV == 'rn') {
  826. // return <ScrollView>
  827. // {
  828. // render()
  829. // }
  830. // </ScrollView>
  831. // }
  832. return render()
  833. }