themeContext.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import {createContext, useContext, useEffect, useState} from 'react';
  2. import {isRtlLang} from 'rtl-detect';
  3. import {useWindowSize} from "react-use";
  4. import {APP_THEME} from "@constants/app";
  5. import {ROUTE_PATH} from "@constants/routes";
  6. import {useSelector} from "react-redux";
  7. import {getUserInfo, isLogined} from "@features/mainSlice";
  8. const ThemeContext = createContext(undefined);
  9. export const ThemeProvider = ({children}) => {
  10. const {width} = useWindowSize();
  11. const page = document.documentElement;
  12. const isRtl = isRtlLang(navigator.language);
  13. const browserTheme = window.matchMedia('(prefers-color-scheme: light)');
  14. const persisted = JSON.parse(localStorage.getItem('preferences') || '{}');
  15. const isDesktop=()=>{
  16. return width>=1280;
  17. }
  18. const isTablet=()=>{
  19. return width<1280&&width>=768;
  20. }
  21. const isMobile=()=>{
  22. return width<768;
  23. }
  24. const [theme, setTheme] = useState(persisted && persisted.theme ? persisted.theme : (APP_THEME.DARK));
  25. // const [fontScale, setFontScale] = useState(persisted.fontScale || 1);
  26. const [fontScale, setFontScale] = useState(isMobile()?0.88:1);
  27. const [direction, setDirection] = useState(persisted.direction || (isRtl ? 'rtl' : 'ltr'));
  28. const [headerHeight,setHeaderHeight]=useState('64px');
  29. //GameSearch
  30. const [isShowSearch,setIsShowSearch]=useState(false);
  31. const [searchData,setSearchData]=useState(null);
  32. const [showHeader, setShowHeader] = useState(true);
  33. //GameSearch
  34. //lang select
  35. const [isShowLang,setIsShowLang]=useState(false);
  36. //show pass prompt
  37. const [isShowPassPrompt,setIsShowPassPrompt]=useState(false);
  38. const isLogin=useSelector(isLogined);
  39. const user=useSelector(getUserInfo);
  40. const stopTransition = () => {
  41. page.classList.add('no-transition');
  42. setTimeout(() => page.classList.remove('no-transition'), 100);
  43. }
  44. const savePreferences = () => {
  45. localStorage.setItem('preferences', JSON.stringify({
  46. theme,
  47. fontScale,
  48. direction
  49. }));
  50. }
  51. const toggleTheme = () => {
  52. setTheme(theme === APP_THEME.LIGHT ? APP_THEME.DARK : APP_THEME.LIGHT);
  53. // stopTransition();
  54. }
  55. const changeFontScale = (scale) => {
  56. setFontScale(scale);
  57. stopTransition();
  58. }
  59. const toggleDirection = () => {
  60. setDirection(direction === 'ltr' ? 'rtl' : 'ltr');
  61. page.setAttribute('dir', direction);
  62. }
  63. const initHeaderHeight=(height)=>{
  64. setHeaderHeight(height);
  65. }
  66. const showGameSearchPanel=(show,data)=>{
  67. setIsShowSearch(show);
  68. setSearchData(data);
  69. }
  70. //检查提现
  71. const checkWithdraw=()=>{
  72. if (isLogin){
  73. if (user){
  74. let InsurePass=Number(user.InsurePass);
  75. if (InsurePass!==1){
  76. setIsShowPassPrompt(true);
  77. return false;
  78. }
  79. }
  80. }
  81. return true;
  82. }
  83. //检查路由是否允许跳转
  84. const checkRoute=(path)=>{
  85. if (path===ROUTE_PATH.SAQUE){
  86. return checkWithdraw();
  87. }
  88. return true;
  89. }
  90. useEffect(() => {
  91. page.style.setProperty('--font-scale', fontScale);
  92. // page.style.setProperty('--widget-scale', fontScale === 1 ? '0px' : `${fontScale * 3}px`);
  93. page.setAttribute('dir', direction);
  94. savePreferences();
  95. // window
  96. // .matchMedia('(prefers-color-scheme: light)')
  97. // .addEventListener('change', event => {
  98. // event.matches ? setTheme('light') : setTheme('dark');
  99. // stopTransition();
  100. // savePreferences();
  101. // })
  102. // eslint-disable-next-line react-hooks/exhaustive-deps
  103. }, [theme, fontScale, direction]);
  104. return (
  105. <ThemeContext.Provider
  106. value={{
  107. theme,
  108. fontScale,
  109. direction,
  110. toggleTheme,
  111. changeFontScale,
  112. toggleDirection,
  113. isDesktop,
  114. isTablet,
  115. isMobile,
  116. headerHeight,
  117. initHeaderHeight,
  118. isShowSearch,
  119. searchData,
  120. showGameSearchPanel,
  121. showHeader,
  122. setShowHeader,
  123. //lang
  124. isShowLang,
  125. setIsShowLang,
  126. isShowPassPrompt,
  127. setIsShowPassPrompt,
  128. //检查路由是否允许跳转
  129. checkRoute
  130. }}>
  131. {children}
  132. </ThemeContext.Provider>
  133. );
  134. }
  135. export const useThemeProvider = () => useContext(ThemeContext);