diff --git a/src/common/js/cache.js b/src/common/js/cache.js index be947bb..ea77f2e 100644 --- a/src/common/js/cache.js +++ b/src/common/js/cache.js @@ -49,6 +49,28 @@ export function loadPlay() { return storage.get(PLAY_KEY, []) } +export function saveFavorite(song) { + let songs = storage.get(FAVORITE_KEY, []) + insertArr(songs, song, (item) => { + return song.id === item.id + }, FAVORITE_MAX_LEN) + storage.set(FAVORITE_KEY, songs) + return songs +} + +export function deleteFavorite(song) { + let songs = storage.get(FAVORITE_KEY, []) + deleteFromArr(songs, (item) => { + return item.id === song.id + }) + storage.set(FAVORITE_KEY, songs) + return songs +} + +export function loadFavorite() { + return storage.get(FAVORITE_KEY, []) +} + function insertArr(arr, val, compare, maxLen) { const index = arr.findIndex(compare) if (index === 0) return diff --git a/src/common/js/mixin.js b/src/common/js/mixin.js index c1b9a1e..7d28e86 100644 --- a/src/common/js/mixin.js +++ b/src/common/js/mixin.js @@ -8,7 +8,7 @@ import { set_playList } from 'store/action-creator' -import {saveSearchHistory, deleteSearchHistory} from 'store/action' +import {saveSearchHistory, deleteSearchHistory, saveFavoriteList, deleteFavoriteList} from 'store/action' import {playMode} from 'common/js/config' import {shuffle, debounce} from 'common/js/util' @@ -20,16 +20,18 @@ export const playListHoc = (WrapperComponent) => { this.state = {} this.changeMode = this.changeMode.bind(this) this.show = this.show.bind(this) + this.toggleFavorite = this.toggleFavorite.bind(this) + this.getFavoriteIcon = this.getFavoriteIcon.bind(this) } changeMode() { - const mode = (this.props.mode + 1) % 3 + const mode = (this.props.player.mode + 1) % 3 this.props.set_playMode(mode) let list = null if (mode === playMode.random) { - list = shuffle(this.props.sequenceList) + list = shuffle(this.props.player.sequenceList) } else { - list = this.props.sequenceList + list = this.props.player.sequenceList } // set list 需要在前,需要根据下一个list来设置currentSong this.props.set_playList(list) @@ -38,7 +40,7 @@ export const playListHoc = (WrapperComponent) => { resetCurrentIndex(list) { let index = list.findIndex(v => { - return v.id === this.props.currentSong.id + return v.id === this.props.player.currentSong.id }) this.props.set_currentIndex(index) } @@ -48,23 +50,50 @@ export const playListHoc = (WrapperComponent) => { instance && instance.show() } + toggleFavorite(song) { + if (this.isFavorite(song)) { + this.props.deleteFavoriteList(song) + } else { + this.props.saveFavoriteList(song) + } + } + + getFavoriteIcon(song) { + return this.isFavorite(song) ? 'icon icon-favorite' : 'icon icon-not-favorite' + } + + isFavorite(song) { + const index = this.props.favoriteList.findIndex((item) => { + return item.id === song.id + }) + return index > -1 + } + render() { - const {mode} = this.props + const {player: {mode}} = this.props const modeIcon = mode === playMode.sequence ? 'icon-sequence' : mode === playMode.loop ? 'icon-loop' : 'icon-random' let props ={ ...this.props, + ...this.props.player, modeIcon } return ( - + ) } } - return connect(state => state.player, { + return connect(state => state, { set_playing, set_currentIndex, set_playMode, - set_playList + set_playList, + saveFavoriteList, + deleteFavoriteList }, null, {withRef: true})(PlayHoc) } diff --git a/src/components/addSong/addSong.js b/src/components/addSong/addSong.js index 34ac7aa..5fb9dd3 100644 --- a/src/components/addSong/addSong.js +++ b/src/components/addSong/addSong.js @@ -2,8 +2,6 @@ import React from 'react' import PropTypes from 'prop-types' import {connect} from 'react-redux' -import {CSSTransition} from 'react-transition-group' - import SearchBox from 'base/searchBox/searchBox' import Suggest from 'components/suggest/suggest' import Switch from 'base/switch/switch' @@ -55,21 +53,11 @@ class AddSong extends React.Component { } } - hide(e) { e.stopPropagation() this.props.hide() } - exit(el) { - // hack 由于render的style直接改变为none,导致动画无效 - el.style.display = 'block' - } - - exited(el) { - el.style.display = 'none' - } - switch(i) { this.setState({ currentIndex: i @@ -102,82 +90,74 @@ class AddSong extends React.Component { render() { const {playHistory, searchHistory} = this.props return ( - this.exit(el)} - onExited={(el) => this.exited(el)}> -
e.stopPropagation()}> -
-

添加歌曲到列表

-
- -
+
e.stopPropagation()}> +
+

