Skip to content

Commit

Permalink
feat: support quiet update audio list #148 #114
Browse files Browse the repository at this point in the history
  • Loading branch information
lijinke666 committed Aug 31, 2020
1 parent c3c40b3 commit c98105b
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 72 deletions.
2 changes: 2 additions & 0 deletions __tests__/tests/__snapshots__/locale.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ exports[`Locale test should render default locale with en_US 1`] = `
playModeShowTime={600}
playModeTipVisible={false}
preload={false}
quietUpdate={false}
remember={false}
remove={true}
responsive={true}
Expand Down Expand Up @@ -759,6 +760,7 @@ exports[`Locale test should render locale with zh_CN 1`] = `
playModeShowTime={600}
playModeTipVisible={false}
preload={false}
quietUpdate={false}
remember={false}
remove={true}
responsive={true}
Expand Down
54 changes: 53 additions & 1 deletion example/example.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,33 @@ const audioList2 = [
},
]

const audioList3 = [
{
name: 'Despacito',
singer: 'Luis Fonsi',
cover:
'http://res.cloudinary.com/alick/image/upload/v1502689731/Despacito_uvolhp.jpg',
musicSrc:
'http://res.cloudinary.com/alick/video/upload/v1502689683/Luis_Fonsi_-_Despacito_ft._Daddy_Yankee_uyvqw9.mp3',
},
{
name: 'Bedtime Stories',
singer: 'Jay Chou',
cover:
'http://res.cloudinary.com/alick/image/upload/v1502375978/bedtime_stories_bywggz.jpg',
musicSrc:
'http://res.cloudinary.com/alick/video/upload/v1502375674/Bedtime_Stories.mp3',
},
{
name: 'Dorost Nemisham',
singer: 'Sirvan Khosravi',
cover:
'https://res.cloudinary.com/ehsanahmadi/image/upload/v1573758778/Sirvan-Khosravi-Dorost-Nemisham_glicks.jpg',
musicSrc:
'https://res.cloudinary.com/ehsanahmadi/video/upload/v1573550770/Sirvan-Khosravi-Dorost-Nemisham-128_kb8urq.mp3',
},
]

