diff --git a/apps/pwa/src/app/index.tsx b/apps/pwa/src/app/index.tsx index f491cd1c..a0c29d8f 100644 --- a/apps/pwa/src/app/index.tsx +++ b/apps/pwa/src/app/index.tsx @@ -5,8 +5,8 @@ import { ThemeProvider } from 'styled-components'; import { HashRouter } from 'react-router-dom'; import App from './app'; import UncaughtError from './uncaught_error'; -import theme from '../global_states/theme'; import Head from './head'; +import { useTheme } from '@/global_states/theme'; const fallback = (error: Error) => ; @@ -14,7 +14,7 @@ function Wrapper() { return ( - + diff --git a/apps/pwa/src/global_states/theme/index.ts b/apps/pwa/src/global_states/theme/index.ts index 8bf02edd..a5b66b5d 100644 --- a/apps/pwa/src/global_states/theme/index.ts +++ b/apps/pwa/src/global_states/theme/index.ts @@ -1,30 +1,26 @@ import { MINI_MODE_MAX_WIDTH } from '@/constants'; -import XState from '@/utils/x_state'; import throttle from 'lodash/throttle'; import scrollbarObserver from './scrollbar_observer'; -import type { DefaultTheme } from 'styled-components'; +import { create } from 'zustand'; +import { Theme } from '@/styled'; -const theme = new XState({ +export const useTheme = create(() => ({ miniMode: window.innerWidth <= MINI_MODE_MAX_WIDTH, autoScrollbar: scrollbarObserver.getScrollbarWidth() === 0, -}); +})); window.addEventListener( 'resize', throttle( () => - theme.set((t) => ({ - ...t, + useTheme.setState({ miniMode: window.innerWidth <= MINI_MODE_MAX_WIDTH, - })), + }), 300, ), ); scrollbarObserver.onChange(() => - theme.set((t) => ({ - ...t, + useTheme.setState({ autoScrollbar: scrollbarObserver.getScrollbarWidth() === 0, - })), + }), ); - -export default theme; diff --git a/apps/pwa/src/global_states/theme/scrollbar_observer.ts b/apps/pwa/src/global_states/theme/scrollbar_observer.ts index 23fe9801..0fbb7908 100644 --- a/apps/pwa/src/global_states/theme/scrollbar_observer.ts +++ b/apps/pwa/src/global_states/theme/scrollbar_observer.ts @@ -3,16 +3,16 @@ import Eventin from 'eventin'; enum EventType { RESIZE = 'resize', } -type EventTypeMapData = { +interface EventTypeMapData { [EventType.RESIZE]: null; -}; +} export default new (class { outer: HTMLDivElement; inner: HTMLDivElement; - private eventemitter: Eventin; + private readonly eventemitter: Eventin; constructor() { this.eventemitter = new Eventin(); diff --git a/apps/pwa/src/pages/player/controller/controller.tsx b/apps/pwa/src/pages/player/controller/controller.tsx index 795ef3b0..90089aa1 100644 --- a/apps/pwa/src/pages/player/controller/controller.tsx +++ b/apps/pwa/src/pages/player/controller/controller.tsx @@ -1,5 +1,4 @@ import styled, { css } from 'styled-components'; -import theme from '@/global_states/theme'; import { useContext } from 'react'; import getResizedImage from '@/server/asset/get_resized_image'; import { type QueueMusic, ZIndex } from '../constants'; @@ -12,6 +11,7 @@ import Context from '../context'; import playerEventemitter, { EventType as PlayerEventType, } from '../eventemitter'; +import { useTheme } from '@/global_states/theme'; const toggleLyric = () => playerEventemitter.emit(PlayerEventType.TOGGLE_LYRIC_PANEL, { open: true }); @@ -68,7 +68,7 @@ function Controller() { | QueueMusic | undefined; - const { miniMode } = theme.useState(); + const { miniMode } = useTheme(); return (