添加歌曲到列表

+
+
-
- -
-
- -
- { - this.state.currentIndex === 0 - ? - -
- -
-
- : - -
- -
-
- } -
-
-
- +
+
+ +
+
+ +
+ { + this.state.currentIndex === 0 + ? + +
+ +
+
+ : + +
+ +
+
+ }
- -
- - 1首歌曲已经添加到播放列表 -
-
- +
+ +
+ +
+ + 1首歌曲已经添加到播放列表 +
+
+
) } } diff --git a/src/components/addSong/addSong.styl b/src/components/addSong/addSong.styl index 5fcfab2..2c69163 100644 --- a/src/components/addSong/addSong.styl +++ b/src/components/addSong/addSong.styl @@ -8,6 +8,10 @@ width: 100% z-index: 200 background: $color-background + transform translate3d(100%, 0, 0) + transition all 0.3s + &.fade + transform translate3d(0, 0, 0) .header position: relative height: 44px diff --git a/src/components/playList/playList.js b/src/components/playList/playList.js index 9733d0c..82e9508 100644 --- a/src/components/playList/playList.js +++ b/src/components/playList/playList.js @@ -37,13 +37,13 @@ class PlayList extends React.Component{ } shouldComponentUpdate(nextProps, nextState) { + const oldSong = this.props.currentSong const newSong = nextProps.currentSong const sequenceList = nextProps.sequenceList - // if (!nextState.showFlag || newSong.id === oldSong.id) { - // return false - // } - this.scrollToCurrent(newSong, sequenceList) + if (newSong.id !== oldSong.id) { + this.scrollToCurrent(newSong, sequenceList) + } return true } @@ -100,6 +100,10 @@ class PlayList extends React.Component{ }, 200) } + toggleFavorite(v, e) { + e.stopPropagation() + this.props.toggleFavorite(v) + } showConfirm() { this.refs.confirm.show() } @@ -164,8 +168,8 @@ class PlayList extends React.Component{
  • this.selectItem(v, i)}> {v.name} - - + this.toggleFavorite(v, e)}> + this.deleteOne(v, e)}> diff --git a/src/components/player/player.js b/src/components/player/player.js index c26aee2..f920cdb 100644 --- a/src/components/player/player.js +++ b/src/components/player/player.js @@ -545,7 +545,7 @@ class Player extends React.Component{
  • - + this.props.toggleFavorite(currentSong)}>
    diff --git a/src/components/user/user.js b/src/components/user/user.js index bd269f6..641e01e 100644 --- a/src/components/user/user.js +++ b/src/components/user/user.js @@ -1,11 +1,87 @@ import React, {Component} from 'react' +import {connect} from 'react-redux' + +import Switch from 'base/switch/switch' +import Scroll from 'base/scroll/scroll' +import SongList from 'base/songlist/songlist' + +import {Song} from 'common/js/song' + +import {insertSong} from 'store/action' + +import './user.styl' + +class User extends Component{ + constructor(props) { + super(props) + this.state ={ + switches: [ + { + name: '最近播放' + }, + { + name: '搜索历史' + } + ], + currentIndex: 0 + } + this.selectSong = this.selectSong.bind(this) + } + + switch(i) { + this.setState({ + currentIndex: i + }) + } + + selectSong(v) { + this.props.insertSong(new Song(v)) + } -export default class User extends Component{ render() { return( -
    - user-center +
    +
    + +
    +
    + +
    +
    + + 随机播放全部 +
    +
    + { + this.state.currentIndex === 0 + ? + +
    + +
    +
    + : + +
    + +
    +
    + } +
    ) } -} \ No newline at end of file +} + +User = connect(state => state, {insertSong})(User) + +export default User \ No newline at end of file diff --git a/src/components/user/user.styl b/src/components/user/user.styl new file mode 100644 index 0000000..88dfcb5 --- /dev/null +++ b/src/components/user/user.styl @@ -0,0 +1,59 @@ +@import "~common/styl/variable" + +.user-center + position: fixed + top: 0 + bottom: 0 + z-index: 100 + width: 100% + background: $color-background + transform translate3d(100%, 0, 0) + transition all 0.3s + &.fade + transform translate3d(0, 0, 0) + .back + position absolute + top: 0 + left: 6px + z-index: 50 + .icon-back + display: block + padding: 10px + font-size: $font-size-large-x + color: $color-theme + .switches-wrapper + margin: 10px 0 30px 0 + .play-btn + box-sizing: border-box + width: 135px + padding: 7px 0 + margin: 0 auto + text-align: center + border: 1px solid $color-text-l + color: $color-text-l + border-radius: 100px + font-size: 0 + .icon-play + display: inline-block + vertical-align: middle + margin-right: 6px + font-size: $font-size-medium-x + .text + display: inline-block + vertical-align: middle + font-size: $font-size-small + .list-wrapper + position: absolute + top: 110px + bottom: 0 + width: 100% + .list-scroll + height: 100% + overflow: hidden + .list-inner + padding: 20px 30px + .no-result-wrapper + position: absolute + width: 100% + top: 50% + transform: translateY(-50%) \ No newline at end of file diff --git a/src/store/action-creator.js b/src/store/action-creator.js index f669ace..ab9b48d 100644 --- a/src/store/action-creator.js +++ b/src/store/action-creator.js @@ -53,4 +53,9 @@ export const setSearchHistory = list => ({ export const setPlayHistory = list => ({ type: types.SET_PLAY_HISTORY, payload: list +}) + +export const setFavorite = list => ({ + type: types.SET_FAVORITE_LIST, + payload: list }) \ No newline at end of file diff --git a/src/store/action.js b/src/store/action.js index b973022..0c1898d 100644 --- a/src/store/action.js +++ b/src/store/action.js @@ -1,7 +1,7 @@ import * as actions from './action-creator' import {playMode} from 'common/js/config' import {shuffle} from 'common/js/util' -import {saveSearch, deleteSearch, clearSearch, savePlay} from 'common/js/cache' +import {saveSearch, deleteSearch, clearSearch, savePlay, saveFavorite, deleteFavorite} from 'common/js/cache' export function setDisc(data) { return dispatch => { @@ -146,6 +146,18 @@ export function savePlayHistory(song) { } } +export function deleteFavoriteList(song) { + return dispatch => { + dispatch(actions.setFavorite(deleteFavorite(song))) + } +} + +export function saveFavoriteList(song) { + return dispatch => { + dispatch(actions.setFavorite(saveFavorite(song))) + } +} + function findIndex(list, song) { return list.findIndex((item) => { return item.id === song.id diff --git a/src/store/reducers.js b/src/store/reducers.js index 87b05a6..4f51fab 100644 --- a/src/store/reducers.js +++ b/src/store/reducers.js @@ -96,4 +96,13 @@ export function playHistory(state = initState.playHistory, action) { default: return state } +} + +export function favoriteList(state = initState.favoriteList, action) { + switch (action.type) { + case types.SET_FAVORITE_LIST: + return [...action.payload] + default: + return state + } } \ No newline at end of file diff --git a/src/store/state.js b/src/store/state.js index 344d379..a5928e9 100644 --- a/src/store/state.js +++ b/src/store/state.js @@ -1,5 +1,5 @@ import {playMode} from 'common/js/config' -import {loadSearch, loadPlay} from 'common/js/cache' +import {loadSearch, loadPlay, loadFavorite} from 'common/js/cache' const state = { disc: {}, @@ -15,6 +15,7 @@ const state = { }, topList: {}, searchHistory: loadSearch(), - playHistory: loadPlay() + playHistory: loadPlay(), + favoriteList: loadFavorite() } export default state \ No newline at end of file