1
0

theme-store.js 4.5 KB

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