setting.tsx 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. import { View, Text, ScrollView } from "@tarojs/components";
  2. import Metric from "@/features/trackSomething/components/Metric";
  3. import { useDidShow, usePullDownRefresh, useShareAppMessage } from "@tarojs/taro";
  4. import { useTranslation } from "react-i18next";
  5. import Segment from '@/components/navigation/Segment'
  6. import { useEffect, useState } from "react";
  7. import { kIsAndroid, rpxToPx } from "@/utils/tools";
  8. import './setting.scss'
  9. import { getNotifySettings, postNotifySettings } from "@/services/notifications";
  10. import { ColorType } from "@/context/themes/color";
  11. import { getLocalPush } from "@/features/trackTimeDuration/actions/TrackTimeActions";
  12. import { useSelector } from "react-redux";
  13. import ProductList from "../store/product_list";
  14. import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
  15. import { getPerm, userAccess } from "@/services/user";
  16. import '@/features/trackTimeDuration/components/CheckAccess.scss';
  17. import Modal from "@/components/layout/Modal.weapp";
  18. import Layout from "@/components/layout/layout";
  19. import { NaviBarTitleShowType, TemplateType } from "@/utils/types";
  20. import TitleView from "@/features/trackTimeDuration/components/TitleView";
  21. let useNavigation;
  22. let AppState, Switch;
  23. if (process.env.TARO_ENV == 'rn') {
  24. AppState = require("react-native").AppState
  25. Switch = require("react-native").Switch
  26. useNavigation = require("@react-navigation/native").useNavigation
  27. }
  28. export default function Page() {
  29. const { t } = useTranslation()
  30. const [segmentIndex, setSegmentIndex] = useState(0)
  31. const [notification, setNotification] = useState<any>(null)
  32. const [isExtra, setIsExtra] = useState(false)
  33. const [isSunrise, setIsSunrise] = useState(false)
  34. const [isSunset, setIsSunset] = useState(false)
  35. const [isSolarNoon, setIsSolarNoon] = useState(false)
  36. const [loaded, setLoaded] = useState(false)
  37. const [systemFast, setSystemFast] = useState(true)
  38. const [systemExtra, setSystemExtra] = useState(true)
  39. const [systemSun, setSystemSun] = useState(true)
  40. const [showMemberAlert, setShowMemberAlert] = useState(false)
  41. const user = useSelector((state: any) => state.user);
  42. const accessObj = useSelector((state: any) => state.access);
  43. let navigation;
  44. if (useNavigation) {
  45. navigation = useNavigation()
  46. }
  47. // useEffect(() => {
  48. // }, [])
  49. useEffect(() => {
  50. if (!user.isLogin) {
  51. return;
  52. }
  53. checkSetting()
  54. getSettings()
  55. getMemberStatus()
  56. if (process.env.TARO_ENV == 'rn') {
  57. navigation.setOptions({
  58. headerTitle: '',
  59. });
  60. AppState.addEventListener('change', handleAppStateChange);
  61. // AppState.addEventListener('change', handleAppStateChange);
  62. // navigation.addListener('focus', () => {
  63. // checkSetting()
  64. // });
  65. // // 当页面即将消失时执行
  66. // navigation.addListener('blur', () => {
  67. // console.log('notfication setting blur')
  68. // });
  69. }
  70. if (process.env.TARO_ENV == 'rn') {
  71. // AppState.addEventListener('change', handleAppStateChange);
  72. navigation.addListener('focus', () => {
  73. getMemberStatus()
  74. });
  75. // 当页面即将消失时执行
  76. navigation.addListener('blur', () => {
  77. });
  78. }
  79. }, [user.isLogin])
  80. const handleAppStateChange = (nextAppState) => {
  81. console.log(nextAppState)
  82. if (nextAppState != 'active') {
  83. return
  84. }
  85. if (nextAppState == 'active') {
  86. checkSetting()
  87. getMemberStatus()
  88. }
  89. };
  90. function getMemberStatus() {
  91. const { access } = accessObj
  92. if (access && access.member) {
  93. if (access.member.status == 'NON_MEMBER') {
  94. postNotifySettings({
  95. notification: {
  96. follow_sun: {
  97. sunrise: {
  98. in_app: 'OFF'
  99. },
  100. sunset: {
  101. in_app: 'OFF'
  102. },
  103. solar_noon: {
  104. in_app: 'OFF'
  105. }
  106. }
  107. }
  108. }).then(res => {
  109. setIsSolarNoon(false)
  110. setIsSunset(false)
  111. setIsSunrise(false)
  112. global.swiperDayNightRefresh()
  113. })
  114. }
  115. }
  116. }
  117. useDidShow(() => {
  118. console.log('notfication setting user did show')
  119. })
  120. function getSettings() {
  121. getNotifySettings().then(res => {
  122. var dt = (res as any).notification
  123. setNotification(dt)
  124. setIsExtra(dt.fast_sleep.extra_reminders.in_app == 'ON')
  125. setIsSunrise(dt.follow_sun.sunrise.in_app == 'ON')
  126. setIsSunset(dt.follow_sun.sunset.in_app == 'ON')
  127. setIsSolarNoon(dt.follow_sun.solar_noon.in_app == 'ON')
  128. setLoaded(true)
  129. })
  130. }
  131. function checkSetting() {
  132. console.log('notification setting begin')
  133. if (process.env.TARO_ENV == 'rn' && kIsAndroid) {
  134. var Jto = require('react-native').NativeModules.NativeBridge;
  135. Jto.getChannelStatus().then(result => {
  136. var data = JSON.parse(result);
  137. console.log('notification setting', data)
  138. if (data.all) {
  139. }
  140. else {
  141. var REMINDER_FS_STATUS = ''
  142. var REMINDER_SUN_STATUS = ''
  143. var REMINDER_FS_EXTRA_STATUS = ''
  144. if ('REMINDER_FS' in data) {
  145. REMINDER_FS_STATUS = data.REMINDER_FS ? 'ON' : 'OFF'
  146. setSystemFast(data.REMINDER_FS)
  147. }
  148. else {
  149. REMINDER_FS_STATUS = 'NA'
  150. }
  151. if ('REMINDER_SUN' in data) {
  152. REMINDER_SUN_STATUS = data.REMINDER_SUN ? 'ON' : 'OFF'
  153. setSystemSun(data.REMINDER_SUN)
  154. }
  155. else {
  156. REMINDER_SUN_STATUS = 'NA'
  157. }
  158. if ('REMINDER_FS_EXTRA' in data) {
  159. REMINDER_FS_EXTRA_STATUS = data.REMINDER_FS_EXTRA ? 'ON' : 'OFF'
  160. setSystemExtra(data.REMINDER_FS_EXTRA)
  161. }
  162. else {
  163. REMINDER_FS_EXTRA_STATUS = 'NA'
  164. }
  165. postNotifySettings({
  166. channels: {
  167. REMINDER_FS: {
  168. system: REMINDER_FS_STATUS
  169. },
  170. REMINDER_SUN: {
  171. system: REMINDER_SUN_STATUS
  172. },
  173. REMINDER_FS_EXTRA: {
  174. system: REMINDER_FS_EXTRA_STATUS
  175. }
  176. }
  177. }).then(res => {
  178. })
  179. }
  180. })
  181. }
  182. }
  183. function goSetting() {
  184. if (process.env.TARO_ENV == 'rn' && kIsAndroid) {
  185. var Jto = require('react-native').NativeModules.NativeBridge;
  186. Jto.openNotificationSettings()
  187. }
  188. }
  189. function free() {
  190. return <View className="setting_container">
  191. <View className="setting_section">
  192. <Text className="setting_section_title">Fasting</Text>
  193. </View>
  194. <Text className="setting_header">Reminders</Text>
  195. <View className="setting_cell">
  196. <Text className="setting_cell_title" style={{ flex: 1 }}>At your scheduled time</Text>
  197. <Text className="setting_cell_value1">{notification.fast_sleep.reminders.in_app}</Text>
  198. </View>
  199. <Text className="setting_footer">A timely reminder so you never miss your scheduled time for fasting.</Text>
  200. </View>
  201. }
  202. function confirm() {
  203. jumpPage('', 'ProductList', navigation)
  204. setShowMemberAlert(false)
  205. }
  206. function alertPop() {
  207. return <View className="fast_alert_container">
  208. <View className="fast_alert_content" catchMove>
  209. <View className="fast_alert_title">Pro Access</View>
  210. <View className="fast_alert_detail">With Pro Membership, you can set custom reminders and will be reminded even when you're not actively using the app.</View>
  211. <View className='fast_alert_confirm' onClick={confirm}>
  212. <Text style={{ fontWeight: 'bold', color: ColorType.black }}>Become a Pro Member</Text>
  213. </View>
  214. <View className="fast_alert_cancel" onClick={()=>{setShowMemberAlert(false)}}>Not now</View>
  215. </View>
  216. </View>
  217. }
  218. function pro(isLogin: boolean) {
  219. return <ScrollView style={{ flex: 1 }}>
  220. {/* <ProductList /> */}
  221. {/* <Text style={{fontSize:30,color:'#fff'}} onClick={iap}>iap test</Text> */}
  222. <View className="setting_container">
  223. <View className="setting_section">
  224. <Text className="setting_section_title">Fasting & Sleep</Text>
  225. </View>
  226. <Text className="setting_header">Reminders</Text>
  227. <View className="setting_cell">
  228. <Text className="setting_cell_title" style={{ flex: 1 }}>At my scheduled time</Text>
  229. {
  230. isLogin ? <Text className="setting_cell_value1">{systemFast ? 'Always' : 'Off'}</Text> :
  231. <Text className="setting_cell_value1">Off</Text>
  232. }
  233. </View>
  234. <Text className="setting_footer">A timely reminder so you never miss your schedule time for fasting and/or sleep.</Text>
  235. <Text className="setting_header">Extra Reminders (Pro)</Text>
  236. <View className="setting_cell">
  237. <Text className="setting_cell_title" style={{ flex: 1 }}>Missed previous action</Text>
  238. <Switch className="myswitch" value={isLogin ? isExtra : false} color={ColorType.fast} trackColor={{ true: ColorType.fast }} onChange={(e) => {
  239. if (!isLogin) {
  240. jumpPage('/pages/account/ChooseAuth', 'ChooseAuth', navigation)
  241. return
  242. }
  243. const value = e.nativeEvent.value
  244. if (e.nativeEvent.value) {
  245. if (accessObj && accessObj.access && accessObj.access.member.status == 'NON_MEMBER') {
  246. // setTimeout(() => {
  247. // setIsSunrise(false)
  248. // }, 1000)
  249. // jumpPage('', 'ProductList', navigation)
  250. setShowMemberAlert(true)
  251. return
  252. }
  253. }
  254. postNotifySettings({
  255. notification: {
  256. fast_sleep: {
  257. extra_reminders: {
  258. in_app: value ? 'ON' : 'OFF'
  259. }
  260. }
  261. }
  262. }).then(res => {
  263. setIsExtra(value)
  264. getLocalPush()
  265. })
  266. }} />
  267. </View>
  268. <Text className="setting_footer">In case you missed your previous action, receive another reminder to log it together with the current one. This gives you extra protection against any streak loss.</Text>
  269. <View className="setting_section">
  270. <Text className="setting_section_title">The Sun (PRO)</Text>
  271. </View>
  272. <Text className="setting_header">Reminders for Your Daily Local Salor Times</Text>
  273. <View className="setting_cell_group">
  274. <View className="setting_cell_group_item">
  275. <Text className="setting_cell_title" style={{ flex: 1 }}>Sunrise</Text>
  276. <Switch className="myswitch" value={isLogin ? isSunrise : false} color={ColorType.fast} trackColor={{ true: ColorType.fast }} onChange={(e) => {
  277. // setIsMulti(e.nativeEvent.value)
  278. if (!isLogin) {
  279. jumpPage('/pages/account/ChooseAuth', 'ChooseAuth', navigation)
  280. return
  281. }
  282. const value = e.nativeEvent.value
  283. if (e.nativeEvent.value) {
  284. if (accessObj && accessObj.access && accessObj.access.member.status == 'NON_MEMBER') {
  285. // setTimeout(() => {
  286. // setIsSunrise(false)
  287. // }, 1000)
  288. // jumpPage('', 'ProductList', navigation)
  289. setShowMemberAlert(true)
  290. return
  291. }
  292. }
  293. postNotifySettings({
  294. notification: {
  295. follow_sun: {
  296. sunrise: {
  297. in_app: value ? 'ON' : 'OFF'
  298. }
  299. }
  300. }
  301. }).then(res => {
  302. setIsSunrise(value)
  303. // setIsSunrise(e.nativeEvent.value)
  304. global.swiperDayNightRefresh()
  305. })
  306. }} />
  307. </View>
  308. <View className="setting_cell_group_item">
  309. <Text className="setting_cell_title" style={{ flex: 1 }}>Sunset</Text>
  310. <Switch className="myswitch" value={isLogin ? isSunset : false} trackColor={{ true: ColorType.fast }} color={ColorType.fast} onChange={(e) => {
  311. // setIsMulti(e.nativeEvent.value)
  312. if (!isLogin) {
  313. jumpPage('/pages/account/ChooseAuth', 'ChooseAuth', navigation)
  314. return
  315. }
  316. const value = e.nativeEvent.value
  317. if (e.nativeEvent.value) {
  318. if (accessObj && accessObj.access && accessObj.access.member.status == 'NON_MEMBER') {
  319. // setTimeout(() => {
  320. // setIsSunset(false)
  321. // }, 1000)
  322. // jumpPage('', 'ProductList', navigation)
  323. setShowMemberAlert(true)
  324. return
  325. }
  326. }
  327. postNotifySettings({
  328. notification: {
  329. follow_sun: {
  330. sunset: {
  331. in_app: value ? 'ON' : 'OFF'
  332. }
  333. }
  334. }
  335. }).then(res => {
  336. setIsSunset(value)
  337. global.swiperDayNightRefresh()
  338. })
  339. }} />
  340. </View>
  341. <View className="setting_cell_group_item">
  342. <Text className="setting_cell_title" style={{ flex: 1 }}>Solar Noon</Text>
  343. <Switch className="myswitch" value={isLogin ? isSolarNoon : false} trackColor={{ true: ColorType.fast }} color={ColorType.fast} onChange={(e) => {
  344. // setIsMulti(e.nativeEvent.value)
  345. if (!isLogin) {
  346. jumpPage('/pages/account/ChooseAuth', 'ChooseAuth', navigation)
  347. return
  348. }
  349. const value = e.nativeEvent.value
  350. if (e.nativeEvent.value) {
  351. if (accessObj && accessObj.access && accessObj.access.member.status == 'NON_MEMBER') {
  352. // setTimeout(() => {
  353. // setIsSolarNoon(false)
  354. // }, 1000)
  355. // jumpPage('', 'ProductList', navigation)
  356. setShowMemberAlert(true)
  357. return
  358. }
  359. }
  360. postNotifySettings({
  361. notification: {
  362. follow_sun: {
  363. solar_noon: {
  364. in_app: value ? 'ON' : 'OFF'
  365. }
  366. }
  367. }
  368. }).then(res => {
  369. debugger
  370. setIsSolarNoon(value)
  371. global.swiperDayNightRefresh()
  372. })
  373. }} />
  374. </View>
  375. </View>
  376. <Text className="setting_footer">Note if live in polar region, during time of Polar Day (Midnight Sun) when the Sun is up all day and during time of Polar Night when the Sun is down all day, the only reminder available is for daily Solar Noon.</Text>
  377. </View>
  378. </ScrollView>
  379. }
  380. function checkSystemChannel() {
  381. if (!systemFast) {
  382. return true;
  383. }
  384. if (!systemExtra && isExtra) {
  385. return true;
  386. }
  387. if (!systemSun && (isSolarNoon || isSunrise || isSunset)) {
  388. return true;
  389. }
  390. return false;
  391. }
  392. if (!user.isLogin)
  393. return <View className="container" style={{ flex: 1 }}>
  394. <Layout title={t('page.reminders.title')}
  395. titleShowStyle={NaviBarTitleShowType.scrollToShow}
  396. type={TemplateType.customHeader}
  397. header={headerView()}
  398. // triggered={triggered}
  399. // refresh={refresh}
  400. >
  401. {
  402. pro(false)
  403. }
  404. </Layout>
  405. </View>
  406. function headerView() {
  407. return <TitleView title={t('page.reminders.title')} showAddBtn={false}>
  408. </TitleView>
  409. }
  410. return <View className="container" style={{ flex: 1 }}>
  411. <Layout title={t('page.reminders.title')}
  412. titleShowStyle={NaviBarTitleShowType.scrollToShow}
  413. type={TemplateType.customHeader}
  414. header={headerView()}
  415. // triggered={triggered}
  416. // refresh={refresh}
  417. >
  418. {
  419. loaded && pro(true)
  420. }
  421. {
  422. process.env.TARO_ENV == 'rn' && kIsAndroid && checkSystemChannel() && <View className="setting_tip" onClick={goSetting}>
  423. <Text className="setting_tip_text">Jump to App's Notifications settings{'>>'}</Text>
  424. </View>
  425. }
  426. {
  427. showMemberAlert && process.env.TARO_ENV == 'weapp' && alertPop()
  428. }
  429. {
  430. showMemberAlert && process.env.TARO_ENV == 'rn' && <Modal dismiss={() => { setShowMemberAlert(false) }}>
  431. <View style={{ backgroundColor: 'rgba(0,0,0,0.95)', width: '100%', height: '100%', alignItems: 'center', justifyContent: 'center' }}>
  432. {alertPop()}
  433. </View>
  434. </Modal>
  435. }
  436. </Layout>
  437. </View>
  438. }