Google Analytics implemented
This commit is contained in:
@ -35,9 +35,10 @@
|
||||
"node-sass": "*",
|
||||
"extract-text-webpack-plugin": "*",
|
||||
"jquery": "3.1.1",
|
||||
"mopidy": "^0.5.0",
|
||||
"mopidy": "^0.5.0",
|
||||
"expose-loader": "*",
|
||||
"react-fontawesome": "*"
|
||||
"react-fontawesome": "*",
|
||||
"react-ga": "2.1.2"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "./build.sh & NODE_ENV=development webpack",
|
||||
|
||||
2
src/js/bootstrap.js
vendored
2
src/js/bootstrap.js
vendored
@ -36,7 +36,7 @@ var initialState = {
|
||||
pusher: {
|
||||
connected: false,
|
||||
port: 6681,
|
||||
username: '',
|
||||
username: 'Anonymous',
|
||||
connections: [],
|
||||
version: {
|
||||
current: '0.0.0'
|
||||
|
||||
@ -42,7 +42,7 @@ class ContextMenu extends React.Component{
|
||||
|
||||
playQueueItem(){
|
||||
var selectedTracks = this.props.context_menu.data.selected_tracks;
|
||||
this.props.mopidyActions.changeTrack( selectedTracks[0].tlid );
|
||||
this.props.mopidyActions.changeTrack( selectedTracks[0].tlid );
|
||||
this.props.uiActions.hideContextMenu();
|
||||
}
|
||||
|
||||
|
||||
@ -38,6 +38,10 @@ class SendAuthorizationModal extends React.Component{
|
||||
<div className="list pusher-connection-list">
|
||||
{
|
||||
this.props.connections.map( (connection, index) => {
|
||||
|
||||
// don't list OUR connection
|
||||
if (connection.connectionid == this.props.connectionid) return null
|
||||
|
||||
return (
|
||||
<div className='list-item connection' key={connection.connectionid} onClick={ e => this.handleClick(e, connection.connectionid) }>
|
||||
{ connection.username }
|
||||
@ -57,6 +61,7 @@ const mapStateToProps = (state, ownProps) => {
|
||||
return {
|
||||
me: state.spotify.me,
|
||||
authorization: state.spotify.authorization,
|
||||
connectionid: state.pusher.connectionid,
|
||||
connections: state.pusher.connections
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ import React, { PropTypes } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import { Link } from 'react-router'
|
||||
import { createStore, bindActionCreators } from 'redux'
|
||||
import ReactGA from 'react-ga'
|
||||
|
||||
import FontAwesome from 'react-fontawesome'
|
||||
import Thumbnail from './Thumbnail'
|
||||
|
||||
@ -7,9 +7,9 @@ import ReactDOM from 'react-dom';
|
||||
import { Provider } from 'react-redux'
|
||||
import { createStore } from 'redux'
|
||||
import { Router, Route, Link, IndexRoute, hashHistory } from 'react-router'
|
||||
import ReactGA from 'react-ga'
|
||||
|
||||
import store from './bootstrap.js'
|
||||
|
||||
require('../scss/app.scss');
|
||||
|
||||
import App from './views/App'
|
||||
@ -37,11 +37,18 @@ import LibraryLocalArtists from './views/library/LibraryLocalArtists'
|
||||
import LibraryLocalAlbums from './views/library/LibraryLocalAlbums'
|
||||
import LibraryLocalDirectory from './views/library/LibraryLocalDirectory'
|
||||
|
||||
// setup our analytics tracking
|
||||
ReactGA.initialize('UA-64701652-3');
|
||||
function logPageView() {
|
||||
ReactGA.set({ page: window.location.hash })
|
||||
ReactGA.pageview(window.location.hash)
|
||||
}
|
||||
|
||||
global.baseURL = '/'
|
||||
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
<Router history={hashHistory}>
|
||||
<Router history={hashHistory} onUpdate={logPageView}>
|
||||
<Route path={global.baseURL} component={App}>
|
||||
|
||||
<IndexRoute component={Queue} />
|
||||
|
||||
@ -16,7 +16,6 @@ const SpotifyMiddleware = (function(){
|
||||
case 'SPOTIFY_CONNECT':
|
||||
store.dispatch( spotifyActions.getMe() )
|
||||
break
|
||||
|
||||
|
||||
case 'SPOTIFY_CREATE_PLAYLIST':
|
||||
var playlist = state.ui.playlist
|
||||
@ -28,7 +27,6 @@ const SpotifyMiddleware = (function(){
|
||||
store.dispatch( spotifyActions.createPlaylist( action.name, action.is_private ))
|
||||
break
|
||||
|
||||
|
||||
case 'SPOTIFY_REMOVE_PLAYLIST_TRACKS':
|
||||
var playlist = state.ui.playlist
|
||||
|
||||
|
||||
@ -18,9 +18,10 @@ export function hideContextMenu(){
|
||||
}
|
||||
}
|
||||
|
||||
export function searchStarted(){
|
||||
export function searchStarted( query ){
|
||||
return {
|
||||
type: 'SEARCH_STARTED',
|
||||
query: query,
|
||||
data: {
|
||||
artists: [],
|
||||
albums: [],
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
|
||||
import ReactGA from 'react-ga'
|
||||
|
||||
var uiActions = require('./actions.js')
|
||||
var spotifyActions = require('../spotify/actions.js')
|
||||
@ -13,6 +14,122 @@ const UIMiddleware = (function(){
|
||||
|
||||
switch(action.type){
|
||||
|
||||
case 'MOPIDY_CONNECTED':
|
||||
ReactGA.event({ category: 'Mopidy', action: 'Connected', label: window.location.hostname })
|
||||
next(action)
|
||||
break
|
||||
|
||||
case 'PUSHER_CONNECTED':
|
||||
ReactGA.event({ category: 'Pusher', action: 'Connected', label: action.connection.username })
|
||||
next(action)
|
||||
break
|
||||
|
||||
case 'SPOTIFY_CONNECTED':
|
||||
var label = null
|
||||
if (store.getState().spotify.me) label = store.getState().spotify.me.id
|
||||
ReactGA.event({ category: 'Spotify', action: 'Connected', label: label })
|
||||
next(action)
|
||||
break
|
||||
|
||||
case 'SPOTIFY_AUTHORIZATION_GRANTED':
|
||||
ReactGA.event({ category: 'Spotify', action: 'Authorization granted' })
|
||||
next(action)
|
||||
break
|
||||
|
||||
case 'SPOTIFY_AUTHORIZATION_REVOKED':
|
||||
var label = null
|
||||
if (store.getState().spotify.me) label = store.getState().spotify.me.id
|
||||
ReactGA.event({ category: 'Spotify', action: 'Authorization revoked', label: label })
|
||||
next(action)
|
||||
break
|
||||
|
||||
case 'SPOTIFY_ME_LOADED':
|
||||
ReactGA.event({ category: 'Spotify', action: 'Authorization verified', label: action.data.id })
|
||||
next(action)
|
||||
break
|
||||
|
||||
case 'MOPIDY_ALBUM_LOADED':
|
||||
case 'SPOTIFY_ALBUM_LOADED':
|
||||
if (action.data) ReactGA.event({ category: 'Album', action: 'Load', label: action.data.uri })
|
||||
next(action)
|
||||
break
|
||||
|
||||
case 'MOPIDY_ARTIST_LOADED':
|
||||
case 'SPOTIFY_ARTIST_LOADED':
|
||||
if (action.data) ReactGA.event({ category: 'Artist', action: 'Load', label: action.data.uri })
|
||||
next(action)
|
||||
break
|
||||
|
||||
case 'SPOTIFY_USER_LOADED':
|
||||
if (action.data) ReactGA.event({ category: 'User', action: 'Load', label: action.data.uri })
|
||||
next(action)
|
||||
break
|
||||
|
||||
case 'MOPIDY_DIRECTORY':
|
||||
if (action.data) ReactGA.event({ category: 'Directory', action: 'Load', label: action.data.uri })
|
||||
next(action)
|
||||
break
|
||||
|
||||
case 'MOPIDY_PLAYLIST_LOADED':
|
||||
case 'SPOTIFY_PLAYLIST_LOADED':
|
||||
if (action.data) ReactGA.event({ category: 'Playlist', action: 'Load', label: action.data.uri })
|
||||
next(action)
|
||||
break
|
||||
|
||||
case 'MOPIDY_SAVE_PLAYLIST':
|
||||
case 'SPOTIFY_SAVE_PLAYLIST':
|
||||
ReactGA.event({ category: 'Playlist', action: 'Save', label: action.uri })
|
||||
next(action)
|
||||
break
|
||||
|
||||
case 'MOPIDY_CREATE_PLAYLIST':
|
||||
ReactGA.event({ category: 'Playlist', action: 'Create', label: 'Mopidy,'+action.name })
|
||||
next(action)
|
||||
break
|
||||
|
||||
case 'SPOTIFY_CREATE_PLAYLIST':
|
||||
ReactGA.event({ category: 'Playlist', action: 'Create', label: 'Spotify,'+action.name })
|
||||
next(action)
|
||||
break
|
||||
|
||||
case 'MOPIDY_REORDER_PLAYLIST_TRACKS':
|
||||
case 'SPOTIFY_REORDER_PLAYLIST_TRACKS':
|
||||
ReactGA.event({ category: 'Playlist', action: 'Reorder tracks', label: action.uri })
|
||||
next(action)
|
||||
break
|
||||
|
||||
case 'MOPIDY_ADD_PLAYLIST_TRACKS':
|
||||
case 'SPOTIFY_ADD_PLAYLIST_TRACKS':
|
||||
ReactGA.event({ category: 'Playlist', action: 'Add tracks', label: action.playlist_uri })
|
||||
next(action)
|
||||
break
|
||||
|
||||
case 'MOPIDY_REMOVE_PLAYLIST_TRACKS':
|
||||
case 'SPOTIFY_REMOVE_PLAYLIST_TRACKS':
|
||||
ReactGA.event({ category: 'Playlist', action: 'Remove tracks', label: action.playlist_uri })
|
||||
next(action)
|
||||
break
|
||||
|
||||
case 'SEARCH_STARTED':
|
||||
ReactGA.event({ category: 'Search', action: 'Started', label: action.query })
|
||||
next(action)
|
||||
break
|
||||
|
||||
case 'PUSHER_START_RADIO':
|
||||
ReactGA.event({ category: 'Pusher', action: 'Start radio', label: action.uris.join() })
|
||||
next(action)
|
||||
break
|
||||
|
||||
case 'PUSHER_STOP_RADIO':
|
||||
ReactGA.event({ category: 'Pusher', action: 'Stop radio' })
|
||||
next(action)
|
||||
break
|
||||
|
||||
case 'PUSHER_UPGRADING':
|
||||
ReactGA.event({ category: 'Pusher', action: 'Upgrade', label: action.data })
|
||||
next(action)
|
||||
break
|
||||
|
||||
case 'CREATE_NOTIFICATION':
|
||||
|
||||
// start a timeout to remove this notification
|
||||
|
||||
@ -4,6 +4,7 @@ import { connect } from 'react-redux'
|
||||
import { bindActionCreators } from 'redux'
|
||||
import { Link } from 'react-router'
|
||||
import FontAwesome from 'react-fontawesome'
|
||||
import ReactGA from 'react-ga'
|
||||
|
||||
import TrackList from '../components/TrackList'
|
||||
import Thumbnail from '../components/Thumbnail'
|
||||
@ -58,28 +59,34 @@ class Playlist extends React.Component{
|
||||
}
|
||||
|
||||
play(){
|
||||
ReactGA.event({ category: 'Playlist', action: 'Play', label: this.props.playlist.uri })
|
||||
this.props.mopidyActions.playURIs([this.props.playlist.uri])
|
||||
}
|
||||
|
||||
follow(){
|
||||
ReactGA.event({ category: 'Playlist', action: 'Follow', label: this.props.playlist.uri })
|
||||
this.props.spotifyActions.toggleFollowingPlaylist( this.props.playlist.uri, 'PUT' )
|
||||
}
|
||||
|
||||
// TODO: Once unfollowing occurs, remove playlist from global playlists list
|
||||
unfollow(){
|
||||
ReactGA.event({ category: 'Playlist', action: 'Unfollow', label: this.props.playlist.uri })
|
||||
this.props.spotifyActions.toggleFollowingPlaylist( this.props.playlist.uri, 'DELETE' )
|
||||
}
|
||||
|
||||
// TODO: Once deletion occurs, remove playlist from global playlists list
|
||||
delete(){
|
||||
ReactGA.event({ category: 'Playlist', action: 'Delete', label: this.props.playlist.uri })
|
||||
this.props.mopidyActions.deletePlaylist( this.props.playlist.uri )
|
||||
}
|
||||
|
||||
reorderTracks( indexes, index ){
|
||||
ReactGA.event({ category: 'Playlist', action: 'Reorder tracks', label: this.props.playlist.uri })
|
||||
this.props.uiActions.reorderPlaylistTracks( this.props.playlist.uri, indexes, index, this.props.playlist.snapshot_id )
|
||||
}
|
||||
|
||||
removeTracks( tracks_indexes ){
|
||||
ReactGA.event({ category: 'Playlist', action: 'Remove tracks', label: this.props.playlist.uri })
|
||||
this.props.uiActions.removeTracksFromPlaylist( this.props.playlist.uri, tracks_indexes )
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ import { connect } from 'react-redux'
|
||||
import { Link } from 'react-router'
|
||||
import { bindActionCreators } from 'redux'
|
||||
import FontAwesome from 'react-fontawesome'
|
||||
import ReactGA from 'react-ga'
|
||||
|
||||
import Header from '../components/Header'
|
||||
import TrackList from '../components/TrackList'
|
||||
@ -40,7 +41,7 @@ class Search extends React.Component{
|
||||
}
|
||||
|
||||
performSearch( props = this.props ){
|
||||
this.props.uiActions.searchStarted()
|
||||
this.props.uiActions.searchStarted( props.params.query )
|
||||
this.props.spotifyActions.getSearchResults( props.params.query )
|
||||
this.props.mopidyActions.getSearchResults( props.params.query, props.uri_schemes )
|
||||
}
|
||||
|
||||
@ -51,14 +51,6 @@ class Settings extends React.Component{
|
||||
return false;
|
||||
}
|
||||
|
||||
componentWillReceiveProps(newProps){
|
||||
if( this.state.pusher_username != newProps.pusher.username ){
|
||||
this.setState({
|
||||
pusher_username: newProps.pusher.username
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
renderConnectionStatus(service){
|
||||
if( this.props[service].connected ){
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user