Revamping radio notifications; Radio current track
This commit is contained in:
@ -97,7 +97,7 @@ class App extends React.Component{
|
||||
// scroll position. We'll need to keep a running history of locations
|
||||
// and scroll positions, which may be performance-hindering
|
||||
// At this point we can capture "window.scrollY" for the previous scroll position
|
||||
//window.scrollTo(0, 0);
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
src/js/bootstrap.js
vendored
2
src/js/bootstrap.js
vendored
@ -37,7 +37,7 @@ var initialState = {
|
||||
outputs: [],
|
||||
queue: [],
|
||||
queue_metadata: {},
|
||||
current_track_uri: null,
|
||||
current_track: null,
|
||||
albums: {},
|
||||
artists: {},
|
||||
playlists: {},
|
||||
|
||||
@ -122,7 +122,6 @@ const mapStateToProps = (state, ownProps) => {
|
||||
mopidy_connected: state.mopidy.connected,
|
||||
pusher_connected: state.pusher.connected,
|
||||
spotify_enabled: state.spotify.enabled,
|
||||
spotify_connected: state.spotify.connected,
|
||||
spotify_authorized: state.spotify.authorization,
|
||||
test_mode: (state.ui.test_mode ? state.ui.test_mode : false),
|
||||
dragger: state.ui.dragger
|
||||
|
||||
@ -28,7 +28,7 @@ export default function reducer(core = {}, action){
|
||||
for(var i = 0; i < tracklist.length; i++){
|
||||
|
||||
// load our metadata (if we have any for that tlid)
|
||||
if (typeof(action.queue_metadata['tlid_'+tracklist[i].tlid]) !== 'undefined'){
|
||||
if (action.queue_metadata['tlid_'+tracklist[i].tlid] !== undefined){
|
||||
tracklist[i] = Object.assign(
|
||||
{},
|
||||
tracklist[i],
|
||||
@ -38,7 +38,7 @@ export default function reducer(core = {}, action){
|
||||
}
|
||||
return Object.assign({}, core, { current_tracklist: tracklist, queue_metadata: action.queue_metadata });
|
||||
|
||||
case 'PUSHER_RADIO':
|
||||
case 'PUSHER_RADIO_LOADED':
|
||||
case 'PUSHER_RADIO_STARTED':
|
||||
case 'PUSHER_RADIO_CHANGED':
|
||||
case 'PUSHER_RADIO_STOPPED':
|
||||
|
||||
@ -1395,6 +1395,7 @@ const MopidyMiddleware = (function(){
|
||||
{
|
||||
uri: response.uri,
|
||||
type: 'playlist',
|
||||
is_completely_loaded: true,
|
||||
is_mopidy: true,
|
||||
tracks: (response.tracks ? response.tracks : []),
|
||||
tracks_total: (response.tracks ? response.tracks.length : [])
|
||||
|
||||
@ -128,6 +128,26 @@ export function stopRadio(){
|
||||
}
|
||||
}
|
||||
|
||||
export function radioStarted(radio){
|
||||
return {
|
||||
type: 'PUSHER_RADIO_STARTED',
|
||||
radio: radio
|
||||
}
|
||||
}
|
||||
|
||||
export function radioChanged(radio){
|
||||
return {
|
||||
type: 'PUSHER_RADIO_CHANGED',
|
||||
radio: radio
|
||||
}
|
||||
}
|
||||
|
||||
export function radioStopped(){
|
||||
return {
|
||||
type: 'PUSHER_RADIO_STOPPED'
|
||||
}
|
||||
}
|
||||
|
||||
export function debug(message = null){
|
||||
return {
|
||||
type: 'PUSHER_DEBUG',
|
||||
|
||||
@ -81,6 +81,15 @@ const PusherMiddleware = (function(){
|
||||
case 'notification':
|
||||
store.dispatch(uiActions.createNotification(message.params.notification));
|
||||
break;
|
||||
case 'radio_started':
|
||||
store.dispatch(pusherActions.radioStarted(message.params.radio));
|
||||
break;
|
||||
case 'radio_changed':
|
||||
store.dispatch(pusherActions.radioChanged(message.params.radio));
|
||||
break;
|
||||
case 'radio_stopped':
|
||||
store.dispatch(pusherActions.radioStopped());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -360,7 +369,7 @@ const PusherMiddleware = (function(){
|
||||
.then(
|
||||
response => {
|
||||
store.dispatch({
|
||||
type: 'PUSHER_RADIO',
|
||||
type: 'PUSHER_RADIO_LOADED',
|
||||
radio: response.radio
|
||||
});
|
||||
},
|
||||
@ -385,7 +394,7 @@ const PusherMiddleware = (function(){
|
||||
}
|
||||
|
||||
var data = {
|
||||
update: (action.type == 'PUSHER_UPDATE_RADIO'),
|
||||
reset: (action.type == 'PUSHER_START_RADIO'),
|
||||
seed_artists: [],
|
||||
seed_genres: [],
|
||||
seed_tracks: []
|
||||
@ -405,6 +414,18 @@ const PusherMiddleware = (function(){
|
||||
}
|
||||
}
|
||||
|
||||
if (action.type == 'PUSHER_START_RADIO'){
|
||||
store.dispatch(pusherActions.deliverBroadcast(
|
||||
'notification',
|
||||
{
|
||||
notification: {
|
||||
type: 'info',
|
||||
content: store.getState().pusher.username + ' is starting radio mode'
|
||||
}
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
request(store, 'change_radio', data)
|
||||
.then(
|
||||
response => {
|
||||
@ -412,9 +433,10 @@ const PusherMiddleware = (function(){
|
||||
if (response.status == 0){
|
||||
store.dispatch(uiActions.createNotification({content: response.message, type: 'bad'}));
|
||||
}
|
||||
store.dispatch(pusherActions.radioChanged(response.radio));
|
||||
},
|
||||
error => {
|
||||
store.dispatch(uiActions.processFinishing('PUSHER_RADIO_PROCESS'));
|
||||
store.dispatch(uiActions.processFinishing('PUSHER_RADIO_PROCESS'));
|
||||
store.dispatch(coreActions.handleException(
|
||||
'Could not change radio',
|
||||
error
|
||||
@ -427,22 +449,33 @@ const PusherMiddleware = (function(){
|
||||
store.dispatch(uiActions.createNotification({content: 'Stopping radio'}));
|
||||
ReactGA.event({ category: 'Pusher', action: 'Stop radio' });
|
||||
|
||||
store.dispatch(pusherActions.deliverBroadcast(
|
||||
'notification',
|
||||
{
|
||||
notification: {
|
||||
type: 'info',
|
||||
content: store.getState().pusher.username + ' stopped radio mode'
|
||||
}
|
||||
}
|
||||
));
|
||||
|
||||
var data = {
|
||||
seed_artists: [],
|
||||
seed_genres: [],
|
||||
seed_tracks: []
|
||||
}
|
||||
|
||||
// we don't need to wait for response, as change will be broadcast
|
||||
request(store, 'stop_radio', data)
|
||||
break
|
||||
|
||||
case 'PUSHER_RADIO_STARTED':
|
||||
case 'PUSHER_RADIO_CHANGED':
|
||||
if (action.radio && action.radio.enabled && store.getState().spotify.enabled){
|
||||
store.dispatch(spotifyActions.resolveRadioSeeds(action.radio))
|
||||
}
|
||||
next(action)
|
||||
.then(
|
||||
response => {
|
||||
store.dispatch(pusherActions.radioStopped());
|
||||
}, error => {
|
||||
store.dispatch(coreActions.handleException(
|
||||
'Could not stop radio',
|
||||
error
|
||||
));
|
||||
}
|
||||
);
|
||||
break
|
||||
|
||||
case 'PUSHER_BROWSER_NOTIFICATION':
|
||||
|
||||
@ -362,6 +362,7 @@ export function getFeaturedPlaylists(){
|
||||
{},
|
||||
response.playlists.items[i],
|
||||
{
|
||||
is_completely_loaded: false,
|
||||
can_edit: (getState().spotify.me && response.playlists.items[i].owner.id == getState().spotify.me.id),
|
||||
tracks_total: response.playlists.items[i].tracks.total
|
||||
}
|
||||
@ -1543,6 +1544,7 @@ export function getPlaylist(uri){
|
||||
{},
|
||||
response,
|
||||
{
|
||||
is_completely_loaded: true,
|
||||
can_edit: (getState().spotify.me && response.owner.id == getState().spotify.me.id),
|
||||
tracks: helpers.formatTracks(response.tracks.items),
|
||||
tracks_more: response.tracks.next,
|
||||
|
||||
@ -17,23 +17,6 @@ const SpotifyMiddleware = (function(){
|
||||
|
||||
switch(action.type){
|
||||
|
||||
case 'SPOTIFY_CONNECTED':
|
||||
var hashed_username = null
|
||||
if (store.getState().spotify.me){
|
||||
hashed_username = md5(store.getState().spotify.me.id);
|
||||
ReactGA.set({userId: hashed_username});
|
||||
}
|
||||
ReactGA.event({category: 'Spotify', action: 'Connected', label: hashed_username})
|
||||
|
||||
// TODO: remove this so we don't tap out our API limits before we even get started
|
||||
// Perhaps fire this on demand? Context menu, playlists loading or AddToPlaylistModal
|
||||
if (store.getState().spotify_authorized){
|
||||
store.dispatch(spotifyActions.getAllLibraryPlaylists())
|
||||
}
|
||||
|
||||
next(action);
|
||||
break
|
||||
|
||||
case 'SPOTIFY_AUTHORIZATION_GRANTED':
|
||||
ReactGA.event({category: 'Spotify', action: 'Authorization granted'});
|
||||
|
||||
|
||||
@ -42,19 +42,9 @@ class Playlist extends React.Component{
|
||||
}
|
||||
}
|
||||
|
||||
handleContextMenu(e){
|
||||
var data = {
|
||||
e: e,
|
||||
context: (this.props.playlist.can_edit ? 'editable-playlist' : 'playlist'),
|
||||
items: [this.props.playlist],
|
||||
uris: [this.props.params.uri]
|
||||
}
|
||||
this.props.uiActions.showContextMenu(data)
|
||||
}
|
||||
|
||||
loadPlaylist(props = this.props){
|
||||
|
||||
if (props.playlist && props.playlist.tracks && (props.playlist.tracks_total == 0 || props.playlist.tracks.length > 0)){
|
||||
|
||||
if (props.playlist && props.playlist.is_completely_loaded){
|
||||
console.info('Loading playlist from index')
|
||||
|
||||
} else {
|
||||
@ -85,6 +75,16 @@ class Playlist extends React.Component{
|
||||
);
|
||||
}
|
||||
|
||||
handleContextMenu(e){
|
||||
var data = {
|
||||
e: e,
|
||||
context: (this.props.playlist.can_edit ? 'editable-playlist' : 'playlist'),
|
||||
items: [this.props.playlist],
|
||||
uris: [this.props.params.uri]
|
||||
}
|
||||
this.props.uiActions.showContextMenu(data)
|
||||
}
|
||||
|
||||
play(){
|
||||
this.props.mopidyActions.playPlaylist(this.props.playlist.uri)
|
||||
}
|
||||
|
||||
@ -105,7 +105,10 @@ class Queue extends React.Component{
|
||||
track = Object.assign(
|
||||
{},
|
||||
this.props.tracks[track.uri],
|
||||
track
|
||||
track,
|
||||
{
|
||||
playing: (this.props.current_track && this.props.current_track.tlid == track.tlid)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@ -114,10 +117,7 @@ class Queue extends React.Component{
|
||||
track = Object.assign(
|
||||
{},
|
||||
track,
|
||||
this.props.queue_metadata["tlid_"+track.tlid],
|
||||
{
|
||||
playing: (this.props.current_track && this.props.current_track.tlid == track.tlid)
|
||||
}
|
||||
this.props.queue_metadata["tlid_"+track.tlid]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -44,7 +44,7 @@ class Search extends React.Component{
|
||||
this.props.mopidyActions.getSearchResults(context, term)
|
||||
}
|
||||
|
||||
if (this.props.spotify_connected && this.props.search_uri_schemes && this.props.search_uri_schemes.includes('spotify:')){
|
||||
if (this.props.search_uri_schemes && this.props.search_uri_schemes.includes('spotify:')){
|
||||
this.props.spotifyActions.getSearchResults(context, term)
|
||||
}
|
||||
}
|
||||
@ -67,16 +67,8 @@ class Search extends React.Component{
|
||||
var term = null;
|
||||
}
|
||||
|
||||
if (term && !this.props.mopidy_connected && newProps.mopidy_connected){
|
||||
this.props.mopidyActions.getSearchResults(context, term);
|
||||
}
|
||||
|
||||
if (term && !this.props.spotify_connected && newProps.spotify_connected && newProps.search_uri_schemes.includes('spotify:')){
|
||||
this.props.spotifyActions.getSearchResults(context, term);
|
||||
}
|
||||
|
||||
// Search changed
|
||||
if (term && context && term !== old_term){
|
||||
if (term && context && (term !== old_term || context !== old_context)){
|
||||
|
||||
this.props.mopidyActions.clearSearchResults();
|
||||
this.props.spotifyActions.clearSearchResults();
|
||||
@ -375,7 +367,6 @@ class Search extends React.Component{
|
||||
const mapStateToProps = (state, ownProps) => {
|
||||
return {
|
||||
mopidy_connected: state.mopidy.connected,
|
||||
spotify_connected: state.spotify.connected,
|
||||
albums: (state.core.albums ? state.core.albums : []),
|
||||
artists: (state.core.artists ? state.core.artists : []),
|
||||
playlists: (state.core.playlists ? state.core.playlists : []),
|
||||
|
||||
@ -15,7 +15,9 @@ class DiscoverCategories extends React.Component{
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
this.props.spotifyActions.getCategories();
|
||||
if (!this.props.categories){
|
||||
this.props.spotifyActions.getCategories();
|
||||
}
|
||||
}
|
||||
|
||||
render(){
|
||||
|
||||
@ -16,7 +16,7 @@ class DiscoverCategory extends React.Component{
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
this.loadCategory()
|
||||
this.loadCategory();
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps){
|
||||
@ -26,7 +26,9 @@ class DiscoverCategory extends React.Component{
|
||||
}
|
||||
|
||||
loadCategory(){
|
||||
if (!this.props.category || !this.props.category.playlists_uris) this.props.spotifyActions.getCategory(this.props.params.id );
|
||||
if (!this.props.category || !this.props.category.playlists_uris){
|
||||
this.props.spotifyActions.getCategory(this.props.params.id);
|
||||
}
|
||||
}
|
||||
|
||||
loadMore(){
|
||||
|
||||
@ -21,7 +21,9 @@ class DiscoverFeatured extends React.Component{
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
this.props.spotifyActions.getFeaturedPlaylists();
|
||||
if (!this.props.featured_playlists){
|
||||
this.props.spotifyActions.getFeaturedPlaylists();
|
||||
}
|
||||
}
|
||||
|
||||
playPlaylist(e,playlist){
|
||||
|
||||
@ -23,7 +23,9 @@ class DiscoverNewReleases extends React.Component{
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
if (!this.props.new_releases) this.props.spotifyActions.getNewReleases();
|
||||
if (!this.props.new_releases){
|
||||
this.props.spotifyActions.getNewReleases();
|
||||
}
|
||||
}
|
||||
|
||||
loadMore(){
|
||||
|
||||
@ -275,7 +275,6 @@ const mapStateToProps = (state, ownProps) => {
|
||||
return {
|
||||
mopidy_connected: state.mopidy.connected,
|
||||
mopidy_uri_schemes: state.mopidy.uri_schemes,
|
||||
spotify_connected: state.spotify.connected,
|
||||
load_queue: state.ui.load_queue,
|
||||
albums: state.core.albums,
|
||||
mopidy_library_albums: state.mopidy.library_albums,
|
||||
|
||||
@ -242,7 +242,6 @@ class LibraryArtists extends React.Component{
|
||||
const mapStateToProps = (state, ownProps) => {
|
||||
return {
|
||||
mopidy_connected: state.mopidy.connected,
|
||||
spotify_connected: state.spotify.connected,
|
||||
mopidy_uri_schemes: state.mopidy.uri_schemes,
|
||||
mopidy_library_artists: state.mopidy.library_artists,
|
||||
mopidy_library_artists_status: (state.ui.processes.MOPIDY_LIBRARY_ARTISTS_PROCESSOR !== undefined ? state.ui.processes.MOPIDY_LIBRARY_ARTISTS_PROCESSOR.status : null),
|
||||
|
||||
@ -264,7 +264,6 @@ const mapStateToProps = (state, ownProps) => {
|
||||
return {
|
||||
slim_mode: state.ui.slim_mode,
|
||||
mopidy_connected: state.mopidy.connected,
|
||||
spotify_connected: state.spotify.connected,
|
||||
mopidy_uri_schemes: state.mopidy.uri_schemes,
|
||||
mopidy_library_playlists: state.mopidy.library_playlists,
|
||||
mopidy_library_playlists_status: (state.ui.processes.MOPIDY_LIBRARY_PLAYLISTS_PROCESSOR !== undefined ? state.ui.processes.MOPIDY_LIBRARY_PLAYLISTS_PROCESSOR.status : null),
|
||||
|
||||
Reference in New Issue
Block a user