Skip to content

Commit

Permalink
perf: use hook for Layout Footer, add requestAnimationFrame
Browse files Browse the repository at this point in the history
  • Loading branch information
uniquemo committed May 15, 2020
1 parent 96b7f33 commit 3c50e82
Show file tree
Hide file tree
Showing 13 changed files with 159 additions and 129 deletions.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@
"lyric",
"banner",
"typescript",
"eslint"
"eslint",
"网易云",
"音乐",
"网易云音乐"
],
"author": "",
"license": "ISC",
Expand Down
9 changes: 7 additions & 2 deletions src/components/Layout/Footer/AudioTimer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,19 @@ import React from 'react'
import { AudioContext } from 'reducers/playMusic'
import { formatTime } from 'helpers/time'

const { useContext } = React
const { useContext, useMemo } = React

const AudioTimer = () => {
const audioInfo = useContext(AudioContext)
const { state } = audioInfo

const time = useMemo(() => {
return `${formatTime(state?.time)} / ${formatTime(state?.duration)}`
}, [state?.time, state?.duration])

return (
<div>
{formatTime(audioInfo?.state?.time)} / {formatTime(audioInfo?.state?.duration)}
{time}
</div>
)
}
Expand Down
6 changes: 3 additions & 3 deletions src/components/Layout/Footer/PlayMode/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ const MODE_MAP: IDictionary<{
}
}

const { useContext } = React
const { useContext, useCallback } = React

const PlayMode = () => {
const dispatch = useContext(PlayMusicDispatchContext)
const state = useContext(PlayMusicStateContext)
const { playMode } = state

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

Expand All @@ -41,7 +41,7 @@ const PlayMode = () => {
playMode: nextMode
}
})
}
}, [dispatch, playMode])

