mu-player
Version:
Play music from vk.com and soundcloud.com via Music Player Daemon
244 lines (221 loc) • 7.48 kB
JavaScript
import _ from 'lodash';
import storage from './../storage/storage';
import similarPrompt from './../tui/similar-prompt';
import listPrompt from './../tui/list-prompt';
import * as lfmActions from './../actions/lastfm-actions';
import * as vkActions from './../actions/vk-actions';
import * as playlist from './playlist-ctrl';
import errorHandler from '../helpers/error-handler';
let screen = null;
let menuPane = null;
let treeData = {};
let qsearch = null;
export let init = (_screen, _menuPane, _qsearch) => {
screen = _screen;
menuPane = _menuPane;
qsearch = _qsearch;
menuPane.on('select', (item) => {
if (item.fn) item.fn();
});
};
export let search = (payload) => {
let psearch;
if (payload.type === 'search')
psearch = lfmActions.getSearch(payload.query);
else if (payload.type === 'tagsearch')
psearch = lfmActions.getTagSearch(payload.query);
else
return errorHandler('Unknown search type');
psearch.then((searchData) => {
function TrackItem(track, artist) {
this.track = track;
this.artist = artist;
this.name = '{bold}[' + artist + ']{/bold} ' + track;
}
TrackItem.prototype.fn = function() {
playlist.search({
type: 'searchWithArtist',
track: this.track,
artist: this.artist
});
};
function ArtistItem(artist) {
this.artist = artist;
this.name = '{bold}[' + artist + ']{/bold}';
this.extended = true;
this.children = {
'alltracks': {
name: 'All tracks for ' + this.artist, // all nodes must have unique names for tree
artist: this.artist, // save link for fn
fn: function() {
let self = this;
playlist.search({
type: 'search',
query: self.artist
});
}
},
'top': {
name: 'Top tracks for ' + this.artist,
artist: this.artist,
fn: function() {
let self = this;
let limit = storage.data.batchSearch.results;
lfmActions.getTopTracks(self.artist, limit).then((tracks) => {
Logger.screen.info('last.fm', 'found ' + tracks.length + ' track(s)');
let tracklist = [];
tracks.forEach((track) => {
tracklist.push({
artist: self.artist,
track: track.name
});
});
playlist.batchSearch({
type: 'tracklist',
tracklist: tracklist,
});
}).catch(errorHandler);
}
},
'albums': {
name: 'Top albums for ' + this.artist,
artist: this.artist, // save link for fn
fn: function() {
let self = this;
return lfmActions.getTopAlbums(self.artist).then((albums) => {
Logger.screen.info('last.fm', 'found ' + albums.length + ' album(s)');
return listPrompt(screen, albums, 'name', 'Choose the Album').then((album) => {
return lfmActions.getAlbumInfo({
// artist: self.artist,
// album: album.name,
mbid: album.mbid
}).then((tracks) => {
Logger.screen.info('last.fm', 'found ' + tracks.length + ' track(s)');
let tracklist = [];
tracks.forEach((track) => {
tracklist.push({
artist: track.artist.name,
track: track.name,
album: album.name
});
});
return playlist.batchSearch({
type: 'tracklist',
tracklist: tracklist,
});
});
});
}).catch(errorHandler);
}
},
'similar': {
name: 'Similar artists for ' + this.artist,
artist: this.artist, // save link for fn
fn: function() {
let self = this;
return lfmActions.getSimilar(this.artist).then((artists) => {
Logger.screen.info('last.fm', 'found ' + artists.length + ' artist(s)');
return listPrompt(screen, artists, 'name', 'Choose the Artist').then((artist) => {
qsearch.setValue(artist.name);
qsearch.emit('submit');
});
}).catch(errorHandler);
}
},
};
}
function ItemFactory(type, data) {
if (type === 'tracks')
return new TrackItem(data.name, data.artist);
else if (type === 'artists')
return new ArtistItem(data.name);
}
let title = '',
rootKey, fn;
let menu = {
extended: true,
children: {}
};
menu.children.user = {
name: '{bold}{light-white-fg}User{/bold}{/light-white-fg}',
extended: false,
children: {
favs: {
name: 'Favorites',
children: {},
fn: function() {
let self = this;
let limit = storage.data.favs.results;
lfmActions.getUserFavs().then((tracks) => {
Logger.log(tracks);
Logger.screen.info('last.fm', 'found ' + tracks.length + ' track(s)');
playlist.batchSearch({
type: 'tracklist',
tracklist: tracks,
});
}).catch(errorHandler);
}
},
top: {
name: 'Top tracks',
children: {},
fn: function() {
let self = this;
let limit = storage.data.favs.results;
lfmActions.getUserTopTracks().then((tracks) => {
Logger.screen.info('last.fm', 'found ' + tracks.length + ' track(s)');
playlist.batchSearch({
type: 'tracklist',
tracklist: tracks,
});
}).catch(errorHandler);
}
},
recom: {
name: 'Recommended tracks',
children: {},
fn: function() {
let self = this;
let limit = storage.data.favs.results;
vkActions.getUserRecom({limit: 200}).then((tracks) => {
Logger.screen.info('last.fm', 'found ' + tracks.length + ' track(s)');
playlist.setPlaylist(tracks);
}).catch(errorHandler);
}
},
recent: {
name: 'Recent tracks',
children: {},
fn: function() {
let self = this;
let limit = storage.data.favs.results;
lfmActions.getUserRecentTracks().then((tracks) => {
Logger.screen.info('last.fm', 'found ' + tracks.length + ' track(s)');
playlist.batchSearch({
type: 'tracklist',
tracklist: tracks,
});
}).catch(errorHandler);
}
},
},
};
for (var key in searchData) {
rootKey = key.charAt(0).toUpperCase() + key.slice(1);
menu.children[rootKey] = {
name: '{bold}{light-white-fg}' + rootKey + '{/light-white-fg}{/bold}',
extended: true,
children: {}
};
searchData[key].forEach((data, id) => {
menu.children[rootKey].children[id] = ItemFactory(key, data);
});
}
treeData = menu;
renderPane();
});
};
let renderPane = () => {
menuPane.setData(treeData);
screen.render();
};