SetGoal.tsx 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. import { View, Text, Image } from "@tarojs/components";
  2. import './ChooseScenario.scss'
  3. import { useRouter } from "@tarojs/taro";
  4. import { rpxToPx } from "@/utils/tools";
  5. import { ColorType } from "@/context/themes/color";
  6. import Footer from "@/components/layout/Footer";
  7. import { ChooseScenarioBtn, SetScheduleBtn } from "@/features/common/SpecBtns";
  8. import { useDispatch, useSelector } from "react-redux";
  9. import { useEffect, useState } from "react";
  10. import Modal from "@/components/layout/Modal.weapp";
  11. import TimePicker from "@/features/common/TimePicker";
  12. import { useTranslation } from "react-i18next";
  13. import { updateFast, updateSleep } from "@/store/set_target";
  14. import { setPlan } from "@/services/trackTimeDuration";
  15. import showAlert from "@/components/basic/Alert";
  16. import Taro from "@tarojs/taro";
  17. import { getLocalPush } from "@/features/trackTimeDuration/actions/TrackTimeActions";
  18. let OneSignal
  19. let NativeAppEventEmitter
  20. let Jto
  21. let uploadPermissions,checkNotification
  22. if (process.env.TARO_ENV == 'rn') {
  23. OneSignal = require('react-native-onesignal').OneSignal
  24. NativeAppEventEmitter = require('react-native').NativeAppEventEmitter
  25. Jto = require('react-native').NativeModules.NativeBridge;
  26. uploadPermissions = require('@/utils/native_permission_check').uploadPermissions;
  27. checkNotification = require('@/utils/native_permission_check').checkNotification;
  28. }
  29. export default function SetGoal() {
  30. let router
  31. var navigation: any = null
  32. if (process.env.TARO_ENV === 'rn') {
  33. var useNavigation = require("@react-navigation/native").useNavigation
  34. navigation = useNavigation()
  35. const useRoute = require("@react-navigation/native").useRoute
  36. router = useRoute()
  37. }
  38. else {
  39. router = useRouter()
  40. }
  41. const isSelf = router.params.isSelf
  42. const target = useSelector((state: any) => state.target);
  43. const [fastDuration, setFastDuration] = useState<any>(0)
  44. const [sleepDuration, setSleepDuration] = useState<any>(0)
  45. const [fastTarget, setFastTarget] = useState(target.fast.schedule.fast)
  46. const [sleepTarget, setSleepTarget] = useState(target.sleep.schedule.sleep)
  47. const [showTimePicker, setShowTimePicker] = useState(false)
  48. const [isFast, setIsFast] = useState(true)
  49. const [isStart, setIsStart] = useState(true)
  50. const [authStatus, setAuthStatus] = useState('')
  51. const { t } = useTranslation()
  52. const dispatch = useDispatch();
  53. useEffect(() => {
  54. if (process.env.TARO_ENV == 'rn') {
  55. rnNotification()
  56. }
  57. }, [])
  58. useEffect(() => {
  59. getFastDuration()
  60. getSleepDuration()
  61. }, [target.fast, target.sleep])
  62. function rnNotification() {
  63. if (Taro.getSystemInfoSync().platform == 'ios') {
  64. Jto.getNotificationAuthStatus()
  65. NativeAppEventEmitter.addListener('notificationResult', (data) => {
  66. setAuthStatus(data)
  67. global.notification = data
  68. uploadPermissions()
  69. })
  70. NativeAppEventEmitter.addListener('operateNotificationResult', (data) => {
  71. getLocalPush()
  72. global.notification = data
  73. navigation.popToTop()
  74. uploadPermissions()
  75. })
  76. }
  77. else {
  78. OneSignal.Notifications.canRequestPermission().then((status) => {
  79. if (status) {
  80. OneSignal.Notifications.getPermissionAsync().then((res) => {
  81. if (res) {
  82. global.notification = 'authorized'
  83. uploadPermissions()
  84. }
  85. else {
  86. global.notification = 'denied'
  87. uploadPermissions()
  88. }
  89. })
  90. }
  91. else {
  92. global.notification = 'not_determined'
  93. uploadPermissions()
  94. }
  95. })
  96. }
  97. }
  98. function getFastDuration() {
  99. var obj = target.fast.schedule.fast
  100. var duration = obj.end_time.split(':')[0] * 60 + obj.end_time.split(':')[1] * 1 - (obj.start_time.split(':')[0] * 60 + obj.start_time.split(':')[1] * 1)
  101. if (duration <= 0) {
  102. duration += 24 * 60
  103. }
  104. var hours = Math.floor(duration / 60)
  105. var minutes = duration % 60
  106. var str = hours + (global.language=='en'?' hours':'小时')// + minutes + ' minutes'
  107. if (minutes > 0) {
  108. str += ` ${minutes}`+(global.language=='en'?' minutes':'分钟')
  109. }
  110. setFastDuration(str)
  111. }
  112. function getFastDurationMinutes() {
  113. var obj = target.fast.schedule.fast
  114. var duration = obj.end_time.split(':')[0] * 60 + obj.end_time.split(':')[1] * 1 - (obj.start_time.split(':')[0] * 60 + obj.start_time.split(':')[1] * 1)
  115. if (duration <= 0) {
  116. duration += 24 * 60
  117. }
  118. return duration
  119. }
  120. function getSleepDuration() {
  121. var obj = target.sleep.schedule.sleep
  122. var duration = obj.end_time.split(':')[0] * 60 + obj.end_time.split(':')[1] * 1 - (obj.start_time.split(':')[0] * 60 + obj.start_time.split(':')[1] * 1)
  123. if (duration <= 0) {
  124. duration += 24 * 60
  125. }
  126. var hours = Math.floor(duration / 60)
  127. var minutes = duration % 60
  128. var str = hours + (global.language=='en'?' hours':'小时')// + minutes + ' minutes'
  129. if (minutes > 0) {
  130. str += ` ${minutes}`+(global.language=='en'?' minutes':'分钟')
  131. }
  132. setSleepDuration(str)
  133. }
  134. function getSleepDurationMinutes() {
  135. var obj = target.sleep.schedule.sleep
  136. var duration = obj.end_time.split(':')[0] * 60 + obj.end_time.split(':')[1] * 1 - (obj.start_time.split(':')[0] * 60 + obj.start_time.split(':')[1] * 1)
  137. if (duration <= 0) {
  138. duration += 24 * 60
  139. }
  140. return duration
  141. }
  142. function hidePicker() {
  143. setShowTimePicker(false)
  144. }
  145. function modalContent() {
  146. return <Modal
  147. testInfo={null}
  148. dismiss={() => {
  149. hidePicker()
  150. // setShowTimeoutPicker(false)
  151. }}
  152. confirm={() => { }}>
  153. {
  154. timePickerContent()
  155. }
  156. </Modal>
  157. }
  158. function pickerTitle() {
  159. if (isFast) {
  160. if (isStart) {
  161. return t('feature.track_time_duration.dial.picker_fast_schedule_start_time');
  162. }
  163. return t('feature.track_time_duration.dial.picker_fast_schedule_end_time');
  164. }
  165. else {
  166. if (isStart) {
  167. return t('feature.track_time_duration.dial.picker_sleep_schedule_start_time');
  168. }
  169. return t('feature.track_time_duration.dial.picker_sleep_schedule_end_time');
  170. }
  171. }
  172. function pickerConfirm(e) {
  173. hidePicker()
  174. if (isFast) {
  175. var fast = JSON.parse(JSON.stringify(target.fast))
  176. if (isStart) {
  177. fast.schedule.fast.start_time = e
  178. }
  179. else {
  180. fast.schedule.fast.end_time = e
  181. }
  182. dispatch(updateFast({ fast: fast }))
  183. setFastTarget(fast.schedule.fast)
  184. }
  185. else {
  186. var sleep = JSON.parse(JSON.stringify(target.sleep))
  187. if (isStart) {
  188. sleep.schedule.sleep.start_time = e
  189. }
  190. else {
  191. sleep.schedule.sleep.end_time = e
  192. }
  193. dispatch(updateSleep({ sleep: sleep }))
  194. setSleepTarget(sleep.schedule.sleep)
  195. }
  196. getFastDuration()
  197. getSleepDuration()
  198. }
  199. function timePickerContent() {
  200. var time = ''
  201. if (isFast) {
  202. if (isStart) {
  203. time = fastTarget.start_time
  204. }
  205. else {
  206. time = fastTarget.end_time
  207. }
  208. }
  209. else {
  210. if (isStart) {
  211. time = sleepTarget.start_time
  212. }
  213. else {
  214. time = sleepTarget.end_time
  215. }
  216. }
  217. return <TimePicker time={time}
  218. color={isFast ? ColorType.fast : ColorType.sleep}
  219. title={pickerTitle()}
  220. confirm={pickerConfirm}
  221. cancel={hidePicker} />
  222. }
  223. function confirm() {
  224. debugger
  225. var params: any = {
  226. method: parseInt(router.params.isSelf + '') == 1 ? 'USER_SET' : 'SUGGEST',
  227. schedule: {
  228. fast: {
  229. start_time: fastTarget.start_time,
  230. end_time: fastTarget.end_time,
  231. duration: {
  232. input_value: getFastDurationMinutes()//target.fast.schedule.fast.duration.init_value,
  233. }
  234. },
  235. }
  236. }
  237. if (target.isMixed) {
  238. params.scenario = 'FAST_SLEEP'
  239. params.schedule.sleep = {
  240. start_time: sleepTarget.start_time,
  241. end_time: sleepTarget.end_time,
  242. duration: {
  243. input_value: getSleepDurationMinutes()
  244. },
  245. latency: parseInt(router.params.isSelf + '') == 1 ? null : {
  246. input_value: target.sleep.schedule.sleep.latency.init_value,
  247. },
  248. cycle: parseInt(router.params.isSelf + '') == 1 ? null : {
  249. num: {
  250. input_value: target.sleep.schedule.sleep.cycle.num.init_value,
  251. }
  252. }
  253. }
  254. }
  255. else {
  256. params.scenario = 'FAST'
  257. }
  258. if (router.params.upgrade) {
  259. params.trigger_event = router.params.trigger_event
  260. }
  261. else {
  262. params.trigger_event = router.params.trigger_event ? router.params.trigger_event : 'SET'
  263. }
  264. setPlan(params).then(res => {
  265. if (global.checkData) {
  266. global.checkData()
  267. }
  268. if (global.indexPageRefresh) {
  269. global.indexPageRefresh()
  270. }
  271. if (process.env.TARO_ENV === 'rn') {
  272. popRNAlert()
  273. }
  274. else {
  275. popAlert()
  276. }
  277. // popAlert()
  278. }).catch(e => {
  279. })
  280. }
  281. function popAlert() {
  282. global.chooseMixed()
  283. if (process.env.TARO_ENV === 'weapp') {
  284. Taro.navigateBack({ delta: 6 }).then(res => {
  285. })
  286. }
  287. else {
  288. navigation.popToTop()
  289. }
  290. if (target.isMixed) {
  291. setTimeout(() => {
  292. global.popMixScheduleAlert(fastTarget.start_time, sleepTarget.start_time)
  293. }, 800)
  294. }
  295. else {
  296. setTimeout(() => {
  297. global.popScheduleAlert({
  298. name: 'FAST'
  299. }, fastTarget.start_time)
  300. }, 800)
  301. }
  302. }
  303. function popRNAlert(){
  304. debugger
  305. if (target.isMixed) {
  306. popMixScheduleAlert(fastTarget.start_time, sleepTarget.start_time)
  307. }
  308. else {
  309. popScheduleAlert({
  310. name: 'FAST'
  311. }, fastTarget.start_time)
  312. }
  313. }
  314. function popScheduleAlert(scenario, startTime) {
  315. if (process.env.TARO_ENV === 'rn') {
  316. const JPush = require('jpush-react-native').default;
  317. JPush.isNotificationEnabled((res) => {
  318. if (res) {
  319. getLocalPush();
  320. showAlert({
  321. title: t('feature.track_time_duration.reminders.schedule_title'),
  322. content: scenario.name == 'FAST' ?
  323. t('feature.track_time_duration.reminders.enable_schedule_fast_content', { time: startTime }) :
  324. t('feature.track_time_duration.reminders.enable_schedule_sleep_content', { time: startTime }),
  325. showCancel: false,
  326. confirmText: t('feature.track_time_duration.reminders.ok'),
  327. cancel: () => {
  328. navigation.popToTop()
  329. },
  330. confirm: () => {
  331. navigation.popToTop()
  332. },
  333. })
  334. }
  335. else {
  336. showAlert({
  337. title: t('feature.track_time_duration.reminders.schedule_title'),
  338. content: scenario.name == 'FAST' ?
  339. t('feature.track_time_duration.reminders.schedule_fast_content', { time: startTime }) :
  340. t('feature.track_time_duration.reminders.schedule_sleep_content', { time: startTime }),
  341. cancelText: t('feature.track_time_duration.reminders.later'),
  342. confirmText: t('feature.track_time_duration.reminders.open'),
  343. showCancel: true,
  344. cancel: () => {
  345. navigation.popToTop()
  346. },
  347. confirm: () => {
  348. if (authStatus != 'not_determined') {
  349. navigation.popToTop()
  350. }
  351. checkNotification()
  352. // Linking.openURL('app-settings:notifications')
  353. }
  354. })
  355. }
  356. })
  357. }
  358. }
  359. function popMixScheduleAlert(time1, time2) {
  360. console.log(time1, time2)
  361. if (process.env.TARO_ENV === 'rn') {
  362. const JPush = require('jpush-react-native').default;
  363. const checkNotification = require('@/utils/native_permission_check').checkNotification;
  364. JPush.isNotificationEnabled((res) => {
  365. if (res) {
  366. getLocalPush();
  367. showAlert({
  368. title: t('feature.track_time_duration.reminders.schedule_title'),
  369. content: t('feature.track_time_duration.reminders.enable_schedule_mix_content', { time1: time1, time2: time2 }),
  370. showCancel: false,
  371. confirmText: t('feature.track_time_duration.reminders.ok'),
  372. cancel: () => {
  373. navigation.popToTop()
  374. },
  375. confirm: () => {
  376. navigation.popToTop()
  377. },
  378. })
  379. }
  380. else {
  381. showAlert({
  382. title: t('feature.track_time_duration.reminders.schedule_title'),
  383. content:
  384. t('feature.track_time_duration.reminders.schedule_mix_content'),
  385. cancelText: t('feature.track_time_duration.reminders.later'),
  386. confirmText: t('feature.track_time_duration.reminders.open'),
  387. showCancel: true,
  388. cancel: () => {
  389. navigation.popToTop()
  390. },
  391. confirm: () => {
  392. if (authStatus != 'not_determined') {
  393. navigation.popToTop()
  394. }
  395. checkNotification()
  396. // Linking.openURL('app-settings:notifications')
  397. }
  398. })
  399. }
  400. })
  401. }
  402. }
  403. function isNextDay(isFast: boolean, isStart: boolean) {
  404. var time = fastTarget.start_time.split(':')[0] * 60 + fastTarget.start_time.split(':')[1] * 1
  405. if (isFast) {
  406. var time2 = fastTarget.end_time.split(':')[0] * 60 + fastTarget.end_time.split(':')[1] * 1
  407. return time2 <= time
  408. }
  409. else {
  410. if (isStart) {
  411. time2 = sleepTarget.start_time.split(':')[0] * 60 + sleepTarget.start_time.split(':')[1] * 1
  412. return time2 <= time
  413. }
  414. else {
  415. time2 = sleepTarget.end_time.split(':')[0] * 60 + sleepTarget.end_time.split(':')[1] * 1
  416. return time2 <= time
  417. }
  418. }
  419. }
  420. return <View style={{ display: 'flex', flexDirection: 'column', flex: 1 }}>
  421. <Text className="target_title">{isSelf ? t('feature.set_goal.set_action_plan') : t('feature.set_goal.almost_done')}</Text>
  422. {
  423. !isSelf && <Text className="target_desc">{t('feature.set_goal.header')}</Text>
  424. }
  425. <View style={{ color: '#fff' }}>
  426. <View className="cell_bg">
  427. <View className="cell_full" style={{
  428. // marginLeft: rpxToPx(46),
  429. // marginRight: rpxToPx(46),
  430. // paddingLeft: rpxToPx(40),
  431. // paddingRight: rpxToPx(40),
  432. margin: 0,
  433. // backgroundColor:'red'
  434. }} onClick={() => { }}>
  435. <Text className="cell_title">{t('feature.set_goal.fast')}</Text>
  436. <Text className="cell_value" style={{ color: ColorType.fast }}>{fastDuration}</Text>
  437. </View>
  438. {
  439. target.isMixed && <View className="cell_full" style={{
  440. marginLeft: 0,
  441. marginRight: 0,
  442. paddingLeft: 0,
  443. paddingRight: 0
  444. }} onClick={() => { }}>
  445. <Text className="cell_title">{t('feature.set_goal.sleep')}</Text>
  446. <Text className="cell_value" style={{ color: ColorType.sleep }}>{sleepDuration}</Text>
  447. </View>
  448. }
  449. </View>
  450. <View style={{ height: rpxToPx(20) }} />
  451. <View className="cell_bg">
  452. <View className="cell_top" style={{
  453. marginLeft: 0,
  454. marginRight: 0,
  455. paddingLeft: 0,
  456. paddingRight: 0
  457. }} onClick={() => {
  458. setIsFast(true)
  459. setIsStart(true)
  460. setShowTimePicker(true)
  461. }}>
  462. <Text className="cell_title">{t('feature.set_goal.start_fasting')}</Text>
  463. <Text className="cell_value" style={{ color: ColorType.fast }}>{fastTarget.start_time}</Text>
  464. <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />
  465. <View className="cell_line" style={{ height: 1 }} />
  466. </View>
  467. {
  468. target.isMixed && <View className="cell_top" style={{
  469. marginLeft: 0,
  470. marginRight: 0,
  471. paddingLeft: 0,
  472. paddingRight: 0
  473. }} onClick={() => {
  474. setIsFast(false)
  475. setIsStart(true)
  476. setShowTimePicker(true)
  477. }}>
  478. <Text className="cell_title">{t('feature.set_goal.go_to_bed')}</Text>
  479. <Text className="cell_value" style={{ color: ColorType.sleep }}>{isNextDay(false, true) ? t('feature.set_goal.next_day') : ' '}{sleepTarget.start_time}</Text>
  480. <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />
  481. <View className="cell_line" style={{ height: 1 }} />
  482. </View>
  483. }
  484. {
  485. target.isMixed && <View className="cell_bottom" style={{
  486. marginLeft: 0,
  487. marginRight: 0,
  488. paddingLeft: 0,
  489. paddingRight: 0
  490. }} onClick={() => {
  491. setIsFast(false)
  492. setIsStart(false)
  493. setShowTimePicker(true)
  494. }}>
  495. <Text className="cell_title">{t('feature.set_goal.wake_up')}</Text>
  496. <Text className="cell_value" style={{ color: ColorType.sleep }}>{isNextDay(false, false) ? t('feature.set_goal.next_day') : ' '}{sleepTarget.end_time}</Text>
  497. <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />
  498. </View>
  499. }
  500. <View className="cell_bottom" style={{
  501. marginLeft: 0,
  502. marginRight: 0,
  503. paddingLeft: 0,
  504. paddingRight: 0
  505. }} onClick={() => {
  506. setIsFast(true)
  507. setIsStart(false)
  508. setShowTimePicker(true)
  509. }}>
  510. <Text className="cell_title">{t('feature.set_goal.end_fasting')}</Text>
  511. <Text className="cell_value" style={{ color: ColorType.fast }}>{isNextDay(true, false) ? t('feature.set_goal.next_day') : ' '}{fastTarget.end_time}</Text>
  512. <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />
  513. </View>
  514. </View>
  515. <Text className="cell_footer">{t('feature.set_goal.footer')}</Text>
  516. </View>
  517. <View style={{ flex: 1 }} />
  518. <Footer>
  519. <ChooseScenarioBtn
  520. onClick={confirm}
  521. title={t('feature.set_goal.done')}
  522. background={ColorType.fast}
  523. />
  524. </Footer>
  525. {
  526. showTimePicker && modalContent()
  527. }
  528. {
  529. process.env.TARO_ENV == 'rn' && <View style={{ marginBottom: 40 }} />
  530. }
  531. </View>
  532. }