Suggest.tsx 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716
  1. import { ColorType } from "@/context/themes/color";
  2. import { ChooseScenarioBtn } from "@/features/common/SpecBtns";
  3. import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
  4. import { View, Text, Picker, ScrollView } from "@tarojs/components";
  5. import { useDidShow, useRouter } from "@tarojs/taro";
  6. import { useEffect, useRef, useState } from "react";
  7. import './ChooseScenario.scss';
  8. import PickerViews from "@/components/input/PickerViews";
  9. import { useDispatch, useSelector } from "react-redux";
  10. import { rpxToPx } from "@/utils/tools";
  11. import { updateFast, updateSleep, updateStep } from "@/store/set_target";
  12. import { TimeFormatter } from "@/utils/time_format";
  13. import Footer from "@/components/layout/Footer";
  14. import { IconCheck } from "@/components/basic/Icons";
  15. import Rings2, { BgRing, RingCommon, TargetRing } from '@/features/trackTimeDuration/components/Rings';
  16. import { useTranslation } from "react-i18next";
  17. import Taro from "@tarojs/taro";
  18. let ScrollViewRN
  19. if (process.env.TARO_ENV === 'rn') {
  20. ScrollViewRN = require('react-native').ScrollView
  21. }
  22. export default function Suggest() {
  23. let router: any = null
  24. var navigation: any = null
  25. if (process.env.TARO_ENV === 'rn') {
  26. var useNavigation = require("@react-navigation/native").useNavigation
  27. navigation = useNavigation()
  28. const useRoute = require("@react-navigation/native").useRoute
  29. router = useRoute()
  30. }
  31. else {
  32. router = useRouter()
  33. }
  34. const common = useSelector((state: any) => state.common);
  35. const target = useSelector((state: any) => state.target);
  36. const [pageStep] = useState(target.step);
  37. const dispatch = useDispatch();
  38. const [suggestIndex, setSuggestIndex] = useState(-1)
  39. const [suggestItems, setSuggestItem] = useState<any>([])
  40. const [scrollTop, setScrollTop] = useState(0)
  41. const [fastRecommendIndex, setFastRecommendIndex] = useState(-1)
  42. const [fastLastIndex, setFastLastIndex] = useState(-1)
  43. const [scrollHeight, setScrollHeight] = useState(0)
  44. const { t } = useTranslation()
  45. const scrollViewRef = useRef(null);
  46. useEffect(() => {
  47. if (navigation) {
  48. navigation.setOptions({
  49. headerTitle: '',
  50. });
  51. }
  52. if (pageStep == 1) {
  53. var obj = target.fast.schedule.fast
  54. var array: any = []
  55. var currentIndex = -1;
  56. var recommendIndex = -1;
  57. var lastIndex = -1;
  58. for (var i = 0; i < obj.duration.options.length; i++) {
  59. if (obj.duration.options[i] == obj.duration.last_value) {
  60. lastIndex = i
  61. }
  62. if (obj.duration.options[i] == obj.duration.default_value) {
  63. recommendIndex = i
  64. }
  65. var fast = JSON.parse(JSON.stringify(target.fast))
  66. var startCount = fast.schedule.fast.end_time.split(':')[0] * 60 + fast.schedule.fast.end_time.split(':')[1] * 1 - obj.duration.options[i]
  67. if (startCount < 0) {
  68. startCount += 24 * 60
  69. }
  70. var start = TimeFormatter.padZero(Math.floor(startCount / 60)) + ':' + TimeFormatter.padZero(startCount % 60)
  71. array.push({
  72. hours: obj.duration.options[i] / 60,
  73. left: 24 - obj.duration.options[i] / 60,
  74. // minutes: obj.duration.minutes[i],
  75. // number: obj.duration.numbers[i],
  76. time: start
  77. })
  78. if (obj.duration.options[i] == obj.duration.init_value) {
  79. currentIndex = i
  80. }
  81. }
  82. // 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)
  83. // if (duration <= 0) {
  84. // duration += 24 * 60
  85. // }
  86. // var durationHours = Math.floor(duration / 60)
  87. // var durationMinutes = duration % 60
  88. // var currentIndex = -1;
  89. // var array: any = []
  90. // for (var i = 12; i <= 23; i++) {
  91. // if (i != 23 || durationMinutes == 0) {
  92. // array.push({
  93. // hours: i,
  94. // minutes: durationMinutes
  95. // });
  96. // }
  97. // }
  98. // for (var i = 0; i < array.length; i++) {
  99. // if (array[i].hours == durationHours && array[i].minutes == durationMinutes) {
  100. // currentIndex = i
  101. // break
  102. // }
  103. // }
  104. setFastRecommendIndex(recommendIndex)
  105. setFastLastIndex(lastIndex)
  106. setSuggestItem(array)
  107. setSuggestIndex(currentIndex)
  108. setScrollTop(currentIndex * (rpxToPx(92 + 28) + 72) - 30)
  109. if (process.env.TARO_ENV == 'rn') {
  110. setTimeout(() => {
  111. (scrollViewRef.current as any).scrollTo({ x: 0, y: currentIndex * (rpxToPx(92 + 28) + 72) - 30, animated: true })
  112. }, 500)
  113. }
  114. else {
  115. setTimeout(() => {
  116. Taro.createSelectorQuery().select('#myScrollView').boundingClientRect((rect) => {
  117. var screenHeight = Taro.getSystemInfoSync().screenHeight
  118. var safeBottom = Taro.getSystemInfoSync().safeArea?.bottom
  119. setScrollHeight(Taro.getSystemInfoSync().windowHeight - (rect as any).top - rpxToPx(88) - 50 - (screenHeight - safeBottom) - rpxToPx(46));
  120. }).exec()
  121. }, 100)
  122. }
  123. }
  124. else if (pageStep == 3) {
  125. var obj = target.sleep.schedule.sleep
  126. var sleep_cycle = obj.cycle
  127. var sleep_latency = obj.latency.init_value
  128. var array: any = []
  129. var index: number = 0;
  130. for (var i = 0; i < sleep_cycle.num.options.length; i++) {
  131. var count = sleep_cycle.num.options[i] * sleep_cycle.duration.init_value + sleep_latency
  132. //sleep.schedule.sleep.cycle.num.init_value = sleep.schedule.sleep.cycle.num.options[suggestIndex]
  133. if (sleep_cycle.num.options[i] == sleep_cycle.num.init_value) {
  134. index = i
  135. }
  136. var sleep = JSON.parse(JSON.stringify(target.sleep))
  137. var startCount = sleep.schedule.sleep.end_time.split(':')[0] * 60 + sleep.schedule.sleep.end_time.split(':')[1] * 1 - count
  138. if (startCount < 0) {
  139. startCount += 24 * 60
  140. }
  141. var start = TimeFormatter.padZero(Math.floor(startCount / 60)) + ':' + TimeFormatter.padZero(startCount % 60)
  142. array.push({
  143. hours: Math.floor(count / 60),
  144. minutes: count % 60,
  145. number: sleep_cycle.num.options[i],
  146. time: start
  147. })
  148. }
  149. setSuggestItem(array)
  150. setSuggestIndex(index)
  151. }
  152. }, [])
  153. useDidShow(() => {
  154. dispatch(updateStep({ step: pageStep }))
  155. })
  156. function next() {
  157. if (pageStep == 1) {
  158. var item = suggestItems[suggestIndex]
  159. var fast = JSON.parse(JSON.stringify(target.fast))
  160. // var startCount = fast.schedule.fast.end_time.split(':')[0] * 60 + fast.schedule.fast.end_time.split(':')[1] * 1 - (item.hours * 60 + item.minutes)
  161. // if (startCount < 0) {
  162. // startCount += 24 * 60
  163. // }
  164. // var start = TimeFormatter.padZero(Math.floor(startCount / 60)) + ':' + TimeFormatter.padZero(startCount % 60)
  165. fast.schedule.fast.start_time = item.time
  166. fast.schedule.fast.duration.init_value = fast.schedule.fast.duration.options[suggestIndex]
  167. dispatch(updateFast({ fast: fast }))
  168. }
  169. else if (pageStep == 3) {
  170. var item = suggestItems[suggestIndex]
  171. var sleep = JSON.parse(JSON.stringify(target.sleep))
  172. var startCount = sleep.schedule.sleep.end_time.split(':')[0] * 60 + sleep.schedule.sleep.end_time.split(':')[1] * 1 - (item.hours * 60 + item.minutes)
  173. if (startCount < 0) {
  174. startCount += 24 * 60
  175. }
  176. var start = TimeFormatter.padZero(Math.floor(startCount / 60)) + ':' + TimeFormatter.padZero(startCount % 60)
  177. sleep.schedule.sleep.start_time = start
  178. sleep.schedule.sleep.cycle.num.init_value = sleep.schedule.sleep.cycle.num.options[suggestIndex]
  179. dispatch(updateSleep({ sleep: sleep }))
  180. }
  181. var step: number = target.step + 1
  182. dispatch(updateStep({ step: step }))
  183. var url = '/pages/clock/Suggest?trigger_event=' + router.params.trigger_event
  184. var pageName = 'Suggest'
  185. if (!target.isMixed) {
  186. if (step == 2) {
  187. url = '/pages/clock/SetGoal?trigger_event=' + router.params.trigger_event
  188. pageName = 'SetGoal'
  189. }
  190. }
  191. else {
  192. if (step == 4) {
  193. url = '/pages/clock/SetGoal?trigger_event=' + router.params.trigger_event
  194. pageName = 'SetGoal'
  195. }
  196. }
  197. jumpPage(url, pageName, navigation, {
  198. trigger_event: router.params.trigger_event
  199. })
  200. }
  201. function myself() {
  202. jumpPage(`/pages/clock/SetGoal?isSelf=1&trigger_event=` + router.params.trigger_event, 'SetGoal', navigation, {
  203. isSelf: 1,
  204. trigger_event: router.params.trigger_event
  205. })
  206. }
  207. function suggestTitle() {
  208. switch (pageStep) {
  209. case 0:
  210. return t('feature.suggest.step_0_title')
  211. case 1:
  212. return t('feature.suggest.step_1_title')
  213. case 2:
  214. return t('feature.suggest.step_2_title')
  215. case 3:
  216. return t('feature.suggest.step_3_title')
  217. default:
  218. return ''
  219. }
  220. }
  221. function suggestDesc() {
  222. switch (pageStep) {
  223. case 0:
  224. return t('feature.suggest.end_fast_picker_header')
  225. case 1:
  226. return t('feature.suggest.fast_suggest_header', { time: target.fast.schedule.fast.end_time })
  227. case 2:
  228. return t('feature.suggest.end_sleep_picker_header')
  229. case 3:
  230. return t('feature.suggest.sleep_suggest_header', { time: target.sleep.schedule.sleep.end_time })
  231. default:
  232. return ''
  233. }
  234. }
  235. function durationDatas() {
  236. var min: number = 0
  237. var max: number = 23
  238. var step: number = 5
  239. var minutes: string[] = []
  240. for (let i = 0; i < 60; i += step) {
  241. minutes.push(TimeFormatter.padZero(i))
  242. }
  243. var hours: string[] = []
  244. for (let i = min; i <= max; i++) {
  245. hours.push(TimeFormatter.padZero(i))
  246. }
  247. return [hours, minutes]
  248. }
  249. function durationValues() {
  250. var eatTime = target.fast.schedule.fast.end_time
  251. if (pageStep == 2) {
  252. eatTime = target.sleep.schedule.sleep.end_time
  253. }
  254. var eatHour = eatTime.split(':')[0]
  255. var eatMin = eatTime.split(':')[1]
  256. var list = durationDatas()
  257. var hourIndex = 0
  258. var minIndex = 0
  259. for (let i = 0; i < list[0].length; i++) {
  260. if (list[0][i] == eatHour) {
  261. hourIndex = i
  262. break
  263. }
  264. }
  265. for (let i = 0; i < list[1].length; i++) {
  266. if (list[1][i] == eatMin) {
  267. minIndex = i
  268. break
  269. }
  270. }
  271. return [hourIndex, minIndex]
  272. }
  273. function sleepLatency() {
  274. var obj = target.sleep.schedule.sleep.latency
  275. var min: number = obj.min
  276. var max: number = obj.max
  277. var step: number = obj.step
  278. var minutes: string[] = []
  279. for (let i = min; i <= max; i += step) {
  280. minutes.push(i + ' ' + t('feature.suggest.mins'))
  281. }
  282. return [minutes]
  283. }
  284. function sleepLatencyValue() {
  285. var obj = target.sleep.schedule.sleep.latency
  286. var value: number = obj.init_value
  287. var min: number = obj.min
  288. var step: number = obj.step
  289. var index = (value - min) / step
  290. return [index]
  291. }
  292. function timePickerChanged(e: any) {
  293. var obj = target.fast.schedule.fast
  294. if (pageStep == 2) {
  295. obj = target.sleep.schedule.sleep
  296. }
  297. 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)
  298. if (duration <= 0) {
  299. duration += 24 * 60
  300. }
  301. var endCount = duration - (e[0] * 60 + e[1] * 5)
  302. if (endCount < 0) {
  303. endCount += 24 * 60
  304. }
  305. var time = TimeFormatter.padZero(e[0]) + ':' + TimeFormatter.padZero(e[1] * 5)
  306. var start = TimeFormatter.padZero(Math.floor(endCount / 60)) + ':' + TimeFormatter.padZero(endCount % 60)
  307. if (pageStep == 0) {
  308. var fast = JSON.parse(JSON.stringify(target.fast))
  309. fast.schedule.fast.end_time = time
  310. fast.schedule.fast.start_time = start
  311. dispatch(updateFast({ fast: fast }))
  312. }
  313. else {
  314. var sleep = JSON.parse(JSON.stringify(target.sleep))
  315. sleep.schedule.sleep.end_time = time
  316. sleep.schedule.sleep.start_time = start
  317. dispatch(updateSleep({ sleep: sleep }))
  318. }
  319. }
  320. function picker1() {
  321. return <PickerViews ref={null}
  322. onChange={timePickerChanged}
  323. items={durationDatas()}
  324. value={durationValues()} height={170}
  325. title=''
  326. themeColor={target.isMixed ? global.fastColor ? global.fastColor : ColorType.fast : global.sleepColor ? global.sleepColor : ColorType.sleep}
  327. showBtns={false}
  328. hideTitle={true}
  329. onCancel={() => { }} />
  330. }
  331. function timePicker() {
  332. return <View>
  333. {
  334. process.env.TARO_ENV == 'weapp' ? <View style={{
  335. marginBottom: rpxToPx(40), marginLeft: rpxToPx(46),
  336. marginRight: rpxToPx(46), borderRadius: 10,
  337. overflow: 'hidden', backgroundColor: '#1c1c1c', paddingTop: 10, paddingBottom: 10
  338. }}>
  339. {picker1()}
  340. </View> :
  341. <View style={{
  342. marginBottom: rpxToPx(40), marginLeft: rpxToPx(46),
  343. marginRight: rpxToPx(46), borderRadius: 10,
  344. overflow: 'hidden', backgroundColor: '#1c1c1c',
  345. height: 180,
  346. justifyContent: 'center'
  347. }}>
  348. {picker1()}
  349. </View>
  350. }
  351. {
  352. pageStep == 0 && <Text className="suggest_footer_note">{t('feature.suggest.end_fast_picker_footer')}</Text>
  353. }
  354. {
  355. pageStep == 1 && <Text className="suggest_footer_note">If you plan to skip breakfast, pick a time for your first meal of the day.</Text>
  356. }
  357. </View>
  358. }
  359. function fallSleepChanged(e: any) {
  360. var value = target.sleep.schedule.sleep.latency
  361. var time = e[0] * value.step + value.min
  362. var sleep = JSON.parse(JSON.stringify(target.sleep))
  363. sleep.schedule.sleep.latency.init_value = time
  364. dispatch(updateSleep({ sleep: sleep }))
  365. }
  366. function picker2() {
  367. return <PickerViews ref={null}
  368. onChange={fallSleepChanged}
  369. items={sleepLatency()}
  370. value={sleepLatencyValue()} height={170}
  371. title=''
  372. themeColor={target.isMixed ? global.fastColor ? global.fastColor : ColorType.fast : global.sleepColor ? global.sleepColor : ColorType.sleep}
  373. showBtns={false}
  374. hideTitle={true}
  375. onCancel={() => { }} />
  376. }
  377. function fallSleepPicker() {
  378. return <View>
  379. <View className="target_desc">{t('feature.suggest.fall_sleep_picker_header')}</View>
  380. {
  381. process.env.TARO_ENV == 'weapp' ? <View style={{
  382. marginLeft: rpxToPx(46), marginRight: rpxToPx(46),
  383. borderRadius: 10,
  384. overflow: 'hidden', backgroundColor: '#1c1c1c', paddingTop: 10, paddingBottom: 10
  385. }}>
  386. {
  387. picker2()
  388. }
  389. </View> :
  390. <View style={{
  391. marginLeft: rpxToPx(46), marginRight: rpxToPx(46),
  392. borderRadius: 10,
  393. overflow: 'hidden', backgroundColor: '#1c1c1c',
  394. justifyContent:'center',
  395. height:180
  396. }}>
  397. {
  398. picker2()
  399. }
  400. </View>
  401. }
  402. <Text className="suggest_footer_note">{t('feature.suggest.fall_sleep_picker_footer')}</Text>
  403. </View>
  404. }
  405. // const common: RingCommon = {
  406. // useCase: 'ChooseScenario',
  407. // radius: 33,
  408. // lineWidth: 8,
  409. // isFast: true,
  410. // status: 'WAIT_FOR_START'
  411. // }
  412. const bgRing: BgRing = {
  413. color: '#262626'
  414. }
  415. // const targetRing: TargetRing = {
  416. // color: ColorType.fast,
  417. // startArc: timeToArc(ring.schedule.fast.start_time),
  418. // durationArc: durationToArc(ring.schedule.fast.start_time, ring.schedule.fast.end_time)
  419. // }
  420. function ringCommon() {
  421. return {
  422. useCase: 'ChooseScenario',
  423. radius: 30,
  424. lineWidth: 12,
  425. isFast: true,
  426. status: 'WAIT_FOR_START'
  427. }
  428. }
  429. function targetRing(start, end, isFast, isHighLight) {
  430. var color: any = isFast ? ColorType.fast + '66' : ColorType.sleep + '66'
  431. if (!isHighLight) {
  432. color = isFast ? ColorType.fast + '0D' : ColorType.sleep + '0D'
  433. }
  434. return {
  435. color: color,
  436. startArc: timeToArc(start),
  437. durationArc: durationToArc(start, end)
  438. }
  439. }
  440. function point(isFast: boolean, isShow: boolean) {
  441. if (!isShow) return null;
  442. var now = new Date()
  443. var t = suggestItems[suggestIndex].time
  444. now.setHours(parseInt(t.split(':')[0]))
  445. now.setMinutes(parseInt(t.split(':')[1]))
  446. return [{
  447. color: isFast ? ColorType.fast : ColorType.sleep,
  448. borderColor: 'transparent',
  449. timestamp: now.getTime()
  450. }]
  451. }
  452. function timeToArc(time: string) {
  453. var count: number = parseInt(time.split(':')[1]) + parseInt(time.split(':')[0]) * 60
  454. // count = count>720?count-720:count
  455. return (count as any) / 1440 * 2 * Math.PI - Math.PI / 2
  456. }
  457. function durationToArc(startTime: string, endTime: string) {
  458. var start: number = parseInt(startTime.split(':')[1]) + parseInt(startTime.split(':')[0]) * 60
  459. var end: number = parseInt(endTime.split(':')[1]) + parseInt(endTime.split(':')[0]) * 60
  460. if (end <= start) {
  461. end += 1440
  462. }
  463. return (end - start) / 1440 * 2 * Math.PI
  464. }
  465. function scrollContent() {
  466. return <View style={{ flexDirection: 'column', display: 'flex' }}>
  467. {
  468. suggestItems.map((item: any, index: number) => {
  469. return <View key={index} className={suggestIndex == index ? 'item1 item_sel1' : 'item1'} onClick={() => setSuggestIndex(index)}>
  470. <View style={{ flexShrink: 0, display: 'flex', width: 74, height: 74, marginRight: rpxToPx(24) }}>
  471. <Rings2 common={ringCommon()}
  472. bgRing={bgRing}
  473. targetRing={targetRing(item.time, target.fast.schedule.fast.end_time, true, suggestIndex == index)}
  474. dotList={point(true, index == suggestIndex)}
  475. canvasId={new Date().getTime() + index * 5} />
  476. </View>
  477. <View style={{ flex: 1 }}>
  478. <View className="suggest_item_title">{item.hours}{t('feature.suggest.hour')}</View>
  479. <View className="suggest_item_desc">{index == suggestIndex ?
  480. t('feature.suggest.fast_desc', { start_time: item.hours, end_time: item.left }) :
  481. t('feature.suggest.intermittent_fast', { data: `${item.hours}/${item.left}` })
  482. }</View>
  483. {
  484. index == suggestIndex &&
  485. <View className="suggest_choose">
  486. <View className="suggest_choose_text" style={{ color: ColorType.fast }}>{t('feature.suggest.start_fast_time', { time: item.time })}</View>
  487. </View>
  488. }
  489. </View>
  490. {
  491. index == suggestIndex && <View className="choose_item_check_bg">
  492. <IconCheck color={ColorType.fast} width={24} height={24} />
  493. </View>
  494. }
  495. <View className='suggest_fast_tag_bg'>
  496. {
  497. index == fastRecommendIndex &&
  498. <View className='suggest_fast_tag'>{t('feature.suggest.popular')}</View>
  499. }
  500. {
  501. index == fastLastIndex &&
  502. <View className='suggest_fast_tag'>{t('feature.suggest.recent')}</View>
  503. }
  504. </View>
  505. </View>
  506. // return <View onClick={() => {
  507. // setSuggestIndex(index)
  508. // }} key={index} className={index == suggestIndex ? 'item_choose_selected' : 'item_choose'}>
  509. // <View style={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
  510. // <View className="suggest_item_title">{item.hours} hours</View>
  511. // <View style={{ flex: 1 }} />
  512. // {
  513. // index == fastRecommendIndex &&
  514. // <View style={{ color: '#fff' }}>Popular</View>
  515. // }
  516. // {
  517. // index == fastLastIndex &&
  518. // <View style={{ color: '#fff', marginLeft: 5 }}>Recent</View>
  519. // }
  520. // </View>
  521. // <View className="suggest_item_desc">{index == suggestIndex ? `${item.hours} hours fasting / ${item.left} hours eating` : `${item.hours}/${item.left} Intermittent Fasting`}</View>
  522. // {
  523. // index == suggestIndex &&
  524. // <View className="suggest_choose">
  525. // <View style={{ color: ColorType.fast }}>Start fasting at {item.time}</View>
  526. // <IconCheck color={ColorType.fast} width={38} height={26} />
  527. // </View>
  528. // }
  529. // </View>
  530. })
  531. }
  532. </View>
  533. }
  534. function suggestList() {
  535. if (pageStep == 1 && process.env.TARO_ENV === 'weapp') {
  536. return <ScrollView scrollY style={{ height: scrollHeight }} id="myScrollView" scrollTop={scrollTop}>
  537. {
  538. scrollContent()
  539. }
  540. </ScrollView>
  541. }
  542. if (pageStep == 1 && process.env.TARO_ENV === 'rn') {
  543. return <ScrollViewRN style={{ height: rpxToPx(868) }} ref={scrollViewRef}>
  544. {
  545. scrollContent()
  546. }
  547. </ScrollViewRN>
  548. }
  549. return <View style={{ height:400 }}>
  550. {
  551. suggestItems.map((item: any, index: number) => {
  552. return <View key={index} className={suggestIndex == index ? 'item1 item_sel1' : 'item1'} style={{ borderColor: suggestIndex == index ? ColorType.sleep : '#00000000' }} onClick={() => setSuggestIndex(index)}>
  553. <View style={{ flexShrink: 0, display: 'flex', width: 74, height: 74, marginRight: rpxToPx(24) }}>
  554. <Rings2 common={ringCommon()}
  555. bgRing={bgRing}
  556. dotList={point(false, index == suggestIndex)}
  557. targetRing={targetRing(item.time, target.sleep.schedule.sleep.end_time, false, suggestIndex == index)}
  558. canvasId={new Date().getTime() + index * 5} />
  559. </View>
  560. <View>
  561. <View className="suggest_item_title">{item.hours}{t('feature.suggest.hours2')}{item.minutes > 0 && item.minutes + t('feature.suggest.minute')}</View>
  562. <View className="suggest_item_desc">{t('feature.suggest.cycles', { times: item.number })}</View>
  563. {
  564. index == suggestIndex && <View className="suggest_choose">
  565. <View className="suggest_choose_text" style={{ color: ColorType.sleep }}>{t('feature.suggest.go_to_bed_at', { time: item.time })}</View>
  566. </View>
  567. }
  568. </View>
  569. {
  570. index == 0 && <View className='suggest_tag' style={{ backgroundColor: ColorType.sleep }}>{t('feature.suggest.popular')}</View>
  571. }
  572. {
  573. index == 1 && <View className='suggest_tag' style={{ backgroundColor: ColorType.sleep }}>{t('feature.suggest.restorative')}</View>
  574. }
  575. {
  576. index == suggestIndex && <View className="choose_item_check_bg">
  577. <IconCheck color={ColorType.sleep} width={24} height={24} />
  578. </View>
  579. }
  580. </View>
  581. })
  582. }
  583. </View>
  584. }
  585. function content() {
  586. return <View style={{ display: 'flex', flexDirection: 'column' }}>
  587. {
  588. (pageStep == 0 || pageStep == 2) && timePicker()
  589. }
  590. {
  591. (pageStep == 1 || pageStep == 3) && suggestList()
  592. }
  593. {
  594. pageStep == 3 && <Text className="suggest_footer_note">{t('feature.suggest.sleep_suggest_footer')}</Text>
  595. }
  596. {
  597. pageStep == 2 && fallSleepPicker()
  598. }
  599. {
  600. pageStep == 2 && process.env.TARO_ENV=='weapp' && <View style={{ height: 200 }} />
  601. }
  602. </View>
  603. }
  604. function btnText() {
  605. // if (pageStep == 3){
  606. // return t('feature.suggest.done')
  607. // }
  608. // if (pageStep == 1 && !target.isMixed){
  609. // return t('feature.suggest.done')
  610. // }
  611. return t('feature.suggest.btn')
  612. }
  613. return <View style={{ display: 'flex', flexDirection: 'column', flex: 1, height: process.env.TARO_ENV == 'weapp' ? '100vh' : 'auto' }}>
  614. <Text className="target_title">{suggestTitle()}</Text>
  615. <Text className="target_desc">{suggestDesc()}</Text>
  616. {
  617. content()
  618. }
  619. {
  620. process.env.TARO_ENV == 'rn' && <View style={{ flex: 1 }} />
  621. }
  622. <Footer>
  623. <View style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
  624. <ChooseScenarioBtn
  625. onClick={next}
  626. title={btnText()}
  627. background={pageStep < 2 ? ColorType.fast : ColorType.sleep}
  628. />
  629. <Text className="suggest_footer_btn" onClick={myself}>{t('feature.suggest.set_myself')}</Text>
  630. </View>
  631. </Footer>
  632. {
  633. process.env.TARO_ENV == 'rn' && <View style={{ marginBottom: 20 }} />
  634. }
  635. </View>
  636. }