2016-10-17 10:39:11 +13:00
2019-02-10 19:51:33 +13:00
import React from 'react' ;
2019-01-09 16:56:35 +13:00
import { connect } from 'react-redux' ;
import { bindActionCreators } from 'redux' ;
2019-01-14 16:50:21 +13:00
import { Route , Link } from 'react-router-dom' ;
2016-11-29 15:36:01 +13:00
2019-04-16 20:06:56 +12:00
import ConfirmationButton from '../components/Fields/ConfirmationButton' ;
import PusherConnectionList from '../components/PusherConnectionList' ;
import SourcesPriority from '../components/Fields/SourcesPriority' ;
import Commands from '../components/Fields/Commands' ;
2019-05-10 10:34:58 +12:00
import TextField from '../components/Fields/TextField' ;
2019-04-16 20:06:56 +12:00
import Header from '../components/Header' ;
import Icon from '../components/Icon' ;
import Services from '../components/Services' ;
import * as helpers from '../helpers' ;
import * as coreActions from '../services/core/actions' ;
import * as uiActions from '../services/ui/actions' ;
import * as pusherActions from '../services/pusher/actions' ;
import * as mopidyActions from '../services/mopidy/actions' ;
import * as lastfmActions from '../services/lastfm/actions' ;
import * as spotifyActions from '../services/spotify/actions' ;
2017-08-05 22:25:25 +12:00
2019-09-05 15:36:11 +12:00
class Settings extends React . Component {
constructor ( props ) {
super ( props ) ;
this . state = {
mopidy _host : this . props . mopidy . host ,
mopidy _port : this . props . mopidy . port ,
mopidy _library _artists _uri : this . props . mopidy . library _artists _uri ,
mopidy _library _albums _uri : this . props . mopidy . library _albums _uri ,
pusher _username : this . props . pusher . username ,
input _in _focus : null ,
} ;
}
componentDidMount ( ) {
this . props . uiActions . setWindowTitle ( 'Settings' ) ;
}
componentWillReceiveProps ( nextProps ) {
let changed = false ;
const { state } = this ;
if ( nextProps . pusher . username && nextProps . pusher . username != this . state . pusher _username && this . state . input _in _focus != 'pusher_username' ) {
state . pusher _username = nextProps . pusher . username ;
changed = true ;
}
if ( changed ) {
this . setState ( state ) ;
}
}
resetAllSettings ( ) {
localStorage . clear ( ) ;
window . location = '#' ;
window . location . reload ( true ) ;
return false ;
}
setConfig ( e ) {
this . setState ( { input _in _focus : null } ) ;
e . preventDefault ( ) ;
this . props . mopidyActions . set ( {
host : this . state . mopidy _host ,
port : this . state . mopidy _port ,
} ) ;
window . location . reload ( true ) ;
return false ;
}
handleBlur ( service , name , value ) {
this . setState ( { input _in _focus : null } ) ;
const data = { } ;
data [ name ] = value ;
this . props [ ` ${ service } Actions ` ] . set ( data ) ;
// Any per-field actions
switch ( name ) {
case 'library_albums_uri' :
this . props . mopidyActions . clearLibraryAlbums ( ) ;
break ;
case 'library_artists_uri' :
this . props . mopidyActions . clearLibraryArtists ( ) ;
break ;
}
}
renderApplyButton ( ) {
if ( this . props . mopidy . host == this . state . mopidy _host
&& this . props . mopidy . port == this . state . mopidy _port ) {
return null ;
}
return (
< div className = "field" >
< div className = "name" / >
< div className = "input" >
< button type = "submit" className = "button button--secondary" > Apply and reload < / b u t t o n >
< / d i v >
< / d i v >
) ;
}
renderServerStatus ( ) {
let colour = 'grey' ;
let icon = 'help' ;
let status = 'Unknown' ;
let className = null ;
if ( this . props . mopidy . connecting || this . props . pusher . connecting ) {
icon = 'autorenew' ;
status = 'Connecting...' ;
className = 'icon--spin' ;
} else if ( ! this . props . mopidy . connected || ! this . props . pusher . connected ) {
colour = 'red' ;
icon = 'close' ;
status = 'Disconnected' ;
} else if ( this . props . mopidy . connected && this . props . pusher . connected ) {
colour = 'green' ;
icon = 'check' ;
status = 'Connected' ;
}
return (
< span className = { ` ${ colour } -text ` } >
< Icon className = { className } name = { icon } / >
{ ' ' }
{ status }
< / s p a n >
) ;
}
render ( ) {
const options = (
< span >
< a className = "button button--default button--no-hover" onClick = { ( e ) => this . props . history . push ( '/settings/debug' ) } >
< Icon name = "code" / >
Debug
< / a >
< a className = "button button--default button--no-hover" href = "https://github.com/jaedb/Iris/wiki" target = "_blank" >
< Icon name = "help" / >
Help
< / a >
< / s p a n >
) ;
return (
< div className = "view settings-view" >
< Header options = { options } uiActions = { this . props . uiActions } >
< Icon name = "settings" type = "material" / >
2018-05-15 21:30:57 +12:00
Settings
2019-09-05 15:36:11 +12:00
< / H e a d e r >
< section className = "content-wrapper" >
< h4 className = "underline" >
Server
< a name = "server" / >
< / h 4 >
< div className = "field" >
< div className = "name" > Status < / d i v >
< div className = "input" >
< div className = "text" >
{ this . renderServerStatus ( ) }
< / d i v >
< / d i v >
< / d i v >
< label className = "field" >
< div className = "name" > Username < / d i v >
< div className = "input" >
< TextField
onChange = { ( value ) => this . props . pusherActions . setUsername ( value . replace ( /\W/g , '' ) ) }
value = { this . state . pusher _username }
/ >
< div className = "description" >
2017-09-27 15:39:55 +13:00
A non - unique string used to identify this client ( no special characters )
2019-09-05 15:36:11 +12:00
< / d i v >
< / d i v >
< / l a b e l >
< form onSubmit = { ( e ) => this . setConfig ( e ) } >
< label className = "field" >
< div className = "name" > Host < / d i v >
< div className = "input" >
< input
type = "text"
onChange = { ( e ) => this . setState ( { mopidy _host : e . target . value } ) }
onFocus = { ( e ) => this . setState ( { input _in _focus : 'mopidy_host' } ) }
onBlur = { ( e ) => this . setState ( { input _in _focus : null } ) }
value = { this . state . mopidy _host }
/ >
< / d i v >
< / l a b e l >
< label className = "field" >
< div className = "name" > Port < / d i v >
< div className = "input" >
< input
type = "text"
onChange = { ( e ) => this . setState ( { mopidy _port : e . target . value } ) }
onFocus = { ( e ) => this . setState ( { input _in _focus : 'mopidy_port' } ) }
onBlur = { ( e ) => this . setState ( { input _in _focus : null } ) }
value = { this . state . mopidy _port }
/ >
< / d i v >
< / l a b e l >
{ this . renderApplyButton ( ) }
< / f o r m >
< h4 className = "underline" >
Services
< a name = "services" / >
< / h 4 >
< Route path = "/settings/:service?" component = { Services } / >
< h4 className = "underline" >
Interface
< a name = "interface" / >
< / h 4 >
< div className = "field radio" >
< div className = "name" >
2018-08-24 16:10:41 +12:00
Theme
2019-09-05 15:36:11 +12:00
< / d i v >
< div className = "input" >
< label >
< input
type = "radio"
name = "theme"
value = "dark"
checked = { this . props . ui . theme == 'dark' }
onChange = { ( e ) => this . props . uiActions . set ( { theme : e . target . value } ) }
/ >
< span className = "label" > Dark < / s p a n >
< / l a b e l >
< label >
< input
type = "radio"
name = "theme"
value = "light"
checked = { this . props . ui . theme == 'light' }
onChange = { ( e ) => this . props . uiActions . set ( { theme : e . target . value } ) }
/ >
< span className = "label" > Light < / s p a n >
< / l a b e l >
< / d i v >
< / d i v >
< div className = "field checkbox" >
< div className = "name" > Behavior < / d i v >
< div className = "input" >
< label >
< input
type = "checkbox"
name = "log_actions"
checked = { this . props . ui . clear _tracklist _on _play }
onChange = { ( e ) => this . props . uiActions . set ( { clear _tracklist _on _play : ! this . props . ui . clear _tracklist _on _play } ) }
/ >
< span className = "label tooltip" >
2017-11-19 20:38:36 +13:00
Clear tracklist on play of URI ( s )
2019-09-05 15:36:11 +12:00
< span className = "tooltip__content" > Playing one or more URIs will clear the current play queue first < / s p a n >
< / s p a n >
< / l a b e l >
< label >
< input
type = "checkbox"
name = "hotkeys_enabled"
checked = { this . props . ui . hotkeys _enabled }
onChange = { ( e ) => this . props . uiActions . set ( { hotkeys _enabled : ! this . props . ui . hotkeys _enabled } ) }
/ >
< span className = "label" >
2019-05-10 10:34:58 +12:00
Enable hotkeys
2019-09-05 15:36:11 +12:00
< / s p a n >
< / l a b e l >
< label >
< input
type = "checkbox"
name = "smooth_scrolling_enabled"
checked = { this . props . ui . smooth _scrolling _enabled }
onChange = { ( e ) => this . props . uiActions . set ( { smooth _scrolling _enabled : ! this . props . ui . smooth _scrolling _enabled } ) }
/ >
< span className = "label" >
2019-02-08 16:05:43 +13:00
Enable smooth scrolling
2019-09-05 15:36:11 +12:00
< / s p a n >
< / l a b e l >
< label >
< input
type = "checkbox"
name = "playback_controls_touch_enabled"
checked = { this . props . ui . playback _controls _touch _enabled }
onChange = { ( e ) => this . props . uiActions . set ( { playback _controls _touch _enabled : ! this . props . ui . playback _controls _touch _enabled } ) }
/ >
< span className = "label tooltip" >
2019-08-18 16:51:22 +12:00
Enable touch events on play controls
2019-09-05 15:36:11 +12:00
< span className = "tooltip__content" > Allows left - and right - swipe to change tracks < / s p a n >
< / s p a n >
< / l a b e l >
< label >
< input
type = "checkbox"
name = "wide_scrollbar_enabled"
checked = { this . props . ui . wide _scrollbar _enabled }
onChange = { ( e ) => this . props . uiActions . set ( { wide _scrollbar _enabled : ! this . props . ui . wide _scrollbar _enabled } ) }
/ >
< span className = "label" >
2019-06-14 11:32:56 +12:00
Use wide scrollbars
2019-09-05 15:36:11 +12:00
< / s p a n >
< / l a b e l >
< / d i v >
< / d i v >
2017-08-05 22:25:25 +12:00
2019-09-05 15:36:11 +12:00
< div className = "field sources-priority" >
< div className = "name" >
2018-06-11 08:15:55 +12:00
Sources priority
2019-09-05 15:36:11 +12:00
< / d i v >
< div className = "input" >
< SourcesPriority
uri _schemes = { this . props . mopidy . uri _schemes ? this . props . mopidy . uri _schemes : [ ] }
uri _schemes _priority = { this . props . ui . uri _schemes _priority ? this . props . ui . uri _schemes _priority : [ ] }
uiActions = { this . props . uiActions }
/ >
< div className = "description" >
2018-09-18 21:38:37 +12:00
Drag - and - drop to prioritize search providers and results
2019-09-05 15:36:11 +12:00
< / d i v >
< / d i v >
< / d i v >
{ helpers . isHosted ( ) ? null : (
< div className = "field checkbox" >
< div className = "name" > Reporting < / d i v >
< div className = "input" >
< label >
< input
type = "checkbox"
name = "allow_reporting"
checked = { this . props . ui . allow _reporting }
onChange = { ( e ) => this . props . uiActions . set ( { allow _reporting : ! this . props . ui . allow _reporting } ) }
/ >
< span className = "label" >
2018-09-18 21:38:37 +12:00
Allow reporting of anonymous usage statistics
2019-09-05 15:36:11 +12:00
< / s p a n >
< / l a b e l >
< div className = "description" >
This helps identify errors and potential features that make Iris better for everyone . See
< a href = "https://github.com/jaedb/Iris/wiki/Terms-of-use#privacy-policy" target = "_blank" > privacy policy < / a >
.
< / d i v >
< / d i v >
< / d i v >
) }
< div className = "field commands-setup" id = "commands-setup" >
< div className = "name" >
2018-10-09 21:39:38 +13:00
Commands
2019-09-05 15:36:11 +12:00
< / d i v >
< div className = "input" >
< Commands
commands = { this . props . pusher . commands }
runCommand = { ( id , notify ) => this . props . pusherActions . runCommand ( id , notify ) }
onChange = { ( commands ) => this . props . pusherActions . setCommands ( commands ) }
/ >
< Link to = "/edit-command" className = "button button--default" > Add new < / L i n k >
< / d i v >
< / d i v >
< h4 className = "underline" >
Advanced
< a name = "advanced" / >
< / h 4 >
< div className = "field" >
< div className = "name" > Artist library URI < / d i v >
< div className = "input" >
< input
type = "text"
value = { this . state . mopidy _library _artists _uri }
onChange = { ( e ) => this . setState ( { mopidy _library _artists _uri : e . target . value } ) }
onBlur = { ( e ) => this . handleBlur ( 'mopidy' , 'library_artists_uri' , e . target . value ) }
/ >
< div className = "description" >
2018-10-16 21:21:36 +13:00
URI used for collecting library artists
2019-09-05 15:36:11 +12:00
< / d i v >
< / d i v >
< / d i v >
< label className = "field" >
< div className = "name" > Album library URI < / d i v >
< div className = "input" >
< input
type = "text"
value = { this . state . mopidy _library _albums _uri }
onChange = { ( e ) => this . setState ( { mopidy _library _albums _uri : e . target . value } ) }
onBlur = { ( e ) => this . handleBlur ( 'mopidy' , 'library_albums_uri' , e . target . value ) }
/ >
< div className = "description" >
2018-10-16 21:21:36 +13:00
URI used for collecting library albums
2019-09-05 15:36:11 +12:00
< / d i v >
< / d i v >
< / l a b e l >
< div className = "field pusher-connections" >
< div className = "name" > Connections < / d i v >
< div className = "input" >
< div className = "text" >
< PusherConnectionList / >
< / d i v >
< / d i v >
< / d i v >
< div className = "field" >
< div className = "name" > Version < / d i v >
< div className = "input" >
< span className = "text" >
{ this . props . pusher . version . current }
{ ' ' }
installed
{ this . props . pusher . version . upgrade _available ? (
< span className = "flag dark" >
< Icon name = "cloud_download" className = "blue-text" / >
& nbsp ; Upgrade available
< / s p a n >
) : (
< span className = "flag dark" >
< Icon name = "check" className = "green-text" / >
& nbsp ; Up - to - date
< / s p a n >
) }
< / s p a n >
< / d i v >
< / d i v >
< div className = "field" >
< button className = "button button--default" onClick = { ( e ) => this . props . pusherActions . localScan ( ) } > Run local scan < / b u t t o n >
< Link className = "button button--default" to = "/share-configuration" > Share configuration < / L i n k >
< / d i v >
< div className = "field" >
{ this . props . pusher . version . upgrade _available ? (
< button className = "button button--secondary" onClick = { ( e ) => this . props . pusherActions . upgrade ( ) } >
Upgrade to
{ this . props . pusher . version . latest }
< / b u t t o n >
) : null }
< button className = { ` button button--destructive ${ this . props . mopidy . restarting ? ' button--working' : '' } ` } onClick = { ( e ) => this . props . pusherActions . restart ( ) } > Restart server < / b u t t o n >
< ConfirmationButton className = "button--destructive" content = "Reset all settings" confirmingContent = "Are you sure?" onConfirm = { ( ) => this . resetAllSettings ( ) } / >
< / d i v >
< h4 className = "underline" >
About
< a name = "about" / >
< / h 4 >
< div className = "field" >
< div >
< em > < a href = "https://github.com/jaedb/Iris" target = "_blank" > Iris < / a > < / e m >
{ ' ' }
is an open - source project by
< a href = "https://github.com/jaedb" target = "_blank" > James Barnsley < / a >
. It is provided free and with absolutely no warranty . If you paid someone for this software , please let me know .
< / d i v >
< br / >
< br / >
< div >
< a className = "button button--default" href = "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=james%40barnsley%2enz&lc=NZ&item_name=James%20Barnsley¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted" target = "_blank" >
< Icon type = "fontawesome" name = "paypal" / >
{ ' ' }
Donate
< / a >
< a className = "button button--default" href = "https://github.com/jaedb/Iris" target = "_blank" >
< Icon type = "fontawesome" name = "github" / >
{ ' ' }
GitHub
< / a >
< a className = "button button--default" href = "http://creativecommons.org/licenses/by-nc/4.0/" target = "_blank" >
< Icon type = "fontawesome" name = "creative-commons" / >
& nbsp ; Licence
< / a >
< / d i v >
< / d i v >
< / s e c t i o n >
< / d i v >
) ;
}
2017-08-05 22:25:25 +12:00
}
2019-09-05 15:36:11 +12:00
const mapStateToProps = ( state , ownProps ) => state ;
2017-08-05 22:25:25 +12:00
2019-09-05 15:36:11 +12:00
const mapDispatchToProps = ( dispatch ) => ( {
coreActions : bindActionCreators ( coreActions , dispatch ) ,
uiActions : bindActionCreators ( uiActions , dispatch ) ,
pusherActions : bindActionCreators ( pusherActions , dispatch ) ,
mopidyActions : bindActionCreators ( mopidyActions , dispatch ) ,
lastfmActions : bindActionCreators ( lastfmActions , dispatch ) ,
spotifyActions : bindActionCreators ( spotifyActions , dispatch ) ,
} ) ;
2017-08-05 22:25:25 +12:00
2019-09-05 15:36:11 +12:00
export default connect ( mapStateToProps , mapDispatchToProps ) ( Settings ) ;