themeContext.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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,height} = 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 initWindowSize=()=>{
  41. if (isMobile())global.device="mobile";
  42. else global.device="pc";
  43. global.width=width;
  44. global.height=height;
  45. }
  46. initWindowSize();
  47. const stopTransition = () => {
  48. page.classList.add('no-transition');
  49. setTimeout(() => page.classList.remove('no-transition'), 100);
  50. }
  51. const savePreferences = () => {
  52. localStorage.setItem('preferences', JSON.stringify({
  53. theme,
  54. fontScale,
  55. direction
  56. }));
  57. }
  58. const toggleTheme = () => {
  59. setTheme(theme === APP_THEME.LIGHT ? APP_THEME.DARK : APP_THEME.LIGHT);
  60. // stopTransition();
  61. }
  62. const changeFontScale = (scale) => {
  63. setFontScale(scale);
  64. stopTransition();
  65. }
  66. const toggleDirection = () => {
  67. setDirection(direction === 'ltr' ? 'rtl' : 'ltr');
  68. page.setAttribute('dir', direction);
  69. }
  70. const initHeaderHeight=(height)=>{
  71. setHeaderHeight(height);
  72. }
  73. const showGameSearchPanel=(show,data)=>{
  74. setIsShowSearch(show);
  75. setSearchData(data);
  76. }
  77. //检查提现
  78. const checkWithdraw=()=>{
  79. if (isLogin){
  80. if (user){
  81. let InsurePass=Number(user.InsurePass);
  82. if (InsurePass!==1){
  83. setIsShowPassPrompt(true);
  84. return false;
  85. }
  86. }
  87. }
  88. return true;
  89. }
  90. //检查路由是否允许跳转
  91. const checkRoute=(path)=>{
  92. if (path===ROUTE_PATH.SAQUE){
  93. return checkWithdraw();
  94. }
  95. return true;
  96. }
  97. useEffect(() => {
  98. page.style.setProperty('--font-scale', fontScale);
  99. // page.style.setProperty('--widget-scale', fontScale === 1 ? '0px' : `${fontScale * 3}px`);
  100. page.setAttribute('dir', direction);
  101. savePreferences();
  102. // window
  103. // .matchMedia('(prefers-color-scheme: light)')
  104. // .addEventListener('change', event => {
  105. // event.matches ? setTheme('light') : setTheme('dark');
  106. // stopTransition();
  107. // savePreferences();
  108. // })
  109. // eslint-disable-next-line react-hooks/exhaustive-deps
  110. }, [theme, fontScale, direction]);
  111. return (
  112. <ThemeContext.Provider
  113. value={{
  114. theme,
  115. fontScale,
  116. direction,
  117. toggleTheme,
  118. changeFontScale,
  119. toggleDirection,
  120. isDesktop,
  121. isTablet,
  122. isMobile,
  123. headerHeight,
  124. initHeaderHeight,
  125. isShowSearch,
  126. searchData,
  127. showGameSearchPanel,
  128. showHeader,
  129. setShowHeader,
  130. //lang
  131. isShowLang,
  132. setIsShowLang,
  133. isShowPassPrompt,
  134. setIsShowPassPrompt,
  135. //检查路由是否允许跳转
  136. checkRoute
  137. }}>
  138. {children}
  139. </ThemeContext.Provider>
  140. );
  141. }
  142. export const useThemeProvider = () => useContext(ThemeContext);