Skip to content

Commit

Permalink
feat: add localStorage helper
Browse files Browse the repository at this point in the history
  • Loading branch information
uniquemo committed May 14, 2020
1 parent d894774 commit 41f57e4
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 55 deletions.
16 changes: 8 additions & 8 deletions src/components/Layout/Footer/PlayMode/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from 'react'
import { Tooltip, Icon, IconName } from '@blueprintjs/core'

import { getPlayMode, MODE } from 'helpers/play'
import { PlayMusicDispatchContext, ACTIONS } from 'reducers/playMusic'
import { MODE } from 'helpers/play'
import { PlayMusicStateContext, PlayMusicDispatchContext, ACTIONS } from 'reducers/playMusic'

const MODE_ORDER = [MODE.PLAY_IN_ORDER, MODE.SINGLE_CYCLE, MODE.SHUFFLE_PLAYBACK]

Expand All @@ -24,16 +24,16 @@ const MODE_MAP: IDictionary<{
}
}

const { useState, useContext } = React
const { useContext } = React

const PlayMode = () => {
const dispatch = useContext(PlayMusicDispatchContext)
const [mode, setMode] = useState(getPlayMode())
const state = useContext(PlayMusicStateContext)
const { playMode } = state

const handleClick = () => {
const idx = MODE_ORDER.findIndex(m => m === mode)
const idx = MODE_ORDER.findIndex(m => m === playMode)
const nextMode = MODE_ORDER[(idx + 1) % (MODE_ORDER.length)]
setMode(nextMode)

dispatch({
type: ACTIONS.SET_PLAY_MODE,
Expand All @@ -44,8 +44,8 @@ const PlayMode = () => {
}

return (
<Tooltip content={MODE_MAP[mode].label}>
<Icon icon={MODE_MAP[mode].icon} onClick={handleClick} />
<Tooltip content={MODE_MAP[playMode].label}>
<Icon icon={MODE_MAP[playMode].icon} onClick={handleClick} />
</Tooltip>
)
}
Expand Down
14 changes: 11 additions & 3 deletions src/components/Layout/Header/Searcher/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import useAsyncFn from 'hooks/useAsyncFn'
import useClickAway from 'hooks/useClickAway'
import useQuery from 'hooks/useQuery'
import searchApis from 'apis/search'
import { setSearchHistory, getSearchHistory } from 'helpers/search'
import { setSearchHistory, searchHistoryLocalStorage } from 'helpers/search'
import { debounce } from 'helpers/fn'
import ROUTES from 'constants/routes'
import styles from './style.module.css'
Expand Down Expand Up @@ -88,8 +88,16 @@ const Searcher = () => {
<SearchResult data={searchResult} />
) : (
<div>
<Words title='热门搜索' words={state.value?.map(({ first }) => first)} onWordClick={handleWordClick} />
<Words title='搜索历史' words={getSearchHistory()} onWordClick={handleWordClick} />
<Words
title='热门搜索'
words={state.value?.map(({ first }) => first)}
onWordClick={handleWordClick}
/>
<Words
title='搜索历史'
words={searchHistoryLocalStorage.getItem()}
onWordClick={handleWordClick}
/>
</div>
)}
</div>
Expand Down
41 changes: 41 additions & 0 deletions src/helpers/localStorage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
export const DEFAULT_VALUE = {
ARRAY: '[]',
OBJECT: '{}',
STRING: ''
}

interface ILocalStorageFactoryParams<T> {
key: string,
defaultValue: string,
raw?: boolean,
serializer?: (value: T) => string,
deserializer?: (value: string) => T
}

interface ILocalStorageFactoryReturn<T> {
setItem: (value: T) => void,
getItem: () => T,
removeItem: () => void
}

export const localStorageFactory = <T>(params: ILocalStorageFactoryParams<T>): ILocalStorageFactoryReturn<T> => {
const { key, defaultValue, raw, serializer = JSON.stringify, deserializer = JSON.parse } = params

const setItem = (value: T) => {
const data = (raw ? value : serializer(value)) as string
window.localStorage.setItem(key, data || defaultValue)
}

const getItem = () => {
const data = window.localStorage.getItem(key) || defaultValue
return raw ? data : deserializer(data)
}

const removeItem = () => window.localStorage.removeItem(key)

return {
setItem,
getItem,
removeItem,
}
}
32 changes: 16 additions & 16 deletions src/helpers/play.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { DEFAULT_VALUE, localStorageFactory } from 'helpers/localStorage'
import { IMyMusic } from 'apis/types/business'

enum KEY {
Expand All @@ -6,38 +7,37 @@ enum KEY {
PLAY_MODE = '__playMode'
}

const DEFAULT_VALUE = '[]'
export const playHistory = localStorageFactory<IMyMusic[]>({
key: KEY.PLAY_HISTORY,
defaultValue: DEFAULT_VALUE.ARRAY
})

// play history
export const setPlayHistory = (music: IMyMusic): IMyMusic[] => {
const list = getPlayHistory().slice(0, 100)
const list = playHistory.getItem().slice(0, 100)
const index = list.findIndex((item) => item.id === music.id)

if (index > -1) {
list.splice(index, 1)
}

list.unshift(music)
window.localStorage.setItem(KEY.PLAY_HISTORY, JSON.stringify(list))
playHistory.setItem(list)

return list
}
export const getPlayHistory = (): IMyMusic[] => JSON.parse(window.localStorage.getItem(KEY.PLAY_HISTORY) || DEFAULT_VALUE)
export const removePlayHistory = () => window.localStorage.removeItem(KEY.PLAY_HISTORY)

// play list
export const setPlayList = (list: IMyMusic[]) => {
window.localStorage.setItem(KEY.PLAY_LIST, JSON.stringify(list))
}
export const getPlayList = (): IMyMusic[] => JSON.parse(window.localStorage.getItem(KEY.PLAY_LIST) || DEFAULT_VALUE)
export const removePlayList = () => window.localStorage.removeItem(KEY.PLAY_LIST)
export const playList = localStorageFactory<IMyMusic[]>({
key: KEY.PLAY_LIST,
defaultValue: DEFAULT_VALUE.ARRAY
})

// play mode
export enum MODE {
PLAY_IN_ORDER = 'PLAY_IN_ORDER',
SINGLE_CYCLE = 'SINGLE_CYCLE',
SHUFFLE_PLAYBACK = 'SHUFFLE_PLAYBACK'
}
export const setPlayMode = (mode: MODE = MODE.PLAY_IN_ORDER) => window.localStorage.setItem(KEY.PLAY_MODE, mode)
export const getPlayMode = (): MODE => (window.localStorage.getItem(KEY.PLAY_MODE) as MODE) || MODE.PLAY_IN_ORDER
export const removePlayMode = () => window.localStorage.removeItem(KEY.PLAY_MODE)
export const playMode = localStorageFactory<MODE>({
key: KEY.PLAY_MODE,
defaultValue: MODE.PLAY_IN_ORDER,
raw: true
})
17 changes: 11 additions & 6 deletions src/helpers/search.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import { DEFAULT_VALUE, localStorageFactory } from './localStorage'

const KEY = '__searchHistory'

export const searchHistoryLocalStorage = localStorageFactory<string[]>({
key: KEY,
defaultValue: DEFAULT_VALUE.ARRAY,
})

export const setSearchHistory = (keyword: string) => {
keyword = keyword.trim()
if (!keyword) {
return
}

let data: string[] = getSearchHistory()
let data: string[] = searchHistoryLocalStorage.getItem()
data = data.slice(0, 10)

const index = data.findIndex(key => key === keyword)
Expand All @@ -14,9 +23,5 @@ export const setSearchHistory = (keyword: string) => {
}

data.unshift(keyword)
window.localStorage.setItem('__searchHistory', JSON.stringify(data))
searchHistoryLocalStorage.setItem(data)
}

export const removeSearchHistory = () => window.localStorage.removeItem('__searchHistory')

export const getSearchHistory = (): string[] => JSON.parse(window.localStorage.getItem('__searchHistory') || '[]')
10 changes: 6 additions & 4 deletions src/helpers/session.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { DEFAULT_VALUE, localStorageFactory } from './localStorage'
import { ILoginResult } from 'apis/types/auth'

export const setSession = (session: ILoginResult) => window.localStorage.setItem('__session', JSON.stringify(session))
const KEY = '__session'

export const removeSession = () => window.localStorage.removeItem('__session')

export const getSession = (): ILoginResult => JSON.parse(window.localStorage.getItem('__session') || '{}')
export const sessionLocalStorage = localStorageFactory<ILoginResult>({
key: KEY,
defaultValue: DEFAULT_VALUE.OBJECT
})
8 changes: 4 additions & 4 deletions src/reducers/log.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react'

import { getSession, setSession, removeSession } from 'helpers/session'
import { sessionLocalStorage } from 'helpers/session'
import { IAction } from './types'
import { ILoginResult } from 'apis/types/auth'

Expand All @@ -17,7 +17,7 @@ export interface IState {
user: ILoginResult
}

const session = getSession()
const session = sessionLocalStorage.getItem()

export const initialState = {
isLogined: !!session.userId,
Expand All @@ -27,7 +27,7 @@ export const initialState = {
const logReducer = (state: IState, action: IAction) => {
switch (action.type) {
case ACTIONS.LOGIN: {
setSession(action.payload?.user)
sessionLocalStorage.setItem(action.payload?.user)

return {
...state,
Expand All @@ -36,7 +36,7 @@ const logReducer = (state: IState, action: IAction) => {
}
}
case ACTIONS.LOGOUT: {
removeSession()
sessionLocalStorage.removeItem()

return {
...state,
Expand Down
24 changes: 10 additions & 14 deletions src/reducers/playMusic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,11 @@ import { IMyMusic } from 'apis/types/business'
import { HTMLMediaState, HTMLMediaControls } from 'hooks/utils/createHTMLMediaHook'
import { getMusicUrl } from 'helpers/business'
import {
setPlayList,
getPlayList,
removePlayList,
MODE,
getPlayMode,
setPlayMode,
setPlayHistory,
getPlayHistory,
removePlayHistory
playHistory as playHistoryLocalStorage,
playMode as playModeLocalStorage,
playList as playListLocalStorage
} from 'helpers/play'
import { IAction } from './types'

Expand Down Expand Up @@ -49,9 +45,9 @@ export interface IState {
export const initialState = {
musicId: 0,
musicUrl: '',
playList: getPlayList(),
playHistory: getPlayHistory(),
playMode: getPlayMode(),
playList: playListLocalStorage.getItem(),
playHistory: playHistoryLocalStorage.getItem(),
playMode: playModeLocalStorage.getItem(),
showLyric: false
}

Expand All @@ -73,23 +69,23 @@ const playMusicReducer = (state: IState, { type, payload }: IAction) => {
}
case ACTIONS.SET_PLAY_LIST: {
const playList = payload?.playList || []
setPlayList(playList)
playListLocalStorage.setItem(playList)

return {
...state,
playList
}
}
case ACTIONS.CLEAR_PLAY_LIST: {
removePlayList()
playListLocalStorage.removeItem()

return {
...state,
playList: []
}
}
case ACTIONS.SET_PLAY_MODE: {
setPlayMode(payload?.playMode)
playModeLocalStorage.setItem(payload?.playMode)

return {
...state,
Expand All @@ -109,7 +105,7 @@ const playMusicReducer = (state: IState, { type, payload }: IAction) => {
}
}
case ACTIONS.CLEAR_PLAY_HISTORY: {
removePlayHistory()
playHistoryLocalStorage.removeItem()

return {
...state,
Expand Down

0 comments on commit 41f57e4

Please sign in to comment.