2018-03-30 22:37:38 +13:00
import React , { PropTypes } from 'react'
import { connect } from 'react-redux'
import { Link } from 'react-router'
import { bindActionCreators } from 'redux'
import Thumbnail from './Thumbnail'
import Icon from './Icon'
import URILink from './URILink'
2018-04-19 13:34:16 +12:00
import SpotifyAuthenticationFrame from '../components/Fields/SpotifyAuthenticationFrame'
import LastfmAuthenticationFrame from '../components/Fields/LastfmAuthenticationFrame'
2018-08-15 16:52:24 +12:00
import GeniusAuthenticationFrame from '../components/Fields/GeniusAuthenticationFrame'
2018-03-30 22:37:38 +13:00
import Snapcast from '../components/Snapcast'
import * as uiActions from '../services/ui/actions'
import * as coreActions from '../services/core/actions'
import * as mopidyActions from '../services/mopidy/actions'
import * as pusherActions from '../services/pusher/actions'
import * as spotifyActions from '../services/spotify/actions'
import * as lastfmActions from '../services/lastfm/actions'
2018-08-15 16:52:24 +12:00
import * as geniusActions from '../services/genius/actions'
2018-03-30 22:37:38 +13:00
class Services extends React . Component {
constructor ( props ) {
super ( props ) ;
this . state = {
country : this . props . spotify . country ,
locale : this . props . spotify . locale ,
input _in _focus : null
}
}
componentDidMount ( ) {
if ( this . props . lastfm . session && this . props . core . users [ "lastfm:user:" + this . props . lastfm . session . name ] === undefined ) {
this . props . lastfmActions . getMe ( ) ;
}
2018-08-17 16:09:36 +12:00
if ( this . props . genius . me && this . props . core . users [ "genius:user:" + this . props . genius . me . id ] === undefined ) {
this . props . geniusActions . getMe ( ) ;
}
2018-03-30 22:37:38 +13:00
}
componentWillReceiveProps ( newProps ) {
var changed = false
var state = this . state
2018-08-15 16:52:24 +12:00
2018-03-30 22:37:38 +13:00
if ( newProps . spotify . country != this . state . country && this . state . input _in _focus != 'country' ) {
state . country = newProps . spotify . country
changed = true
}
2018-08-15 16:52:24 +12:00
2018-03-30 22:37:38 +13:00
if ( newProps . spotify . locale != this . state . locale && this . state . input _in _focus != 'locale' ) {
state . locale = newProps . spotify . locale
changed = true
}
if ( changed ) {
this . setState ( state )
}
}
handleBlur ( name , value ) {
this . setState ( { input _in _focus : null } )
var data = { }
data [ name ] = value
this . props . coreActions . set ( data )
}
renderSpotify ( ) {
2018-07-13 16:48:41 +12:00
var share _authorization _button = null ;
2018-03-30 22:37:38 +13:00
if ( this . props . spotify . authorization ) {
2018-07-13 16:48:41 +12:00
share _authorization _button = (
2018-07-21 11:43:40 +12:00
< Link className = "button" to = { global . baseURL + 'settings/share-authorization' } >
2018-07-13 16:48:41 +12:00
Share authorization
< / L i n k >
2018-03-30 22:37:38 +13:00
) ;
}
2018-09-12 21:42:55 +12:00
var user _object = ( this . props . spotify . me && this . props . core . users [ this . props . spotify . me . uri ] ? this . props . core . users [ this . props . spotify . me . uri ] : null ) ;
2018-03-30 22:37:38 +13:00
if ( user _object ) {
var user = (
< URILink className = "user" type = "user" uri = { user _object . uri } >
< Thumbnail circle = { true } size = "small" images = { user _object . images } / >
< span className = "user-name" >
2018-09-12 21:42:55 +12:00
{ user _object . name ? user _object . name : user _object . id }
2018-03-30 22:37:38 +13:00
{ ! this . props . spotify . authorization ? < span className = "grey-text" > & nbsp ; & nbsp ; ( Limited access ) < / s p a n > : n u l l }
< / s p a n >
< / U R I L i n k >
)
} else {
var user = (
< URILink className = "user" >
< Thumbnail circle = { true } size = "small" / >
< span className = "user-name" >
Unknown
< / s p a n >
< / U R I L i n k >
)
}
var not _installed = null ;
if ( ! this . props . mopidy . uri _schemes || ! this . props . mopidy . uri _schemes . includes ( 'spotify:' ) ) {
not _installed = (
< div >
< p className = "message warning" > < em > Mopidy - Spotify < / e m > e x t e n s i o n i s n o t r u n n i n g - y o u w i l l n o t b e a b l e t o p l a y a n y S p o t i f y t r a c k s < / p >
< br / >
< / d i v >
) ;
}
return (
< div >
{ not _installed }
< div className = "field" >
< div className = "name" > Country < / d i v >
< div className = "input" >
2018-08-15 16:52:24 +12:00
< input
2018-03-30 22:37:38 +13:00
type = "text"
2018-08-15 16:52:24 +12:00
onChange = { e => this . setState ( { country : e . target . value } ) }
2018-03-30 22:37:38 +13:00
onFocus = { e => this . setState ( { input _in _focus : 'country' } ) }
2018-08-15 16:52:24 +12:00
onBlur = { e => this . props . spotifyActions . set ( { country : e . target . value } ) }
2018-03-30 22:37:38 +13:00
value = { this . state . country } / >
< div className = "description" >
An < a href = "http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2" target = "_blank" > ISO 3166 - 1 alpha - 2 < / a > c o u n t r y c o d e ( e g < e m > N Z < / e m > )
< / d i v >
< / d i v >
< / d i v >
< div className = "field" >
< div className = "name" > Locale < / d i v >
< div className = "input" >
2018-08-15 16:52:24 +12:00
< input
2018-03-30 22:37:38 +13:00
type = "text"
onChange = { e => this . setState ( { locale : e . target . value } ) }
2018-08-15 16:52:24 +12:00
onFocus = { e => this . setState ( { input _in _focus : 'locale' } ) }
onBlur = { e => this . props . spotifyActions . set ( { locale : e . target . value } ) }
2018-03-30 22:37:38 +13:00
value = { this . state . locale } / >
< div className = "description" >
Lowercase < a href = "http://en.wikipedia.org/wiki/ISO_639" target = "_blank" > ISO 639 language code < /a> and an uppercase <a href="http:/ / en . wikipedia . org / wiki / ISO _3166 - 1_ alpha - 2 " target=" _blank " > ISO 3166 - 1 alpha - 2 country code < / a > , j o i n e d b y a n u n d e r s c o r e ( e g < e m > e n _ N Z < / e m > )
< / d i v >
< / d i v >
< / d i v >
< div className = "field current-user" >
< div className = "name" > Current user < / d i v >
< div className = "input" >
< div className = "text" >
{ user }
< / d i v >
< / d i v >
2018-08-15 16:52:24 +12:00
< / d i v >
2018-03-30 22:37:38 +13:00
< div className = "field" >
< div className = "name" > Authorization < / d i v >
< div className = "input" >
< SpotifyAuthenticationFrame / >
2018-07-13 16:48:41 +12:00
{ share _authorization _button }
2018-03-30 22:37:38 +13:00
{ this . props . spotify . refreshing _token ? < button className = "working" > Refreshing ... < / b u t t o n > : < b u t t o n o n C l i c k = { e = > t h i s . p r o p s . s p o t i f y A c t i o n s . r e f r e s h i n g T o k e n ( ) } > F o r c e t o k e n r e f r e s h < / b u t t o n > }
< / d i v >
< / d i v >
< / d i v >
) ;
}
renderLastfm ( ) {
2018-08-22 08:13:08 +12:00
var user _object = ( this . props . lastfm . me ? this . props . core . users [ "lastfm:user:" + this . props . lastfm . me . name ] : null ) ;
2018-03-30 22:37:38 +13:00
if ( user _object ) {
var user = (
< span className = "user" >
2018-09-12 21:42:55 +12:00
< Thumbnail circle = { true } size = "small" images = { user _object . images } / >
2018-03-30 22:37:38 +13:00
< span className = "user-name" >
2018-09-12 21:42:55 +12:00
{ user _object . name }
2018-03-30 22:37:38 +13:00
< / s p a n >
< / s p a n >
)
} else {
var user = (
< span className = "user" >
< Thumbnail circle = { true } size = "small" / >
< span className = "user-name" >
Unknown
< / s p a n >
< / s p a n >
)
}
return (
< div >
{ this . props . lastfm . session ? < div className = "field current-user" >
< div className = "name" > Current user < / d i v >
< div className = "input" >
< div className = "text" >
{ user }
< / d i v >
< / d i v >
< / d i v > : n u l l }
< div className = "field" >
< div className = "name" > Authorization < / d i v >
< div className = "input" >
< LastfmAuthenticationFrame / >
< / d i v >
< / d i v >
< / d i v >
) ;
}
2018-08-15 16:52:24 +12:00
renderGenius ( ) {
2018-09-12 21:42:55 +12:00
var user _object = ( this . props . genius . me ? this . props . core . users [ this . props . genius . me . uri ] : null ) ;
2018-08-15 16:52:24 +12:00
if ( user _object ) {
var user = (
< span className = "user" >
2018-09-12 21:42:55 +12:00
< Thumbnail circle = { true } size = "small" images = { user _object . images } / >
2018-08-15 16:52:24 +12:00
< span className = "user-name" >
2018-08-16 08:05:06 +12:00
{ user _object . name }
2018-08-15 16:52:24 +12:00
< / s p a n >
< / s p a n >
)
} else {
var user = (
< span className = "user" >
< Thumbnail circle = { true } size = "small" / >
< span className = "user-name" >
Unknown
< / s p a n >
< / s p a n >
)
}
return (
< div >
2018-08-17 16:09:36 +12:00
{ this . props . genius . authorization ? < div className = "field current-user" >
2018-08-15 16:52:24 +12:00
< div className = "name" > Current user < / d i v >
< div className = "input" >
< div className = "text" >
{ user }
< / d i v >
< / d i v >
< / d i v > : n u l l }
< div className = "field" >
< div className = "name" > Authorization < / d i v >
< div className = "input" >
< GeniusAuthenticationFrame / >
< / d i v >
< / d i v >
< / d i v >
) ;
}
2018-03-30 22:37:38 +13:00
renderIcecast ( ) {
return (
2018-08-15 16:52:24 +12:00
< div >
2018-03-30 22:37:38 +13:00
< div className = "field checkbox" >
< div className = "name" > Enable < / d i v >
< div className = "input" >
< label >
2018-08-15 16:52:24 +12:00
< input
2018-03-30 22:37:38 +13:00
type = "checkbox"
name = "ssl"
checked = { this . props . core . http _streaming _enabled }
onChange = { e => this . props . coreActions . set ( { http _streaming _enabled : ! this . props . core . http _streaming _enabled } ) } / >
< span className = "label" >
Stream audio to this browser
< / s p a n >
< / l a b e l >
< / d i v >
< / d i v >
< div className = "field" >
< div className = "name" > Location < / d i v >
< div className = "input" >
2018-08-15 16:52:24 +12:00
< input
2018-03-30 22:37:38 +13:00
type = "text"
onChange = { e => this . props . coreActions . set ( { http _streaming _url : e . target . value } ) }
value = { this . props . core . http _streaming _url } / >
< div className = "description" >
The full URL to your stream endpoint
< / d i v >
< / d i v >
2018-08-15 16:52:24 +12:00
< / d i v >
2018-03-30 22:37:38 +13:00
< / d i v >
) ;
}
renderMenu ( ) {
2018-09-12 21:42:55 +12:00
if ( this . props . spotify . me && this . props . core . users [ this . props . spotify . me . uri ] ) {
var spotify _icon = < Thumbnail circle = { true } size = "small" images = { this . props . core . users [ this . props . spotify . me . uri ] . images } / >
2018-03-30 22:37:38 +13:00
} else {
2018-03-31 20:36:36 +13:00
var spotify _icon = < Thumbnail circle = { true } size = "small" / >
2018-03-30 22:37:38 +13:00
}
2018-09-12 21:42:55 +12:00
if ( this . props . lastfm . me && this . props . core . users [ this . props . lastfm . me . uri ] ) {
var lastfm _icon = < Thumbnail circle = { true } size = "small" images = { this . props . core . users [ this . props . lastfm . me . uri ] . images } / >
2018-03-30 22:37:38 +13:00
} else {
2018-05-20 20:42:20 +12:00
var lastfm _icon = < Icon type = "fontawesome" name = "lastfm" / >
2018-03-30 22:37:38 +13:00
}
2018-09-12 21:42:55 +12:00
if ( this . props . genius . me && this . props . core . users [ this . props . genius . me . uri ] ) {
var genius _icon = < Thumbnail circle = { true } size = "small" images = { this . props . core . users [ this . props . genius . me . uri ] . images } / >
2018-08-16 08:05:06 +12:00
} else {
2018-08-22 08:13:08 +12:00
var genius _icon = < Icon name = "genius" type = "svg" / >
2018-08-16 08:05:06 +12:00
}
2018-08-15 16:52:24 +12:00
2018-03-30 22:37:38 +13:00
return (
< div className = "menu" >
< div className = "menu-item-wrapper" >
< Link className = { "menu-item" + ( this . props . active == 'spotify' ? ' active' : '' ) } to = { this . props . active == 'spotify' ? global . baseURL + 'settings' : global . baseURL + 'settings/service/spotify' } >
2018-03-31 20:36:36 +13:00
{ spotify _icon }
2018-03-30 22:37:38 +13:00
< div className = "title" >
Spotify
< / d i v >
{ this . props . spotify . authorization ? < span className = "status green-text" > Authorized < / s p a n > : < s p a n c l a s s N a m e = " s t a t u s g r e y - t e x t " > R e a d - o n l y < / s p a n > }
< / L i n k >
< / d i v >
< div className = "menu-item-wrapper" >
< Link className = { "menu-item" + ( this . props . active == 'lastfm' ? ' active' : '' ) } to = { this . props . active == 'lastfm' ? global . baseURL + 'settings' : global . baseURL + 'settings/service/lastfm' } >
2018-03-31 20:36:36 +13:00
{ lastfm _icon }
2018-03-30 22:37:38 +13:00
< div className = "title" >
LastFM
< / d i v >
{ this . props . lastfm . session ? < span className = "status green-text" > Authorized < / s p a n > : < s p a n c l a s s N a m e = " s t a t u s g r e y - t e x t " > R e a d - o n l y < / s p a n > }
< / L i n k >
< / d i v >
2018-08-15 16:52:24 +12:00
< div className = "menu-item-wrapper" >
< Link className = { "menu-item" + ( this . props . active == 'genius' ? ' active' : '' ) } to = { this . props . active == 'genius' ? global . baseURL + 'settings' : global . baseURL + 'settings/service/genius' } >
{ genius _icon }
< div className = "title" >
Genius
< / d i v >
2018-08-17 16:09:36 +12:00
{ this . props . genius . authorization ? < span className = "status green-text" > Authorized < / s p a n > : < s p a n c l a s s N a m e = " s t a t u s g r e y - t e x t " > U n a u t h o r i z e d < / s p a n > }
2018-08-15 16:52:24 +12:00
< / L i n k >
< / d i v >
2018-03-30 22:37:38 +13:00
< div className = "menu-item-wrapper" >
< Link className = { "menu-item" + ( this . props . active == 'snapcast' ? ' active' : '' ) } to = { this . props . active == 'snapcast' ? global . baseURL + 'settings' : global . baseURL + 'settings/service/snapcast' } >
2018-07-01 21:08:35 +12:00
< Icon name = "devices" / >
2018-03-30 22:37:38 +13:00
< div className = "title" >
Snapcast
< / d i v >
{ this . props . pusher . config . snapcast _enabled ? < span className = "status green-text" > Enabled < / s p a n > : < s p a n c l a s s N a m e = " s t a t u s g r e y - t e x t " > D i s a b l e d < / s p a n > }
< / L i n k >
< / d i v >
< div className = "menu-item-wrapper" >
< Link className = { "menu-item" + ( this . props . active == 'icecast' ? ' active' : '' ) } to = { this . props . active == 'icecast' ? global . baseURL + 'settings' : global . baseURL + 'settings/service/icecast' } >
2018-07-01 21:08:35 +12:00
< Icon name = "wifi_tethering" / >
2018-03-30 22:37:38 +13:00
< div className = "title" >
Icecast
< / d i v >
{ this . props . core . http _streaming _enabled ? < span className = "status green-text" > Enabled < / s p a n > : < s p a n c l a s s N a m e = " s t a t u s g r e y - t e x t " > D i s a b l e d < / s p a n > }
< / L i n k >
< / d i v >
< / d i v >
) ;
}
renderService ( ) {
var service = null ;
switch ( this . props . active ) {
case 'spotify' :
service = this . renderSpotify ( ) ;
break ;
case 'lastfm' :
service = this . renderLastfm ( ) ;
break ;
2018-08-15 16:52:24 +12:00
case 'genius' :
service = this . renderGenius ( ) ;
break ;
2018-03-30 22:37:38 +13:00
case 'icecast' :
service = this . renderIcecast ( ) ;
break ;
case 'snapcast' :
service = < Snapcast / >
break ;
}
if ( service ) {
return (
< div className = "service" >
{ service }
< / d i v >
) ;
} else {
return null ;
}
}
render ( ) {
return (
< div className = "services" >
{ this . renderMenu ( ) }
{ this . renderService ( ) }
< / d i v >
) ;
}
}
const mapStateToProps = ( state , ownProps ) => {
return state
}
const mapDispatchToProps = ( dispatch ) => {
return {
coreActions : bindActionCreators ( coreActions , dispatch ) ,
uiActions : bindActionCreators ( uiActions , dispatch ) ,
pusherActions : bindActionCreators ( pusherActions , dispatch ) ,
mopidyActions : bindActionCreators ( mopidyActions , dispatch ) ,
spotifyActions : bindActionCreators ( spotifyActions , dispatch ) ,
2018-08-15 16:52:24 +12:00
lastfmActions : bindActionCreators ( lastfmActions , dispatch ) ,
geniusActions : bindActionCreators ( geniusActions , dispatch )
2018-03-30 22:37:38 +13:00
}
}
2018-08-15 16:52:24 +12:00
export default connect ( mapStateToProps , mapDispatchToProps ) ( Services )