const options = {
// audio lists model
audioLists: audioList1,
Expand Down Expand Up @@ -437,7 +464,19 @@ class Demo extends React.PureComponent {
}

onChangeToSecondAudioList = () => {
this.updateParams({ clearPriorAudioLists: true, audioLists: audioList2 })
this.updateParams({
clearPriorAudioLists: true,
// quietUpdate: true,
audioLists: audioList2,
})
}

onQuietUpdateAudioList = () => {
this.updateParams({
clearPriorAudioLists: true,
quietUpdate: true,
audioLists: audioList3,
})
}

onAutoPlayMode = () => {
Expand Down Expand Up @@ -659,6 +698,10 @@ class Demo extends React.PureComponent {
<button type="button" onClick={this.onChangeToSecondAudioList}>
change to second audio list ({audioList2.length})
</button>
<button type="button" onClick={this.onQuietUpdateAudioList}>
quiet update audio list (don't interrupt current play state) (
{audioList3.length})
</button>
<button type="button" onClick={this.onAddAudio}>
+ add audio ({params.audioLists.length})
</button>
Expand Down Expand Up @@ -885,6 +928,15 @@ class Demo extends React.PureComponent {
/>
autoHiddenCover
</label>
<label htmlFor="quietUpdate">
<input
type="checkbox"
id="quietUpdate"
checked={params.quietUpdate}
onChange={() => this.onChangeKey('quietUpdate')}
/>
quietUpdate
</label>
<div className="toggle">
theme :{params.theme}
<Switch
Expand Down
1 change: 1 addition & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ export interface ReactJkMusicPlayerProps {
bottom?: number | string,
},
responsive?: boolean,
quietUpdate?: boolean,
onAudioPlay?: (audioInfo: ReactJkMusicPlayerAudioInfo) => void,
onAudioPause?: (audioInfo: ReactJkMusicPlayerAudioInfo) => void,
onAudioEnded?: (
Expand Down
1 change: 1 addition & 0 deletions src/config/propTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,5 @@ export default {
customDownloader: PropTypes.func,
audioTitle: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
responsive: PropTypes.bool,
quietUpdate: PropTypes.bool,
}
175 changes: 104 additions & 71 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ export default class ReactJkMusicPlayer extends PureComponent {
locale: LOCALE.en_US,
responsive: true,
icon: DEFAULT_ICON,
quietUpdate: false, // 更新后的播放列表如果有当前正在播放的歌曲不打断当前播放状态
}

static propTypes = PROP_TYPES
Expand Down Expand Up @@ -816,12 +817,14 @@ export default class ReactJkMusicPlayer extends PureComponent {
this.props.onPlayIndexChange && this.props.onPlayIndexChange(playIndex)
}

switch (typeof musicSrc) {
case 'function':
musicSrc().then(loadAudio, this.onAudioError)
break
default:
loadAudio(musicSrc)
if (!this.checkCurrentPlayingAudioIsInUpdatedAudioLists()) {
switch (typeof musicSrc) {
case 'function':
musicSrc().then(loadAudio, this.onAudioError)
break
default:
loadAudio(musicSrc)
}
}
}

Expand Down Expand Up @@ -1402,6 +1405,7 @@ export default class ReactJkMusicPlayer extends PureComponent {
const mergedAudioInfo = { ...e, ...audioInfo }
this.props.onAudioAbort &&
this.props.onAudioAbort(playId, audioLists, mergedAudioInfo)

if (audioLists.length) {
this.audio.pause()
this.state.isInitAutoPlay && this.audio.play()
Expand Down Expand Up @@ -1500,6 +1504,20 @@ export default class ReactJkMusicPlayer extends PureComponent {
}
}

checkCurrentPlayingAudioIsInUpdatedAudioLists = (nextProps = this.props) => {
const { playId, audioLists } = this.state
if (
!nextProps.quietUpdate ||
!Array.isArray(nextProps.audioLists) ||
nextProps.audioLists.length !== audioLists.length
) {
return false
}

// FIXME: 比较更新之后有没有当前正在播放的这首歌
return playId && nextProps.audioLists.some(({ id }) => id === playId)
}

mockAutoPlayForMobile = () => {
if (this.props.autoPlay && !this.state.playing && this.state.pause) {
this.audio.load()
Expand Down Expand Up @@ -1610,11 +1628,16 @@ export default class ReactJkMusicPlayer extends PureComponent {

// I change the name of getPlayInfo to getPlayInfoOfNewList because i didn't want to change the prior changes
// the only thing this function does is to add id to audiolist elements.
getPlayInfoOfNewList = (audioLists = []) => {
const _audioLists = audioLists.map((info) => {
getPlayInfoOfNewList = (nextProps) => {
const { audioLists = [] } = nextProps
const _audioLists = audioLists.map((info, i) => {
const currentPlayIdBeforeUpdate =
this.state.playIndex === i &&
this.checkCurrentPlayingAudioIsInUpdatedAudioLists(nextProps) &&
this.state.playId
return {
...info,
id: uuId(),
id: currentPlayIdBeforeUpdate || uuId(),
}
})

Expand Down Expand Up @@ -1773,57 +1796,67 @@ export default class ReactJkMusicPlayer extends PureComponent {
)
}

loadNewAudioLists = ({
audioLists,
remember,
playMode,
theme,
autoPlayInitLoadPlayList,
playIndex,
}) => {
if (audioLists.length >= 1) {
const info = this.getPlayInfoOfNewList(audioLists)
const lastPlayStatus = remember
? this.getLastPlayStatus()
: {
playMode: playMode || PLAY_MODE.order,
playIndex: playIndex || 0,
}
loadNewAudioLists = (nextProps) => {
const {
audioLists,
remember,
playMode,
theme,
autoPlayInitLoadPlayList,
playIndex,
} = nextProps
if (!Array.isArray(audioLists) || !audioLists.length) {
return
}
const info = this.getPlayInfoOfNewList(nextProps)
const lastPlayStatus = remember
? this.getLastPlayStatus()
: {
playMode: playMode || PLAY_MODE.order,
playIndex: playIndex || 0,
}

if (theme !== THEME.AUTO) {
lastPlayStatus.theme = theme
}
if (theme !== THEME.AUTO) {
lastPlayStatus.theme = theme
}

const audioInfo = {
...info,
...lastPlayStatus,
isInitAutoPlay: autoPlayInitLoadPlayList,
}
switch (typeof info.musicSrc) {
case 'function':
info.musicSrc().then((musicSrc) => {
this.setState(
{
...audioInfo,
musicSrc,
},
() => {
this.audio.load()
},
)
}, this.onAudioError)
break
default:
this.setState(audioInfo, () => {
// 预加载, 防止非自动播放, 直接点击播放列表无法播放的情况
this.audio.load()
})
}
const audioInfo = {
...info,
...lastPlayStatus,
isInitAutoPlay: autoPlayInitLoadPlayList,
}

if (this.checkCurrentPlayingAudioIsInUpdatedAudioLists(nextProps)) {
this.setState({ audioLists: info.audioLists })
return
}

switch (typeof info.musicSrc) {
case 'function':
info.musicSrc().then((musicSrc) => {
this.setState(
{
...audioInfo,
musicSrc,
},
() => {
this.audio.load()
},
)
}, this.onAudioError)
break
default:
this.setState(audioInfo, () => {
// 预加载, 防止非自动播放, 直接点击播放列表无法播放的情况
this.audio.load()
})
}
}

changeAudioLists = (nextProps) => {
this.resetAudioStatus()
if (!this.checkCurrentPlayingAudioIsInUpdatedAudioLists(nextProps)) {
this.resetAudioStatus()
}
this.loadNewAudioLists(nextProps)
this.props.onAudioListsChange &&
this.props.onAudioListsChange(
Expand Down Expand Up @@ -2039,24 +2072,22 @@ export default class ReactJkMusicPlayer extends PureComponent {
audioLists = this.props.audioLists,
isBindKeyDownEvents = true,
) => {
if (!Array.isArray(audioLists)) {
if (!Array.isArray(audioLists) || !audioLists.length) {
return
}
if (audioLists.length) {
this.setDefaultAudioVolume()
this.bindUnhandledRejection()
this.bindEvents(this.audio)
this.initLyricParser()
this.onAddMediaSession()
if (IS_MOBILE) {
this.bindMobileAutoPlayEvents()
} else {
if (isBindKeyDownEvents) {
this.bindKeyDownEvents()
}
if (isSafari()) {
this.bindSafariAutoPlayEvents()
}
this.setDefaultAudioVolume()
this.bindUnhandledRejection()
this.bindEvents(this.audio)
this.initLyricParser()
this.onAddMediaSession()
if (IS_MOBILE) {
this.bindMobileAutoPlayEvents()
} else {
if (isBindKeyDownEvents) {
this.bindKeyDownEvents()
}
if (isSafari()) {
this.bindSafariAutoPlayEvents()
}
}
}
Expand Down Expand Up @@ -2093,7 +2124,9 @@ export default class ReactJkMusicPlayer extends PureComponent {
} else {
this.updateAudioLists(audioLists)
}
this.initPlayer(audioLists, false)
if (!this.checkCurrentPlayingAudioIsInUpdatedAudioLists(nextProps)) {
this.initPlayer(audioLists, false)
}
}
this.updatePlayIndex(playIndex)
this.updateTheme(theme)
Expand Down

0 comments on commit c98105b

Please sign in to comment.