theme-store.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. const settingsService = require('./settings-store.js')
  2. const {
  3. getWxApi
  4. } = require('../utils/platform-utils.js')
  5. const TAB_ITEMS = [
  6. {
  7. pagePath: 'pages/home/home',
  8. text: '首页',
  9. iconPath: 'assets/tab/home.png',
  10. selectedIconPath: 'assets/tab/home-active.png',
  11. darkIconPath: 'assets/tab/home-dark.png',
  12. darkSelectedIconPath: 'assets/tab/home-active-dark.png'
  13. },
  14. {
  15. pagePath: 'pages/params/params',
  16. text: '参数',
  17. iconPath: 'assets/tab/params.png',
  18. selectedIconPath: 'assets/tab/params-active.png',
  19. darkIconPath: 'assets/tab/params-dark.png',
  20. darkSelectedIconPath: 'assets/tab/params-active-dark.png'
  21. },
  22. {
  23. pagePath: 'pages/settings/settings',
  24. text: '设置',
  25. iconPath: 'assets/tab/settings.png',
  26. selectedIconPath: 'assets/tab/settings-active.png',
  27. darkIconPath: 'assets/tab/settings-dark.png',
  28. darkSelectedIconPath: 'assets/tab/settings-active-dark.png'
  29. }
  30. ]
  31. const state = {
  32. themeMode: 'light',
  33. themeClass: ''
  34. }
  35. let initialized = false
  36. let unsubscribeSettings = null
  37. const subscribers = []
  38. function normalizeTheme(theme) {
  39. return theme === 'dark' ? 'dark' : (theme === 'light' ? 'light' : '')
  40. }
  41. function getSystemTheme() {
  42. try {
  43. const wxApi = getWxApi()
  44. const appBaseInfo = typeof wxApi.getAppBaseInfo === 'function' ? wxApi.getAppBaseInfo() : {}
  45. const appTheme = normalizeTheme(appBaseInfo.theme)
  46. if (appTheme) return appTheme
  47. const systemInfo = typeof wxApi.getSystemInfoSync === 'function' ? wxApi.getSystemInfoSync() : {}
  48. const systemTheme = normalizeTheme(systemInfo.theme)
  49. if (systemTheme) return systemTheme
  50. const windowInfo = typeof wxApi.getWindowInfo === 'function' ? wxApi.getWindowInfo() : {}
  51. const windowTheme = normalizeTheme(windowInfo.theme)
  52. if (windowTheme) return windowTheme
  53. return 'light'
  54. } catch (error) {
  55. return 'light'
  56. }
  57. }
  58. function getThemeState(themeMode) {
  59. const isDark = themeMode === 'dark'
  60. return {
  61. themeClass: isDark ? 'theme-dark' : '',
  62. themeMode: isDark ? 'dark' : 'light'
  63. }
  64. }
  65. function getEffectiveThemeMode() {
  66. const settings = settingsService.getState()
  67. if (settings.nightModeFollowSystem) return getSystemTheme()
  68. return settings.nightModeEnabled ? 'dark' : 'light'
  69. }
  70. function setState(nextState) {
  71. Object.assign(state, nextState)
  72. applyTabBarStyle()
  73. subscribers.slice().forEach((subscriber) => {
  74. subscriber(getState())
  75. })
  76. }
  77. function refreshThemeState() {
  78. setState(getThemeState(getEffectiveThemeMode()))
  79. }
  80. function applyTabBarStyle() {
  81. const wxApi = getWxApi()
  82. if (typeof wxApi.setTabBarStyle !== 'function') return
  83. const isDark = state.themeMode === 'dark'
  84. try {
  85. wxApi.setTabBarStyle({
  86. backgroundColor: isDark ? '#111827' : '#ffffff',
  87. borderStyle: isDark ? 'white' : 'black',
  88. color: isDark ? '#94a3b8' : '#64748b',
  89. selectedColor: isDark ? '#5eead4' : '#0f766e'
  90. })
  91. if (typeof wxApi.setTabBarItem === 'function') {
  92. TAB_ITEMS.forEach((item, index) => {
  93. wxApi.setTabBarItem({
  94. index,
  95. pagePath: item.pagePath,
  96. text: item.text,
  97. iconPath: isDark ? item.darkIconPath : item.iconPath,
  98. selectedIconPath: isDark ? item.darkSelectedIconPath : item.selectedIconPath
  99. })
  100. })
  101. }
  102. } catch (error) {}
  103. }
  104. function init() {
  105. settingsService.init()
  106. if (!unsubscribeSettings) {
  107. unsubscribeSettings = settingsService.subscribe(() => {
  108. refreshThemeState()
  109. })
  110. }
  111. refreshThemeState()
  112. if (initialized) return
  113. const wxApi = getWxApi()
  114. if (typeof wxApi.onThemeChange === 'function') {
  115. wxApi.onThemeChange((res) => {
  116. if (!settingsService.getState().nightModeFollowSystem) return
  117. setState(getThemeState(normalizeTheme(res && res.theme) || getSystemTheme()))
  118. })
  119. }
  120. initialized = true
  121. }
  122. function getState() {
  123. return {
  124. ...state
  125. }
  126. }
  127. function subscribe(subscriber) {
  128. if (typeof subscriber !== 'function') return () => {}
  129. subscribers.push(subscriber)
  130. subscriber(getState())
  131. return () => {
  132. const index = subscribers.indexOf(subscriber)
  133. if (index >= 0) subscribers.splice(index, 1)
  134. }
  135. }
  136. function syncWithSystemTheme() {
  137. init()
  138. refreshThemeState()
  139. }
  140. module.exports = {
  141. getState,
  142. init,
  143. subscribe,
  144. syncWithSystemTheme
  145. }