koel/resources/assets/js/stores/album.js

181 lines
4.3 KiB
JavaScript
Raw Normal View History

2016-02-09 04:57:08 +00:00
import Vue from 'vue';
import {
reduce,
each,
find,
union,
difference,
take,
filter,
2016-03-31 08:58:46 +00:00
orderBy
} from 'lodash';
2015-12-13 04:42:28 +00:00
2016-04-10 09:51:06 +00:00
import { secondsToHis } from '../services/utils';
2015-12-13 04:42:28 +00:00
import stub from '../stubs/album';
import songStore from './song';
2016-03-05 09:01:12 +00:00
import artistStore from './artist';
2015-12-13 04:42:28 +00:00
export default {
stub,
2015-12-13 04:42:28 +00:00
state: {
albums: [stub],
2015-12-13 04:42:28 +00:00
},
/**
* Init the store.
*
2016-01-17 14:26:24 +00:00
* @param {Array.<Object>} artists The array of artists to extract album data from.
2015-12-13 04:42:28 +00:00
*/
init(artists) {
// Traverse through the artists array and add their albums into our master album list.
2016-04-05 07:38:10 +00:00
this.all = reduce(artists, (albums, artist) => {
2015-12-13 04:42:28 +00:00
// While we're doing so, for each album, we get its length
// and keep a back reference to the artist too.
each(artist.albums, album => {
2016-03-05 09:01:12 +00:00
this.setupAlbum(album, artist);
2015-12-13 04:42:28 +00:00
});
return albums.concat(artist.albums);
}, []);
// Then we init the song store.
2016-04-05 07:38:10 +00:00
songStore.init(this.all);
2015-12-13 04:42:28 +00:00
},
2016-03-05 09:01:12 +00:00
setupAlbum(album, artist) {
Vue.set(album, 'playCount', 0);
Vue.set(album, 'artist', artist);
Vue.set(album, 'info', null);
this.getLength(album);
return album;
},
2016-01-17 14:26:24 +00:00
/**
* Get all albums in the store.
*
2016-01-17 14:26:24 +00:00
* @return {Array.<Object>}
*/
2016-03-18 04:45:12 +00:00
get all() {
2015-12-13 04:42:28 +00:00
return this.state.albums;
},
2016-04-05 07:38:10 +00:00
/**
* Set all albums.
*
* @param {Array.<Object>} value
*/
set all(value) {
this.state.albums = value;
},
2016-03-05 09:01:12 +00:00
byId(id) {
2016-03-31 08:58:46 +00:00
return find(this.all, { id });
2016-03-05 09:01:12 +00:00
},
2015-12-13 04:42:28 +00:00
/**
* Get the total length of an album by summing up its songs' duration.
* The length will also be converted into a H:i:s format and stored as fmtLength.
*
2016-01-07 09:03:38 +00:00
* @param {Object} album
*
2016-01-17 14:26:24 +00:00
* @return {String} The H:i:s format of the album length.
2015-12-13 04:42:28 +00:00
*/
getLength(album) {
Vue.set(album, 'length', reduce(album.songs, (length, song) => length + song.length, 0));
2016-04-10 09:51:06 +00:00
Vue.set(album, 'fmtLength', secondsToHis(album.length));
return album.fmtLength;
},
2016-03-05 09:01:12 +00:00
/**
2016-04-05 07:38:10 +00:00
* Add new album/albums into the current collection.
2016-03-05 09:01:12 +00:00
*
2016-04-05 07:38:10 +00:00
* @param {Array.<Object>|Object} albums
2016-03-05 09:01:12 +00:00
*/
2016-04-05 07:38:10 +00:00
add(albums) {
albums = [].concat(albums);
each(albums, a => {
this.setupAlbum(a, a.artist)
a.playCount = reduce(a.songs, (count, song) => count + song.playCount, 0);
});
this.all = union(this.all, albums);
2016-03-05 09:01:12 +00:00
},
/**
* Add song(s) into an album.
*
* @param {Object} album
* @param {Array.<Object>|Object} song
*/
addSongsIntoAlbum(album, songs) {
songs = [].concat(songs);
album.songs = union(album.songs ? album.songs : [], songs);
2016-03-05 09:01:12 +00:00
2016-04-05 07:38:10 +00:00
each(songs, song => {
2016-03-05 09:01:12 +00:00
song.album_id = album.id;
song.album = album;
});
album.playCount = reduce(album.songs, (count, song) => count + song.playCount, 0);
2016-03-05 09:01:12 +00:00
this.getLength(album);
},
/**
* Remove song(s) from an album.
*
* @param {Object} album
* @param {Array.<Object>|Object} songs
*/
removeSongsFromAlbum(album, songs) {
album.songs = difference(album.songs, [].concat(songs));
album.playCount = reduce(album.songs, (count, song) => count + song.playCount, 0);
2016-03-05 09:01:12 +00:00
this.getLength(album);
},
/**
* Checks if an album is empty.
*
* @param {Object} album
*
* @return {boolean}
*/
isAlbumEmpty(album) {
return !album.songs.length;
},
/**
* Remove album(s) from the store.
*
* @param {Array.<Object>|Object} albums
*/
remove(albums) {
albums = [].concat(albums);
2016-04-05 07:38:10 +00:00
this.all = difference(this.all, albums);
2016-03-05 09:01:12 +00:00
// Remove from the artist as well
2016-04-05 07:38:10 +00:00
each(albums, album => {
2016-03-05 09:01:12 +00:00
artistStore.removeAlbumsFromArtist(album.artist, album);
});
},
/**
* Get top n most-played albums.
*
* @param {Number} n
*
* @return {Array.<Object>}
*/
getMostPlayed(n = 6) {
// Only non-unknown albums with actually play count are applicable.
2016-04-05 07:38:10 +00:00
const applicable = filter(this.all, album => {
return album.playCount && album.id !== 1;
});
2015-12-13 04:42:28 +00:00
2016-03-31 08:58:46 +00:00
return take(orderBy(applicable, 'playCount', 'desc'), n);
2015-12-13 04:42:28 +00:00
},
};