return (
<Tooltip content={MODE_MAP[playMode].label}>
Expand Down
24 changes: 13 additions & 11 deletions src/components/Layout/Footer/PlayOperations/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,27 @@ import { PlayMusicStateContext, PlayMusicDispatchContext, AudioContext, ACTIONS
import { playList as playListLocalStorage } from 'helpers/play'
import styles from './style.module.css'

const { useContext, useMemo } = React
const { useContext, useMemo, useCallback } = React

const PlayOperations = () => {
const audioInfo = useContext(AudioContext)
const state = useContext(PlayMusicStateContext)
const { state: audioState, controls } = audioInfo

const dispatch = useContext(PlayMusicDispatchContext)
const state = useContext(PlayMusicStateContext)
const { musicId } = state

const playList = useMemo(() => playListLocalStorage.getItem(), [musicId])

const togglePlayStatus = () => {
if (audioInfo.state?.paused) {
audioInfo.controls?.play()
const togglePlayStatus = useCallback(() => {
if (audioState?.paused) {
controls?.play()
} else {
audioInfo.controls?.pause()
controls?.pause()
}
}
}, [audioState?.paused, controls])

const play = (prev?: boolean) => {
const play = useCallback((prev?: boolean) => {
const len = playList.length
if (!len) {
return
Expand All @@ -45,10 +47,10 @@ const PlayOperations = () => {
music: playList[nextIndex]
}
})
}
}, [playList, musicId, dispatch])

const playPrev = () => play(true)
const playNext = () => play()
const playPrev = useCallback(() => play(true), [play])
const playNext = useCallback(() => play(), [play])

return (
<>
Expand Down
36 changes: 19 additions & 17 deletions src/components/Layout/Footer/PlayRecord/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,25 @@ const PlayRecord: React.FC<IProps> = ({ show, onClickAway }) => {

return (
<div className={cn(styles.root, show && styles.show)} ref={ref => playRecordRef.current = ref}>
<div className={styles.tabs}>
{Object.keys(TABS).map((key) => {
return (
<div
key={key}
className={cn(styles.tab, activeTab === key && styles.active)}
onClick={() => setActiveTab(TABS[key].tabKey)}
>
{TABS[key].tab}
</div>
)
})}
</div>

<div className={styles.content}>
{activeTab === TABS.PLAY_LIST.tabKey ? <PlayList /> : <PlayHistory />}
</div>
{show && <>
<div className={styles.tabs}>
{Object.keys(TABS).map((key) => {
return (
<div
key={key}
className={cn(styles.tab, activeTab === key && styles.active)}
onClick={() => setActiveTab(TABS[key].tabKey)}
>
{TABS[key].tab}
</div>
)
})}
</div>

<div className={styles.content}>
{activeTab === TABS.PLAY_LIST.tabKey ? <PlayList /> : <PlayHistory />}
</div>
</>}
</div>
)
}
Expand Down
13 changes: 8 additions & 5 deletions src/components/Layout/Footer/PlayVolume/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@ import ProgressBar from 'components/ProgressBar'
import { AudioContext } from 'reducers/playMusic'
import styles from './style.module.css'

const { useContext } = React
const { useContext, useMemo, useCallback } = React

const PlayVolume = () => {
const audioInfo = useContext(AudioContext)
const { state, controls } = audioInfo

const handleBarClick = (percent: number) => {
audioInfo.controls?.volume(percent)
}
const handleBarClick = useCallback((percent: number) => {
controls?.volume(percent)
}, [controls])

const donePercent = Number((audioInfo.state?.volume || 0).toFixed(2))
const donePercent = useMemo(() => {
return Number((state?.volume || 0).toFixed(2))
}, [state?.volume])

return (
<div className={styles.root}>
Expand Down
25 changes: 17 additions & 8 deletions src/components/Layout/Footer/ProgressBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,31 @@ import BaseProgressBar from 'components/ProgressBar'
import { formatTime } from 'helpers/time'
import { AudioContext } from 'reducers/playMusic'

const { useContext } = React
const { useContext, useMemo, useCallback } = React

const ProgressBar = () => {
const audioInfo = useContext(AudioContext)
const { state, controls } = audioInfo

const donePercent = audioInfo.state?.duration
? (audioInfo.state?.time / audioInfo.state.duration)
: 0
const donePercent = useMemo(() => {
return state?.duration
? (state?.time / state.duration)
: 0
}, [state?.time, state?.duration])

const renderLabel = useCallback(() => {
return formatTime(state?.time)
}, [state?.time])

const handleBarClick = useCallback((percent) => {
controls?.seek((state?.duration || 0) * percent)
}, [controls, state?.duration])

return (
<BaseProgressBar
donePercent={donePercent}
renderLabel={() => formatTime(audioInfo.state?.time)}
onBarClick={(percent) => {
audioInfo.controls?.seek((audioInfo.state?.duration || 0) * percent)
}}
renderLabel={renderLabel}
onBarClick={handleBarClick}
/>
)
}
Expand Down
24 changes: 12 additions & 12 deletions src/components/Layout/Footer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,29 @@ import PlayVolume from './PlayVolume'
import { PlayMusicStateContext, PlayMusicDispatchContext, ACTIONS } from 'reducers/playMusic'
import styles from './style.module.css'

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

const Footer = () => {
const [showPlayRecord, setShowPlayRecord] = useState(false)
const dispatch = useContext(PlayMusicDispatchContext)
const state = useContext(PlayMusicStateContext)
const { musicId, music, showLyric } = state

const togglePlayRecord = () => setShowPlayRecord(!showPlayRecord)
const togglePlayRecord = useCallback(() => {
setShowPlayRecord(!showPlayRecord)
}, [showPlayRecord, setShowPlayRecord])

const handleShowLyric = () => {
const handleShowLyric = useCallback(() => {
dispatch({
type: ACTIONS.SHOW_LYRIC
})
}
}, [dispatch])

const handleHideLyric = () => {
const handleHideLyric = useCallback(() => {
dispatch({
type: ACTIONS.HIDE_LYRIC
})
}
}, [dispatch])

return (
<div className={styles.root}>
Expand Down Expand Up @@ -83,12 +85,10 @@ const Footer = () => {
</div>
</div>

{showPlayRecord && (
<PlayRecord
show={showPlayRecord}
onClickAway={() => setShowPlayRecord(false)}
/>
)}
<PlayRecord
show={showPlayRecord}
onClickAway={() => setShowPlayRecord(false)}
/>
</div>
)
}
Expand Down
38 changes: 20 additions & 18 deletions src/components/Layout/Sidebar/MusicDetail/Lyric/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { formatLyric } from 'helpers/lyric'
import { PlayMusicStateContext, AudioContext } from 'reducers/playMusic'
import styles from './style.module.css'

const { useEffect, useContext, useRef, useState } = React
const { useEffect, useContext, useRef, useState, useMemo } = React

const HIGHLIGHT_LYRIC_TOP = 160
const LYRIC_LINE_HEIGHT = 30
Expand All @@ -22,7 +22,7 @@ const Lyric = () => {
const { musicId, showLyric } = state

const [lyricState, getLyricFn] = useAsyncFn(songApis.getLyric)
const lines = formatLyric(lyricState.value?.lyric)
const lines = useMemo(() => formatLyric(lyricState.value?.lyric), [lyricState.value?.lyric])

useEffect(() => {
if (musicId && showLyric) {
Expand All @@ -32,26 +32,28 @@ const Lyric = () => {

useEffect(() => {
if (!audioInfo.state?.paused) {
const audioTime = audioInfo.state?.time || 0
window.requestAnimationFrame(() => {
const audioTime = audioInfo.state?.time || 0

const lineIndex = lines.findIndex(([time], index) => {
const prevTime = index - 1 >= 0 ? lines[index - 1][0] : time
const nextTime = index + 1 < lines.length ? lines[index + 1][0] : time
if (prevTime <= audioTime && nextTime >= audioTime) {
return true
const lineIndex = lines.findIndex(([time], index) => {
const prevTime = index - 1 >= 0 ? lines[index - 1][0] : time
const nextTime = index + 1 < lines.length ? lines[index + 1][0] : time
if (prevTime <= audioTime && nextTime >= audioTime) {
return true
}
})

if (lineIndex > -1) {
const scrollHeight = LYRIC_LINE_HEIGHT * lineIndex - HIGHLIGHT_LYRIC_TOP
lyricRef.current?.scrollTo({
top: scrollHeight < 0 ? 0 : scrollHeight,
behavior: 'smooth'
})
setLine(lineIndex)
}
})

if (lineIndex > -1) {
const scrollHeight = LYRIC_LINE_HEIGHT * lineIndex - HIGHLIGHT_LYRIC_TOP
lyricRef.current?.scrollTo({
top: scrollHeight < 0 ? 0 : scrollHeight,
behavior: 'smooth'
})
setLine(lineIndex)
}
}
}, [audioInfo.state])
}, [audioInfo.state, lines])

return (
<div className={styles.root} ref={ref => lyricRef.current = ref}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@
}

.playCount {
color: tipsColor;
color: tipsColor !important;
}

0 comments on commit 3c50e82

Please sign in to comment.