Moving providers into subset 'Services'
This commit is contained in:
@ -5463,6 +5463,71 @@ main header {
|
||||
white-space: wrap;
|
||||
max-width: 200px; }
|
||||
|
||||
.services .menu {
|
||||
margin: 0 -10px;
|
||||
display: flex;
|
||||
flex-wrap: wrap; }
|
||||
.services .menu::after {
|
||||
content: '';
|
||||
clear: both;
|
||||
display: block; }
|
||||
.services .menu .menu-item-wrapper {
|
||||
width: 25%;
|
||||
max-width: 200px;
|
||||
padding: 10px;
|
||||
display: block;
|
||||
box-sizing: border-box; }
|
||||
.services .menu .menu-item-wrapper .menu-item {
|
||||
-webkit-transition: all 0.2s ease-in-out;
|
||||
-moz-transition: all 0.2s ease-in-out;
|
||||
-o-transition: all 0.2s ease-in-out;
|
||||
transition: all 0.2s ease-in-out;
|
||||
position: relative;
|
||||
padding: 30px 10px;
|
||||
border-radius: 3px;
|
||||
background: #121212;
|
||||
display: block;
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
border: 0; }
|
||||
.services .menu .menu-item-wrapper .menu-item:hover {
|
||||
background: #222222; }
|
||||
.services .menu .menu-item-wrapper .menu-item.active {
|
||||
background: #222222;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0; }
|
||||
.services .menu .menu-item-wrapper .menu-item.active:after {
|
||||
height: 10px;
|
||||
bottom: -10px; }
|
||||
.services .menu .menu-item-wrapper .menu-item:after {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: #222222; }
|
||||
.services .menu .menu-item-wrapper .menu-item .thumbnail {
|
||||
margin-bottom: 15px;
|
||||
display: inline-block; }
|
||||
.services .menu .menu-item-wrapper .menu-item .fa {
|
||||
font-size: 40px;
|
||||
height: 40px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 15px; }
|
||||
.services .menu .menu-item-wrapper .menu-item .title {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-weight: bold;
|
||||
font-size: 16px; }
|
||||
|
||||
.services .service {
|
||||
padding: 20px 20px 10px 20px;
|
||||
border-radius: 0 0 3px 3px;
|
||||
background: #222222; }
|
||||
|
||||
.artist-view .body-loader:not(.lazy-loader) {
|
||||
padding: 15vh 0; }
|
||||
|
||||
@ -6149,36 +6214,6 @@ main .track-view {
|
||||
.settings-view .content-wrapper {
|
||||
padding-top: 0; }
|
||||
|
||||
.settings-view .services {
|
||||
margin-bottom: -20px; }
|
||||
.settings-view .services::after {
|
||||
content: '';
|
||||
clear: both;
|
||||
display: block; }
|
||||
.settings-view .services .service {
|
||||
margin-right: 20px;
|
||||
margin-bottom: 20px;
|
||||
padding-left: 46px;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
float: left;
|
||||
min-width: 150px; }
|
||||
.settings-view .services .service .title {
|
||||
margin: 0;
|
||||
padding: 0; }
|
||||
.settings-view .services .service .icon {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 0;
|
||||
width: 34px;
|
||||
height: 25px;
|
||||
padding-top: 9px;
|
||||
border: 2px solid #383734;
|
||||
text-align: center;
|
||||
border-radius: 50%; }
|
||||
.settings-view .services .service .icon .fa {
|
||||
font-size: 16px; }
|
||||
|
||||
.settings-view .field.current-user .text .user {
|
||||
border: 0;
|
||||
position: relative; }
|
||||
@ -6208,19 +6243,6 @@ main .track-view {
|
||||
padding: 15vh 20px 0; }
|
||||
.settings-view .content-wrapper {
|
||||
padding-bottom: 60px; }
|
||||
.settings-view .services {
|
||||
text-align: center; }
|
||||
.settings-view .services .service {
|
||||
padding: 40px 0 0 0;
|
||||
text-align: center;
|
||||
min-width: 100px;
|
||||
display: inline-block;
|
||||
margin-right: 0;
|
||||
float: none; }
|
||||
.settings-view .services .service .icon {
|
||||
top: 0;
|
||||
left: 50%;
|
||||
margin-left: -18px; }
|
||||
.settings-view .field.pusher-connections .connection .col {
|
||||
width: auto;
|
||||
display: inline-block;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -38,7 +38,7 @@
|
||||
|
||||
// Release details
|
||||
// These are automatically injected to built HTML
|
||||
var build = "1521931467";
|
||||
var build = "1522395485";
|
||||
var version = "3.15.0";
|
||||
|
||||
// Construct the script tag
|
||||
|
||||
@ -93,7 +93,7 @@ class App extends React.Component{
|
||||
// TODO: Detect if we've gone BACK, and then restore to previous
|
||||
// scroll position. We'll need to keep a running history of locations
|
||||
// and scroll positions, which may be performance-hindering
|
||||
$(window).scrollTop(0)
|
||||
//$(window).scrollTop(0)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
374
src/js/components/Services.js
Executable file
374
src/js/components/Services.js
Executable file
@ -0,0 +1,374 @@
|
||||
|
||||
import React, { PropTypes } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import { Link } from 'react-router'
|
||||
import { bindActionCreators } from 'redux'
|
||||
import FontAwesome from 'react-fontawesome'
|
||||
|
||||
import Thumbnail from './Thumbnail'
|
||||
import Icon from './Icon'
|
||||
import URILink from './URILink'
|
||||
import SpotifyAuthenticationFrame from '../components/SpotifyAuthenticationFrame'
|
||||
import LastfmAuthenticationFrame from '../components/LastfmAuthenticationFrame'
|
||||
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'
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
componentWillReceiveProps(newProps){
|
||||
var changed = false
|
||||
var state = this.state
|
||||
|
||||
if (newProps.spotify.country != this.state.country && this.state.input_in_focus != 'country'){
|
||||
state.country = newProps.spotify.country
|
||||
changed = true
|
||||
}
|
||||
|
||||
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(){
|
||||
var authorization_button = null;
|
||||
var send_authorization_button = null;
|
||||
if (this.props.spotify.authorization){
|
||||
authorization_button = (
|
||||
<button onClick={e => this.props.uiActions.openModal('send_authorization', {}) }>
|
||||
Share authentication
|
||||
</button>
|
||||
);
|
||||
send_authorization_button = (
|
||||
<button onClick={e => this.props.uiActions.openModal('send_authorization', {}) }>
|
||||
Share authentication
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
var user_object = this.props.spotify.me;
|
||||
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">
|
||||
{user_object.display_name ? user_object.display_name : user_object.id}
|
||||
{!this.props.spotify.authorization ? <span className="grey-text"> (Limited access)</span> : null}
|
||||
</span>
|
||||
</URILink>
|
||||
)
|
||||
} else {
|
||||
var user = (
|
||||
<URILink className="user">
|
||||
<Thumbnail circle={true} size="small" />
|
||||
<span className="user-name">
|
||||
Unknown
|
||||
</span>
|
||||
</URILink>
|
||||
)
|
||||
}
|
||||
|
||||
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</em> extension is not running - you will not be able to play any Spotify tracks</p>
|
||||
<br />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{not_installed}
|
||||
<div className="field">
|
||||
<div className="name">Country</div>
|
||||
<div className="input">
|
||||
<input
|
||||
type="text"
|
||||
onChange={e => this.setState({country: e.target.value})}
|
||||
onFocus={e => this.setState({input_in_focus: 'country'})}
|
||||
onBlur={e => this.props.spotifyActions.set({country: e.target.value})}
|
||||
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> country code (eg <em>NZ</em>)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="field">
|
||||
<div className="name">Locale</div>
|
||||
<div className="input">
|
||||
<input
|
||||
type="text"
|
||||
onChange={e => this.setState({locale: e.target.value})}
|
||||
onFocus={e => this.setState({input_in_focus: 'locale'})}
|
||||
onBlur={e => this.props.spotifyActions.set({locale: e.target.value})}
|
||||
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>, joined by an underscore (eg <em>en_NZ</em>)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="field current-user">
|
||||
<div className="name">Current user</div>
|
||||
<div className="input">
|
||||
<div className="text">
|
||||
{user}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="field">
|
||||
<div className="name">Authorization</div>
|
||||
<div className="input">
|
||||
<SpotifyAuthenticationFrame />
|
||||
{send_authorization_button}
|
||||
{this.props.spotify.refreshing_token ? <button className="working">Refreshing...</button> : <button onClick={e => this.props.spotifyActions.refreshingToken()}>Force token refresh</button>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderLastfm(){
|
||||
var user_object = this.props.core.users["lastfm:user:"+this.props.lastfm.session.name];
|
||||
if (user_object){
|
||||
var user = (
|
||||
<span className="user">
|
||||
<Thumbnail circle={true} size="small" images={user_object.image} />
|
||||
<span className="user-name">
|
||||
{user_object.realname ? user_object.realname : user_object.name}
|
||||
</span>
|
||||
</span>
|
||||
)
|
||||
} else {
|
||||
var user = (
|
||||
<span className="user">
|
||||
<Thumbnail circle={true} size="small" />
|
||||
<span className="user-name">
|
||||
Unknown
|
||||
</span>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{this.props.lastfm.session ? <div className="field current-user">
|
||||
<div className="name">Current user</div>
|
||||
<div className="input">
|
||||
<div className="text">
|
||||
{user}
|
||||
</div>
|
||||
</div>
|
||||
</div> : null}
|
||||
|
||||
<div className="field">
|
||||
<div className="name">Authorization</div>
|
||||
<div className="input">
|
||||
<LastfmAuthenticationFrame />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderIcecast(){
|
||||
return (
|
||||
<div>
|
||||
<div className="field checkbox">
|
||||
<div className="name">Enable</div>
|
||||
<div className="input">
|
||||
<label>
|
||||
<input
|
||||
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
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className="field radio">
|
||||
<div className="name">Encoding</div>
|
||||
<div className="input">
|
||||
<label>
|
||||
<input
|
||||
type="radio"
|
||||
name="http_streaming_encoding"
|
||||
checked={this.props.core.http_streaming_encoding == 'mpeg'}
|
||||
onChange={e => this.props.coreActions.set({http_streaming_encoding: 'mpeg'})} />
|
||||
<span className="label">mpeg (mp3)</span>
|
||||
</label>
|
||||
<label>
|
||||
<input
|
||||
type="radio"
|
||||
name="http_streaming_encoding"
|
||||
checked={this.props.core.http_streaming_encoding == 'ogg'}
|
||||
onChange={e => this.props.coreActions.set({http_streaming_encoding: 'ogg'})} />
|
||||
<span className="label">ogg</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="field">
|
||||
<div className="name">Location</div>
|
||||
<div className="input">
|
||||
<input
|
||||
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
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderMenu(){
|
||||
|
||||
if (this.props.spotify.me){
|
||||
var spotify_user = <Thumbnail circle={true} size="small" images={this.props.spotify.me.images} />
|
||||
} else {
|
||||
var spotify_user = <Thumbnail circle={true} size="small" />
|
||||
}
|
||||
|
||||
if (this.props.core.users["lastfm:user:"+this.props.lastfm.session.name]){
|
||||
var lastfm_user = <Thumbnail circle={true} size="small" images={this.props.core.users["lastfm:user:"+this.props.lastfm.session.name].image} />
|
||||
} else {
|
||||
var lastfm_user = <Thumbnail circle={true} size="small" />
|
||||
}
|
||||
|
||||
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'}>
|
||||
{spotify_user}
|
||||
<div className="title">
|
||||
Spotify
|
||||
</div>
|
||||
{this.props.spotify.authorization ? <span className="status green-text">Authorized</span> : <span className="status grey-text">Read-only</span>}
|
||||
</Link>
|
||||
</div>
|
||||
<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'}>
|
||||
{lastfm_user}
|
||||
<div className="title">
|
||||
LastFM
|
||||
</div>
|
||||
{this.props.lastfm.session ? <span className="status green-text">Authorized</span> : <span className="status grey-text">Read-only</span>}
|
||||
</Link>
|
||||
</div>
|
||||
<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'}>
|
||||
<FontAwesome name="rss" />
|
||||
<div className="title">
|
||||
Snapcast
|
||||
</div>
|
||||
{this.props.pusher.config.snapcast_enabled ? <span className="status green-text">Enabled</span> : <span className="status grey-text">Disabled</span>}
|
||||
</Link>
|
||||
</div>
|
||||
<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'}>
|
||||
<FontAwesome name="rss" />
|
||||
<div className="title">
|
||||
Icecast
|
||||
</div>
|
||||
{this.props.core.http_streaming_enabled ? <span className="status green-text">Enabled</span> : <span className="status grey-text">Disabled</span>}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderService(){
|
||||
var service = null;
|
||||
switch (this.props.active){
|
||||
case 'spotify':
|
||||
service = this.renderSpotify();
|
||||
break;
|
||||
case 'lastfm':
|
||||
service = this.renderLastfm();
|
||||
break;
|
||||
case 'icecast':
|
||||
service = this.renderIcecast();
|
||||
break;
|
||||
case 'snapcast':
|
||||
service = <Snapcast />
|
||||
break;
|
||||
}
|
||||
|
||||
if (service){
|
||||
return (
|
||||
<div className="service">
|
||||
{service}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
render(){
|
||||
return (
|
||||
<div className="services">
|
||||
{this.renderMenu()}
|
||||
{this.renderService()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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),
|
||||
lastfmActions: bindActionCreators(lastfmActions, dispatch)
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Services)
|
||||
@ -1,43 +0,0 @@
|
||||
|
||||
import React, { PropTypes } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import { createStore, bindActionCreators } from 'redux'
|
||||
|
||||
import FontAwesome from 'react-fontawesome'
|
||||
|
||||
class URISchemesList extends React.Component{
|
||||
|
||||
constructor(props){
|
||||
super(props)
|
||||
}
|
||||
|
||||
render(){
|
||||
if (!this.props.uri_schemes ) return null;
|
||||
|
||||
return (
|
||||
<div className="uri-schemes-list">
|
||||
{
|
||||
this.props.uri_schemes.map((scheme, index) => {
|
||||
scheme = scheme.replace(':','')
|
||||
return (
|
||||
<span key={index+'_'+scheme}>
|
||||
{ index > 0 ? <span>, </span> : null }
|
||||
<span className="uri-scheme">
|
||||
{ scheme }
|
||||
</span>
|
||||
</span>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state, ownProps) => {
|
||||
return {
|
||||
uri_schemes: (state.mopidy.uri_schemes ? state.mopidy.uri_schemes : [])
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(URISchemesList)
|
||||
@ -20,9 +20,9 @@ import User from './views/User'
|
||||
import Track from './views/Track'
|
||||
import Queue from './views/Queue'
|
||||
import QueueHistory from './views/QueueHistory'
|
||||
import Settings from './views/Settings'
|
||||
import Debug from './views/Debug'
|
||||
import Search from './views/Search'
|
||||
import Settings from './views/Settings'
|
||||
|
||||
import DiscoverRecommendations from './views/discover/DiscoverRecommendations'
|
||||
import DiscoverFeatured from './views/discover/DiscoverFeatured'
|
||||
@ -61,9 +61,8 @@ ReactDOM.render(
|
||||
<IndexRoute component={Queue} />
|
||||
<Route path="queue" component={Queue} />
|
||||
<Route path="queue/history" component={QueueHistory} />
|
||||
<Route path="settings" component={Settings} />
|
||||
<Route path="settings/debug" component={Debug} />
|
||||
<Route path="settings(/:sub_view)" component={Settings} />
|
||||
<Route path="settings(/service/:service)" component={Settings} />
|
||||
|
||||
<Route path="search(/:query)" component={Search} />
|
||||
<Route path="album/:uri" component={Album} />
|
||||
|
||||
@ -20,14 +20,6 @@ export function disconnect(){
|
||||
}
|
||||
}
|
||||
|
||||
export function instruct(call, value){
|
||||
return {
|
||||
type: 'MOPIDY_INSTRUCT',
|
||||
call: call,
|
||||
value: value
|
||||
}
|
||||
}
|
||||
|
||||
export function debug(call, value){
|
||||
return {
|
||||
type: 'MOPIDY_DEBUG',
|
||||
|
||||
@ -128,7 +128,7 @@ const MopidyMiddleware = (function(){
|
||||
* @param string value (optional) = value of the property to pass
|
||||
* @return promise
|
||||
**/
|
||||
const instruct = (ws, store, call, value = {}) => {
|
||||
const request = (ws, store, call, value = {}) => {
|
||||
if (!store.getState().mopidy.connected){
|
||||
return false;
|
||||
}
|
||||
@ -227,7 +227,7 @@ const MopidyMiddleware = (function(){
|
||||
break;
|
||||
|
||||
case 'MOPIDY_DEBUG':
|
||||
instruct(socket, store, action.call, action.value )
|
||||
request(socket, store, action.call, action.value )
|
||||
.then(response => {
|
||||
store.dispatch({type: 'DEBUG', response: response});
|
||||
})
|
||||
@ -239,7 +239,7 @@ const MopidyMiddleware = (function(){
|
||||
**/
|
||||
|
||||
case 'MOPIDY_GET_PLAY_STATE':
|
||||
instruct(socket, store, 'playback.getState')
|
||||
request(socket, store, 'playback.getState')
|
||||
.then(
|
||||
response => {
|
||||
store.dispatch({
|
||||
@ -251,7 +251,7 @@ const MopidyMiddleware = (function(){
|
||||
break
|
||||
|
||||
case 'MOPIDY_PLAY':
|
||||
instruct(socket, store, 'playback.play')
|
||||
request(socket, store, 'playback.play')
|
||||
.then(
|
||||
response => {
|
||||
store.dispatch({
|
||||
@ -274,7 +274,7 @@ const MopidyMiddleware = (function(){
|
||||
break;
|
||||
|
||||
case 'MOPIDY_PAUSE':
|
||||
instruct(socket, store, 'playback.pause')
|
||||
request(socket, store, 'playback.pause')
|
||||
.then(
|
||||
response => {
|
||||
store.dispatch({
|
||||
@ -297,7 +297,7 @@ const MopidyMiddleware = (function(){
|
||||
break
|
||||
|
||||
case 'MOPIDY_NEXT':
|
||||
instruct(socket, store, 'playback.next');
|
||||
request(socket, store, 'playback.next');
|
||||
|
||||
store.dispatch(pusherActions.deliverBroadcast(
|
||||
'notification',
|
||||
@ -312,7 +312,7 @@ const MopidyMiddleware = (function(){
|
||||
break
|
||||
|
||||
case 'MOPIDY_STOP':
|
||||
instruct(socket, store, 'playback.stop');
|
||||
request(socket, store, 'playback.stop');
|
||||
|
||||
store.dispatch(pusherActions.deliverBroadcast(
|
||||
'notification',
|
||||
@ -327,7 +327,7 @@ const MopidyMiddleware = (function(){
|
||||
break
|
||||
|
||||
case 'MOPIDY_CHANGE_TRACK':
|
||||
instruct(socket, store, 'playback.play', {tlid: action.tlid});
|
||||
request(socket, store, 'playback.play', {tlid: action.tlid});
|
||||
|
||||
store.dispatch(pusherActions.deliverBroadcast(
|
||||
'notification',
|
||||
@ -341,7 +341,7 @@ const MopidyMiddleware = (function(){
|
||||
break;
|
||||
|
||||
case 'MOPIDY_REMOVE_TRACKS':
|
||||
instruct(socket, store, 'tracklist.remove', {tlid: action.tlids});
|
||||
request(socket, store, 'tracklist.remove', {tlid: action.tlids});
|
||||
store.dispatch(pusherActions.deliverBroadcast(
|
||||
'notification',
|
||||
{
|
||||
@ -354,7 +354,7 @@ const MopidyMiddleware = (function(){
|
||||
break;
|
||||
|
||||
case 'MOPIDY_GET_REPEAT':
|
||||
instruct(socket, store, 'tracklist.getRepeat')
|
||||
request(socket, store, 'tracklist.getRepeat')
|
||||
.then(
|
||||
response => {
|
||||
store.dispatch({
|
||||
@ -366,11 +366,11 @@ const MopidyMiddleware = (function(){
|
||||
break;
|
||||
|
||||
case 'MOPIDY_SET_REPEAT':
|
||||
instruct(socket, store, 'tracklist.setRepeat', [action.repeat]);
|
||||
request(socket, store, 'tracklist.setRepeat', [action.repeat]);
|
||||
break;
|
||||
|
||||
case 'MOPIDY_GET_RANDOM':
|
||||
instruct(socket, store, 'tracklist.getRandom')
|
||||
request(socket, store, 'tracklist.getRandom')
|
||||
.then(
|
||||
response => {
|
||||
store.dispatch({
|
||||
@ -382,11 +382,11 @@ const MopidyMiddleware = (function(){
|
||||
break;
|
||||
|
||||
case 'MOPIDY_SET_RANDOM':
|
||||
instruct(socket, store, 'tracklist.setRandom', [action.random]);
|
||||
request(socket, store, 'tracklist.setRandom', [action.random]);
|
||||
break;
|
||||
|
||||
case 'MOPIDY_GET_CONSUME':
|
||||
instruct(socket, store, 'tracklist.getConsume')
|
||||
request(socket, store, 'tracklist.getConsume')
|
||||
.then(
|
||||
response => {
|
||||
store.dispatch({
|
||||
@ -398,11 +398,11 @@ const MopidyMiddleware = (function(){
|
||||
break;
|
||||
|
||||
case 'MOPIDY_SET_CONSUME':
|
||||
instruct(socket, store, 'tracklist.setConsume', [action.consume]);
|
||||
request(socket, store, 'tracklist.setConsume', [action.consume]);
|
||||
break;
|
||||
|
||||
case 'MOPIDY_GET_MUTE':
|
||||
instruct(socket, store, 'mixer.getMute')
|
||||
request(socket, store, 'mixer.getMute')
|
||||
.then(
|
||||
response => {
|
||||
store.dispatch({
|
||||
@ -414,7 +414,7 @@ const MopidyMiddleware = (function(){
|
||||
break;
|
||||
|
||||
case 'MOPIDY_SET_MUTE':
|
||||
instruct(socket, store, 'mixer.setMute', [action.mute]);
|
||||
request(socket, store, 'mixer.setMute', [action.mute]);
|
||||
store.dispatch(pusherActions.deliverBroadcast(
|
||||
'notification',
|
||||
{
|
||||
@ -427,7 +427,7 @@ const MopidyMiddleware = (function(){
|
||||
break;
|
||||
|
||||
case 'MOPIDY_GET_VOLUME':
|
||||
instruct(socket, store, 'playback.getVolume')
|
||||
request(socket, store, 'playback.getVolume')
|
||||
.then(
|
||||
response => {
|
||||
store.dispatch({
|
||||
@ -439,7 +439,7 @@ const MopidyMiddleware = (function(){
|
||||
break;
|
||||
|
||||
case 'MOPIDY_SET_VOLUME':
|
||||
instruct(socket, store, 'playback.setVolume', {volume: action.volume})
|
||||
request(socket, store, 'playback.setVolume', {volume: action.volume})
|
||||
.then(
|
||||
response => {
|
||||
store.dispatch({
|
||||
@ -451,7 +451,7 @@ const MopidyMiddleware = (function(){
|
||||
break;
|
||||
|
||||
case 'MOPIDY_SET_TIME_POSITION':
|
||||
instruct(socket, store, 'playback.seek', {time_position: action.time_position})
|
||||
request(socket, store, 'playback.seek', {time_position: action.time_position})
|
||||
.then(
|
||||
response => {
|
||||
store.dispatch({
|
||||
@ -463,7 +463,7 @@ const MopidyMiddleware = (function(){
|
||||
break;
|
||||
|
||||
case 'MOPIDY_GET_TIME_POSITION':
|
||||
instruct(socket, store, 'playback.getTimePosition')
|
||||
request(socket, store, 'playback.getTimePosition')
|
||||
.then(
|
||||
response => {
|
||||
store.dispatch({
|
||||
@ -475,7 +475,7 @@ const MopidyMiddleware = (function(){
|
||||
break;
|
||||
|
||||
case 'MOPIDY_GET_URI_SCHEMES':
|
||||
instruct(socket, store, 'getUriSchemes')
|
||||
request(socket, store, 'getUriSchemes')
|
||||
.then(
|
||||
response => {
|
||||
var uri_schemes = response;
|
||||
@ -546,7 +546,7 @@ const MopidyMiddleware = (function(){
|
||||
|
||||
// fetch the playlist tracks via backend
|
||||
// add each track by URI
|
||||
instruct(socket, store, 'playlists.lookup', {uri: action.uri})
|
||||
request(socket, store, 'playlists.lookup', {uri: action.uri})
|
||||
.then(
|
||||
response => {
|
||||
if (response.tracks === undefined){
|
||||
@ -679,7 +679,7 @@ const MopidyMiddleware = (function(){
|
||||
params.at_position = batch.at_position + batch.offset
|
||||
}
|
||||
|
||||
instruct(socket, store, 'tracklist.add', params)
|
||||
request(socket, store, 'tracklist.add', params)
|
||||
.then(
|
||||
response => {
|
||||
// add metadata to queue
|
||||
@ -729,7 +729,7 @@ const MopidyMiddleware = (function(){
|
||||
var first_uri = action.uris[0];
|
||||
|
||||
// add our first track
|
||||
instruct(socket, store, 'tracklist.add', { uri: first_uri, at_position: 0 })
|
||||
request(socket, store, 'tracklist.add', { uri: first_uri, at_position: 0 })
|
||||
.then(
|
||||
response => {
|
||||
// play it (only if we got a successful lookup)
|
||||
@ -774,7 +774,7 @@ const MopidyMiddleware = (function(){
|
||||
case 'MOPIDY_REORDER_TRACKLIST':
|
||||
|
||||
// add our first track
|
||||
instruct(socket, store, 'tracklist.move', { start: action.range_start, end: action.range_start + action.range_length, to_position: action.insert_before } )
|
||||
request(socket, store, 'tracklist.move', { start: action.range_start, end: action.range_start + action.range_length, to_position: action.insert_before } )
|
||||
.then(
|
||||
response => {
|
||||
// TODO: when complete, send event to confirm success/failure
|
||||
@ -789,7 +789,7 @@ const MopidyMiddleware = (function(){
|
||||
break;
|
||||
|
||||
case 'MOPIDY_CLEAR_TRACKLIST':
|
||||
instruct(socket, store, 'tracklist.clear');
|
||||
request(socket, store, 'tracklist.clear');
|
||||
store.dispatch(pusherActions.deliverBroadcast(
|
||||
'notification',
|
||||
{
|
||||
@ -894,7 +894,7 @@ const MopidyMiddleware = (function(){
|
||||
))
|
||||
}
|
||||
|
||||
instruct(socket, store, 'library.search', {query: {album: [action.data.query]}, uris: [action.data.uri_scheme]})
|
||||
request(socket, store, 'library.search', {query: {album: [action.data.query]}, uris: [action.data.uri_scheme]})
|
||||
.then(
|
||||
response => {
|
||||
if (response.length > 0){
|
||||
@ -963,7 +963,7 @@ const MopidyMiddleware = (function(){
|
||||
))
|
||||
}
|
||||
|
||||
instruct(socket, store, 'library.search', {query: {artist: [action.data.query]}, uris: [action.data.uri_scheme]})
|
||||
request(socket, store, 'library.search', {query: {artist: [action.data.query]}, uris: [action.data.uri_scheme]})
|
||||
.then(
|
||||
response => {
|
||||
if (response.length > 0){
|
||||
@ -1029,7 +1029,7 @@ const MopidyMiddleware = (function(){
|
||||
store.dispatch(uiActions.processFinishing('MOPIDY_GET_SEARCH_RESULTS_PROCESSOR'))
|
||||
}
|
||||
|
||||
instruct(socket, store, 'playlists.asList')
|
||||
request(socket, store, 'playlists.asList')
|
||||
.then(
|
||||
response => {
|
||||
if (response.length > 0){
|
||||
@ -1087,7 +1087,7 @@ const MopidyMiddleware = (function(){
|
||||
))
|
||||
}
|
||||
|
||||
instruct(socket, store, 'library.search', {query: {any: [action.data.query]}, uris: [action.data.uri_scheme]})
|
||||
request(socket, store, 'library.search', {query: {any: [action.data.query]}, uris: [action.data.uri_scheme]})
|
||||
.then(
|
||||
response => {
|
||||
if (response.length > 0 && response[0].tracks !== undefined){
|
||||
@ -1122,7 +1122,7 @@ const MopidyMiddleware = (function(){
|
||||
remaining: (action.data.uri_schemes.length) + 1
|
||||
}
|
||||
));
|
||||
instruct(socket, store, 'library.search', {query: {any: [action.data.query]}, uris: [action.data.uri_scheme]})
|
||||
request(socket, store, 'library.search', {query: {any: [action.data.query]}, uris: [action.data.uri_scheme]})
|
||||
.then(
|
||||
response => {
|
||||
if (response.length > 0 && response[0].tracks !== undefined){
|
||||
@ -1154,7 +1154,7 @@ const MopidyMiddleware = (function(){
|
||||
remaining: (action.data.uri_schemes.length) + 0.75
|
||||
}
|
||||
));
|
||||
instruct(socket, store, 'library.search', {query: {album: [action.data.query]}, uris: [action.data.uri_scheme]})
|
||||
request(socket, store, 'library.search', {query: {album: [action.data.query]}, uris: [action.data.uri_scheme]})
|
||||
.then(
|
||||
response => {
|
||||
if (response.length > 0){
|
||||
@ -1210,7 +1210,7 @@ const MopidyMiddleware = (function(){
|
||||
remaining: (action.data.uri_schemes.length) + 0.5
|
||||
}
|
||||
));
|
||||
instruct(socket, store, 'library.search', {query: {artist: [action.data.query]}, uris: [action.data.uri_scheme]})
|
||||
request(socket, store, 'library.search', {query: {artist: [action.data.query]}, uris: [action.data.uri_scheme]})
|
||||
.then(
|
||||
response => {
|
||||
if (response.length > 0){
|
||||
@ -1288,7 +1288,7 @@ const MopidyMiddleware = (function(){
|
||||
remaining: (action.data.uri_schemes.length) + 0.25
|
||||
}
|
||||
))
|
||||
instruct(socket, store, 'playlists.asList')
|
||||
request(socket, store, 'playlists.asList')
|
||||
.then(
|
||||
response => {
|
||||
if (response.length > 0){
|
||||
@ -1341,7 +1341,7 @@ const MopidyMiddleware = (function(){
|
||||
**/
|
||||
|
||||
case 'MOPIDY_GET_LIBRARY_PLAYLISTS':
|
||||
instruct(socket, store, 'playlists.asList' )
|
||||
request(socket, store, 'playlists.asList' )
|
||||
.then(response => {
|
||||
|
||||
// drop in our URI list
|
||||
@ -1360,7 +1360,7 @@ const MopidyMiddleware = (function(){
|
||||
|
||||
// get the full playlist objects
|
||||
for (var i = 0; i < playlist_uris_filtered.length; i++){
|
||||
instruct(socket, store, 'playlists.lookup', { uri: playlist_uris_filtered[i] })
|
||||
request(socket, store, 'playlists.lookup', { uri: playlist_uris_filtered[i] })
|
||||
.then(response => {
|
||||
var source = helpers.uriSource(response.uri)
|
||||
var playlist = Object.assign(
|
||||
@ -1387,7 +1387,7 @@ const MopidyMiddleware = (function(){
|
||||
break;
|
||||
|
||||
case 'MOPIDY_GET_PLAYLIST':
|
||||
instruct(socket, store, 'playlists.lookup', action.data )
|
||||
request(socket, store, 'playlists.lookup', action.data )
|
||||
.then(response => {
|
||||
var playlist = Object.assign(
|
||||
{},
|
||||
@ -1422,7 +1422,7 @@ const MopidyMiddleware = (function(){
|
||||
var tracks = Object.assign([], action.tracks)
|
||||
var uris = helpers.arrayOf('uri',tracks)
|
||||
|
||||
instruct(socket, store, 'library.lookup', { uris: uris })
|
||||
request(socket, store, 'library.lookup', { uris: uris })
|
||||
.then(response => {
|
||||
for(var uri in response){
|
||||
if (response.hasOwnProperty(uri)){
|
||||
@ -1455,7 +1455,7 @@ const MopidyMiddleware = (function(){
|
||||
|
||||
case 'MOPIDY_ADD_PLAYLIST_TRACKS':
|
||||
|
||||
instruct(socket, store, 'playlists.lookup', { uri: action.key })
|
||||
request(socket, store, 'playlists.lookup', { uri: action.key })
|
||||
.then(response => {
|
||||
var tracks = [];
|
||||
for(var i = 0; i < action.tracks_uris.length; i++){
|
||||
@ -1472,7 +1472,7 @@ const MopidyMiddleware = (function(){
|
||||
playlist.tracks = tracks
|
||||
}
|
||||
|
||||
instruct(socket, store, 'playlists.save', { playlist: playlist } )
|
||||
request(socket, store, 'playlists.save', { playlist: playlist } )
|
||||
.then(response => {
|
||||
store.dispatch({
|
||||
type: 'PLAYLIST_TRACKS_ADDED',
|
||||
@ -1492,13 +1492,13 @@ const MopidyMiddleware = (function(){
|
||||
var indexes = Object.assign([], action.tracks_indexes)
|
||||
indexes.sort(descending);
|
||||
|
||||
instruct(socket, store, 'playlists.lookup', { uri: action.key })
|
||||
request(socket, store, 'playlists.lookup', { uri: action.key })
|
||||
.then(response => {
|
||||
var playlist = Object.assign({}, response)
|
||||
for(var i = 0; i < indexes.length; i++){
|
||||
playlist.tracks.splice(indexes[i], 1);
|
||||
}
|
||||
instruct(socket, store, 'playlists.save', { playlist: playlist } )
|
||||
request(socket, store, 'playlists.save', { playlist: playlist } )
|
||||
.then(response => {
|
||||
store.dispatch({
|
||||
type: 'PLAYLIST_TRACKS_REMOVED',
|
||||
@ -1512,10 +1512,10 @@ const MopidyMiddleware = (function(){
|
||||
case 'MOPIDY_SAVE_PLAYLIST':
|
||||
var uri = action.key
|
||||
|
||||
instruct(socket, store, 'playlists.lookup', { uri: action.key })
|
||||
request(socket, store, 'playlists.lookup', { uri: action.key })
|
||||
.then(response => {
|
||||
var playlist = Object.assign({}, response, { name: action.name })
|
||||
instruct(socket, store, 'playlists.save', { playlist: playlist } )
|
||||
request(socket, store, 'playlists.save', { playlist: playlist } )
|
||||
.then(response => {
|
||||
|
||||
store.dispatch({
|
||||
@ -1541,7 +1541,7 @@ const MopidyMiddleware = (function(){
|
||||
break
|
||||
|
||||
case 'MOPIDY_REORDER_PLAYLIST_TRACKS':
|
||||
instruct(socket, store, 'playlists.lookup', { uri: action.key })
|
||||
request(socket, store, 'playlists.lookup', { uri: action.key })
|
||||
.then(response => {
|
||||
|
||||
var playlist = Object.assign({}, response)
|
||||
@ -1571,7 +1571,7 @@ const MopidyMiddleware = (function(){
|
||||
|
||||
// update playlist
|
||||
playlist = Object.assign({}, playlist, { tracks: tracks })
|
||||
instruct(socket, store, 'playlists.save', { playlist: playlist } )
|
||||
request(socket, store, 'playlists.save', { playlist: playlist } )
|
||||
.then(response => {
|
||||
store.dispatch({
|
||||
type: 'MOPIDY_RESOLVE_PLAYLIST_TRACKS',
|
||||
@ -1583,7 +1583,7 @@ const MopidyMiddleware = (function(){
|
||||
break
|
||||
|
||||
case 'MOPIDY_CREATE_PLAYLIST':
|
||||
instruct(socket, store, 'playlists.create', { name: action.name, uri_scheme: action.scheme })
|
||||
request(socket, store, 'playlists.create', { name: action.name, uri_scheme: action.scheme })
|
||||
.then(response => {
|
||||
store.dispatch(uiActions.createNotification({content: 'Created playlist'}))
|
||||
|
||||
@ -1602,7 +1602,7 @@ const MopidyMiddleware = (function(){
|
||||
break
|
||||
|
||||
case 'MOPIDY_DELETE_PLAYLIST':
|
||||
instruct(socket, store, 'playlists.delete', { uri: action.uri })
|
||||
request(socket, store, 'playlists.delete', { uri: action.uri })
|
||||
.then(response => {
|
||||
store.dispatch(uiActions.createNotification({content: 'Deleted playlist'}))
|
||||
store.dispatch({
|
||||
@ -1622,7 +1622,7 @@ const MopidyMiddleware = (function(){
|
||||
var last_run = store.getState().ui.processes.MOPIDY_LIBRARY_ALBUMS_PROCESSOR
|
||||
|
||||
if (!last_run){
|
||||
instruct(socket, store, 'library.browse', { uri: 'local:directory?type=album' } )
|
||||
request(socket, store, 'library.browse', { uri: 'local:directory?type=album' } )
|
||||
.then(response => {
|
||||
if (response.length <= 0) return
|
||||
|
||||
@ -1682,7 +1682,7 @@ const MopidyMiddleware = (function(){
|
||||
break
|
||||
|
||||
case 'MOPIDY_GET_ALBUMS':
|
||||
instruct(socket, store, 'library.lookup', { uris: action.uris } )
|
||||
request(socket, store, 'library.lookup', { uris: action.uris } )
|
||||
.then(response => {
|
||||
if (response.length <= 0) return
|
||||
|
||||
@ -1725,7 +1725,7 @@ const MopidyMiddleware = (function(){
|
||||
break;
|
||||
|
||||
case 'MOPIDY_GET_ALBUM':
|
||||
instruct(socket, store, 'library.lookup', action.data )
|
||||
request(socket, store, 'library.lookup', action.data )
|
||||
.then(response => {
|
||||
if (response.length <= 0) return
|
||||
|
||||
@ -1756,7 +1756,7 @@ const MopidyMiddleware = (function(){
|
||||
}
|
||||
}
|
||||
|
||||
instruct(socket, store, 'library.lookup', { uris: uris } )
|
||||
request(socket, store, 'library.lookup', { uris: uris } )
|
||||
.then(response => {
|
||||
|
||||
for(var uri in response){
|
||||
@ -1793,7 +1793,7 @@ const MopidyMiddleware = (function(){
|
||||
* ======================================================================================
|
||||
**/
|
||||
case 'MOPIDY_GET_LIBRARY_ARTISTS':
|
||||
instruct(socket, store, 'library.browse', { uri: 'local:directory?type=artist' } )
|
||||
request(socket, store, 'library.browse', { uri: 'local:directory?type=artist' } )
|
||||
.then(response => {
|
||||
if (response.length <= 0) return
|
||||
|
||||
@ -1821,7 +1821,7 @@ const MopidyMiddleware = (function(){
|
||||
var last_run = store.getState().ui.processes.MOPIDY_LIBRARY_ARTISTS_PROCESSOR
|
||||
|
||||
if (!last_run){
|
||||
instruct(socket, store, 'library.browse', { uri: 'local:directory?type=artist' } )
|
||||
request(socket, store, 'library.browse', { uri: 'local:directory?type=artist' } )
|
||||
.then(response => {
|
||||
if (response.length <= 0) return;
|
||||
|
||||
@ -1868,7 +1868,7 @@ const MopidyMiddleware = (function(){
|
||||
**/
|
||||
|
||||
case 'MOPIDY_GET_ARTIST':
|
||||
instruct(socket, store, 'library.lookup', action.data )
|
||||
request(socket, store, 'library.lookup', action.data )
|
||||
.then(response => {
|
||||
if (response.length <= 0) return
|
||||
|
||||
@ -1928,7 +1928,7 @@ const MopidyMiddleware = (function(){
|
||||
break;
|
||||
|
||||
case 'MOPIDY_GET_ARTISTS':
|
||||
instruct(socket, store, 'library.lookup', {uris: action.uris})
|
||||
request(socket, store, 'library.lookup', {uris: action.uris})
|
||||
.then(response => {
|
||||
if (response.length <= 0) return
|
||||
|
||||
@ -1973,7 +1973,7 @@ const MopidyMiddleware = (function(){
|
||||
**/
|
||||
|
||||
case 'MOPIDY_GET_QUEUE':
|
||||
instruct(socket, store, 'tracklist.getTlTracks')
|
||||
request(socket, store, 'tracklist.getTlTracks')
|
||||
.then(
|
||||
response => {
|
||||
store.dispatch({
|
||||
@ -1985,7 +1985,7 @@ const MopidyMiddleware = (function(){
|
||||
break;
|
||||
|
||||
case 'MOPIDY_GET_QUEUE_HISTORY':
|
||||
instruct(socket, store, 'history.getHistory')
|
||||
request(socket, store, 'history.getHistory')
|
||||
.then(
|
||||
response => {
|
||||
store.dispatch({
|
||||
@ -1997,7 +1997,7 @@ const MopidyMiddleware = (function(){
|
||||
break;
|
||||
|
||||
case 'MOPIDY_GET_CURRENT_TRACK':
|
||||
instruct(socket, store, 'playback.getCurrentTlTrack')
|
||||
request(socket, store, 'playback.getCurrentTlTrack')
|
||||
.then(
|
||||
response => {
|
||||
if (response && response.track){
|
||||
@ -2024,7 +2024,7 @@ const MopidyMiddleware = (function(){
|
||||
break;
|
||||
|
||||
case 'MOPIDY_GET_TRACK':
|
||||
instruct(socket, store, 'library.lookup', action.data )
|
||||
request(socket, store, 'library.lookup', action.data )
|
||||
.then(
|
||||
response => {
|
||||
if (response.length > 0){
|
||||
@ -2052,7 +2052,7 @@ const MopidyMiddleware = (function(){
|
||||
|
||||
case 'MOPIDY_GET_IMAGES':
|
||||
|
||||
instruct(socket, store, 'library.getImages', {uris: action.uris})
|
||||
request(socket, store, 'library.getImages', {uris: action.uris})
|
||||
.then(response => {
|
||||
|
||||
var records = [];
|
||||
@ -2091,7 +2091,7 @@ const MopidyMiddleware = (function(){
|
||||
|
||||
case 'MOPIDY_GET_DIRECTORY':
|
||||
store.dispatch({ type: 'MOPIDY_DIRECTORY_LOADED', data: false })
|
||||
instruct(socket, store, 'library.browse', action.data)
|
||||
request(socket, store, 'library.browse', action.data)
|
||||
.then(response => {
|
||||
store.dispatch({
|
||||
type: 'MOPIDY_DIRECTORY_LOADED',
|
||||
|
||||
@ -321,7 +321,7 @@ const PusherMiddleware = (function(){
|
||||
|
||||
var core = store.getState().core;
|
||||
if (!core.country || !core.locale){
|
||||
store.dispatch(coreActions.set({
|
||||
store.dispatch(spotifyActions.set({
|
||||
country: response.config.country,
|
||||
locale: response.config.locale
|
||||
}))
|
||||
|
||||
@ -358,7 +358,7 @@ export function getFeaturedPlaylists(){
|
||||
|
||||
var timestamp = year+'-'+month+'-'+day+'T'+hour+':'+min+':'+sec;
|
||||
|
||||
sendRequest(dispatch, getState, 'browse/featured-playlists?limit=50&country='+getState().core.country+'&locale='+getState().core.locale+'timestamp='+timestamp)
|
||||
sendRequest(dispatch, getState, 'browse/featured-playlists?limit=50&country='+getState().spotify.country+'&locale='+getState().spotify.locale+'timestamp='+timestamp)
|
||||
.then(
|
||||
response => {
|
||||
var playlists = []
|
||||
@ -402,7 +402,7 @@ export function getFeaturedPlaylists(){
|
||||
|
||||
export function getCategories(){
|
||||
return (dispatch, getState) => {
|
||||
sendRequest(dispatch, getState, 'browse/categories?limit=50&country='+getState().core.country+'&locale='+getState().core.locale )
|
||||
sendRequest(dispatch, getState, 'browse/categories?limit=50&country='+getState().spotify.country+'&locale='+getState().spotify.locale )
|
||||
.then(
|
||||
response => {
|
||||
dispatch({
|
||||
@ -432,7 +432,7 @@ export function getCategory(id){
|
||||
});
|
||||
|
||||
// get the category
|
||||
sendRequest(dispatch, getState, 'browse/categories/'+id+'?country='+getState().core.country+'&locale='+getState().core.locale )
|
||||
sendRequest(dispatch, getState, 'browse/categories/'+id+'?country='+getState().spotify.country+'&locale='+getState().spotify.locale )
|
||||
.then(
|
||||
response => {
|
||||
var category = Object.assign({}, response)
|
||||
@ -451,7 +451,7 @@ export function getCategory(id){
|
||||
)
|
||||
|
||||
// and the category's playlists
|
||||
sendRequest(dispatch, getState, 'browse/categories/'+id+'/playlists?limit=50&country='+getState().core.country+'&locale='+getState().core.locale )
|
||||
sendRequest(dispatch, getState, 'browse/categories/'+id+'/playlists?limit=50&country='+getState().spotify.country+'&locale='+getState().spotify.locale )
|
||||
.then(
|
||||
response => {
|
||||
var playlists = []
|
||||
@ -490,7 +490,7 @@ export function getCategory(id){
|
||||
|
||||
export function getNewReleases(){
|
||||
return (dispatch, getState) => {
|
||||
sendRequest(dispatch, getState, 'browse/new-releases?country='+getState().core.country+'&limit=50' )
|
||||
sendRequest(dispatch, getState, 'browse/new-releases?country='+getState().spotify.country+'&limit=50' )
|
||||
.then(
|
||||
response => {
|
||||
dispatch({
|
||||
@ -578,7 +578,7 @@ export function getSearchResults(type, query, limit = 50, offset = 0){
|
||||
|
||||
var url = 'search?q='+query
|
||||
url += '&type='+type
|
||||
url += '&country='+getState().core.country
|
||||
url += '&country='+getState().spotify.country
|
||||
url += '&limit='+limit
|
||||
url += '&offset='+offset
|
||||
|
||||
@ -670,7 +670,7 @@ export function getAutocompleteResults(field_id, query, types = ['album','artist
|
||||
|
||||
var endpoint = 'search?q='+query
|
||||
endpoint += '&type='+types.join(',')
|
||||
endpoint += '&country='+getState().core.country
|
||||
endpoint += '&country='+getState().spotify.country
|
||||
|
||||
sendRequest(dispatch, getState, endpoint)
|
||||
.then(
|
||||
@ -1112,7 +1112,7 @@ export function getArtist(uri, full = false){
|
||||
if (full){
|
||||
|
||||
requests.push(
|
||||
sendRequest(dispatch, getState, 'artists/'+ helpers.getFromUri('artistid', uri) +'/top-tracks?country='+getState().core.country )
|
||||
sendRequest(dispatch, getState, 'artists/'+ helpers.getFromUri('artistid', uri) +'/top-tracks?country='+getState().spotify.country )
|
||||
.then(
|
||||
response => {
|
||||
Object.assign(artist, response);
|
||||
@ -1163,7 +1163,7 @@ export function getArtist(uri, full = false){
|
||||
|
||||
// Now go get our artist albums
|
||||
if (full){
|
||||
sendRequest(dispatch, getState, 'artists/'+ helpers.getFromUri('artistid', uri) +'/albums?market='+getState().core.country )
|
||||
sendRequest(dispatch, getState, 'artists/'+ helpers.getFromUri('artistid', uri) +'/albums?market='+getState().spotify.country )
|
||||
.then(
|
||||
response => {
|
||||
dispatch({
|
||||
@ -1235,7 +1235,7 @@ export function playArtistTopTracks(uri){
|
||||
|
||||
// We need to load the artist's top tracks first
|
||||
} else {
|
||||
sendRequest(dispatch, getState, 'artists/'+ helpers.getFromUri('artistid', uri) +'/top-tracks?country='+getState().core.country )
|
||||
sendRequest(dispatch, getState, 'artists/'+ helpers.getFromUri('artistid', uri) +'/top-tracks?country='+getState().spotify.country )
|
||||
.then(
|
||||
response => {
|
||||
const uris = helpers.arrayOf('uri',response.tracks)
|
||||
@ -1531,7 +1531,7 @@ export function getPlaylist(uri){
|
||||
return (dispatch, getState) => {
|
||||
|
||||
// get the main playlist object
|
||||
sendRequest(dispatch, getState, 'users/'+ helpers.getFromUri('userid',uri) +'/playlists/'+ helpers.getFromUri('playlistid',uri) +'?market='+getState().core.country )
|
||||
sendRequest(dispatch, getState, 'users/'+ helpers.getFromUri('userid',uri) +'/playlists/'+ helpers.getFromUri('playlistid',uri) +'?market='+getState().spotify.country )
|
||||
.then(
|
||||
response => {
|
||||
|
||||
@ -1665,7 +1665,7 @@ export function getPlaylistTracksAndPlay(uri){
|
||||
'Loading playlist tracks',
|
||||
{
|
||||
uri: uri,
|
||||
next: 'users/'+ helpers.getFromUri('userid',uri) +'/playlists/'+ helpers.getFromUri('playlistid',uri) +'/tracks?market='+getState().core.country
|
||||
next: 'users/'+ helpers.getFromUri('userid',uri) +'/playlists/'+ helpers.getFromUri('playlistid',uri) +'/tracks?market='+getState().spotify.country
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
@ -5,14 +5,8 @@ import { Link, hashHistory } from 'react-router'
|
||||
import { bindActionCreators } from 'redux'
|
||||
import FontAwesome from 'react-fontawesome'
|
||||
|
||||
import SpotifyAuthenticationFrame from '../components/SpotifyAuthenticationFrame'
|
||||
import ConfirmationButton from '../components/ConfirmationButton'
|
||||
import PusherConnectionList from '../components/PusherConnectionList'
|
||||
import URISchemesList from '../components/URISchemesList'
|
||||
import VersionManager from '../components/VersionManager'
|
||||
import Header from '../components/Header'
|
||||
import Thumbnail from '../components/Thumbnail'
|
||||
import Snapcast from '../components/Snapcast'
|
||||
|
||||
import * as uiActions from '../services/ui/actions'
|
||||
import * as pusherActions from '../services/pusher/actions'
|
||||
@ -27,7 +21,8 @@ class Debug extends React.Component{
|
||||
mopidy_call: 'playlists.asList',
|
||||
mopidy_data: '{}',
|
||||
pusher_data: '{"method":"get_config"}',
|
||||
access_token: this.props.access_token
|
||||
access_token: this.props.access_token,
|
||||
toggling_test_mode: false
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,6 +36,14 @@ class Debug extends React.Component{
|
||||
this.props.pusherActions.debug(JSON.parse(this.state.pusher_data) )
|
||||
}
|
||||
|
||||
toggleTestMode(e){
|
||||
this.setState({toggling_test_mode: true});
|
||||
this.props.uiActions.set({ test_mode: !this.props.test_mode });
|
||||
|
||||
// Wait a second to allow state to update, and then refresh
|
||||
setTimeout(location.reload(), 1000);
|
||||
}
|
||||
|
||||
render(){
|
||||
|
||||
var options = (
|
||||
@ -60,24 +63,22 @@ class Debug extends React.Component{
|
||||
|
||||
<h4 className="underline">User interface</h4>
|
||||
<form>
|
||||
<div className="field checkbox">
|
||||
<div className="name">Test mode</div>
|
||||
<div className="input">
|
||||
{this.state.toggling_test_mode ? <span className="button working">Applying...</span> : (this.props.test_mode ? <span className="button destructive" onClick={e => this.toggleTestMode(e)}>Disable</span> : <span className="button primary" onClick={e => this.toggleTestMode(e)}>Enable</span>)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="field checkbox">
|
||||
<div className="name">Debug</div>
|
||||
<div className="input">
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="debug_info"
|
||||
checked={ this.props.test_mode }
|
||||
onChange={ e => this.props.uiActions.set({ test_mode: !this.props.test_mode })} />
|
||||
<span className="label">Test mode</span>
|
||||
</label>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="debug_info"
|
||||
checked={ this.props.debug_info }
|
||||
onChange={ e => this.props.uiActions.set({ debug_info: !this.props.debug_info })} />
|
||||
<span className="label">Debug info</span>
|
||||
<span className="label">Show debug overlay</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@ -120,11 +121,6 @@ class Debug extends React.Component{
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<h4 className="underline">Snapcast (beta)</h4>
|
||||
<div className="field">
|
||||
<Snapcast />
|
||||
</div>
|
||||
|
||||
<h4 className="underline">Spotify</h4>
|
||||
<div className="field">
|
||||
<div className="name">Access token</div>
|
||||
|
||||
@ -5,17 +5,15 @@ import { hashHistory, Link } from 'react-router'
|
||||
import { bindActionCreators } from 'redux'
|
||||
import FontAwesome from 'react-fontawesome'
|
||||
|
||||
import SpotifyAuthenticationFrame from '../components/SpotifyAuthenticationFrame'
|
||||
import LastfmAuthenticationFrame from '../components/LastfmAuthenticationFrame'
|
||||
import ConfirmationButton from '../components/ConfirmationButton'
|
||||
import PusherConnectionList from '../components/PusherConnectionList'
|
||||
import URISchemesList from '../components/URISchemesList'
|
||||
import VersionManager from '../components/VersionManager'
|
||||
import Header from '../components/Header'
|
||||
import Parallax from '../components/Parallax'
|
||||
import Icon from '../components/Icon'
|
||||
import Thumbnail from '../components/Thumbnail'
|
||||
import URILink from '../components/URILink'
|
||||
import Services from '../components/Services'
|
||||
|
||||
import * as coreActions from '../services/core/actions'
|
||||
import * as uiActions from '../services/ui/actions'
|
||||
@ -29,8 +27,6 @@ class Settings extends React.Component {
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state = {
|
||||
country: this.props.core.country,
|
||||
locale: this.props.core.locale,
|
||||
mopidy_host: this.props.mopidy.host,
|
||||
mopidy_port: this.props.mopidy.port,
|
||||
mopidy_ssl: this.props.mopidy.ssl,
|
||||
@ -39,26 +35,10 @@ class Settings extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
if (this.props.lastfm.session && this.props.core.users["lastfm:user:"+this.props.lastfm.session.name] === undefined){
|
||||
this.props.lastfmActions.getMe();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(newProps){
|
||||
var changed = false
|
||||
var state = this.state
|
||||
|
||||
if (newProps.core.country != this.state.country && this.state.input_in_focus != 'country'){
|
||||
state.country = newProps.core.country
|
||||
changed = true
|
||||
}
|
||||
|
||||
if (newProps.core.locale != this.state.locale && this.state.input_in_focus != 'locale'){
|
||||
state.locale = newProps.core.locale
|
||||
changed = true
|
||||
}
|
||||
|
||||
if (newProps.pusher.username != this.state.pusher_username && this.state.input_in_focus != 'pusher_username'){
|
||||
state.pusher_username = newProps.pusher.username
|
||||
changed = true
|
||||
@ -123,65 +103,6 @@ class Settings extends React.Component {
|
||||
)
|
||||
}
|
||||
|
||||
renderSpotifyUser(){
|
||||
var user = this.props.spotify.me;
|
||||
|
||||
if (user){
|
||||
return (
|
||||
<URILink className="user" type="user" uri={user.uri}>
|
||||
<Thumbnail circle={true} size="small" images={user.images} />
|
||||
<span className="user-name">
|
||||
{user.display_name ? user.display_name : user.id}
|
||||
{!this.props.spotify.authorization ? <span className="grey-text"> (Limited access)</span> : null}
|
||||
</span>
|
||||
</URILink>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<URILink className="user">
|
||||
<Thumbnail circle={true} size="small" />
|
||||
<span className="user-name">
|
||||
Unknown
|
||||
</span>
|
||||
</URILink>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
renderLastfmUser(){
|
||||
var user = this.props.core.users["lastfm:user:"+this.props.lastfm.session.name];
|
||||
|
||||
if (user){
|
||||
return (
|
||||
<span className="user">
|
||||
<Thumbnail circle={true} size="small" images={user.image} />
|
||||
<span className="user-name">
|
||||
{user.realname ? user.realname : user.name}
|
||||
</span>
|
||||
</span>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<span className="user">
|
||||
<Thumbnail circle={true} size="small" />
|
||||
<span className="user-name">
|
||||
Unknown
|
||||
</span>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
renderSendAuthorizationButton(){
|
||||
if (!this.props.spotify.authorization) return null
|
||||
|
||||
return (
|
||||
<button onClick={e => this.props.uiActions.openModal('send_authorization', {}) }>
|
||||
Share authentication
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
renderServerStatus(){
|
||||
var colour = 'grey';
|
||||
var icon = 'question-circle';
|
||||
@ -207,36 +128,6 @@ class Settings extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
renderSpotifyStatus(){
|
||||
var colour = 'grey';
|
||||
var icon = 'question-circle';
|
||||
var status = 'Unknown';
|
||||
|
||||
if (this.props.spotify.connecting){
|
||||
icon = 'plug';
|
||||
status = 'Connecting...'
|
||||
} else if (!this.props.spotify.connected){
|
||||
colour = 'red';
|
||||
icon = 'close';
|
||||
status = 'Disconnected';
|
||||
} else if (this.props.mopidy.connected){
|
||||
colour = 'green';
|
||||
icon = 'check';
|
||||
status = 'Connected';
|
||||
}
|
||||
|
||||
if (!this.props.mopidy.uri_schemes || !this.props.mopidy.uri_schemes.includes('spotify:')){
|
||||
colour = 'orange';
|
||||
status += ' (Mopidy-Spotify extension not installed/enabled!)';
|
||||
}
|
||||
|
||||
return (
|
||||
<span className={colour+'-text'}>
|
||||
<FontAwesome name={icon} /> {status}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
render(){
|
||||
|
||||
var options = (
|
||||
@ -333,136 +224,8 @@ class Settings extends React.Component {
|
||||
{this.renderApplyButton()}
|
||||
</form>
|
||||
|
||||
<h4 className="underline">Streaming</h4>
|
||||
|
||||
<div className="field checkbox">
|
||||
<div className="name">Enable</div>
|
||||
<div className="input">
|
||||
<label>
|
||||
<input
|
||||
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 has-tooltip">
|
||||
Stream audio to this browser
|
||||
<span className="tooltip">Requires streaming service like Icecast2</span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className="field radio">
|
||||
<div className="name">Encoding</div>
|
||||
<div className="input">
|
||||
<label>
|
||||
<input
|
||||
type="radio"
|
||||
name="http_streaming_encoding"
|
||||
checked={this.props.core.http_streaming_encoding == 'mpeg'}
|
||||
onChange={e => this.props.coreActions.set({http_streaming_encoding: 'mpeg'})} />
|
||||
<span className="label">mpeg (mp3)</span>
|
||||
</label>
|
||||
<label>
|
||||
<input
|
||||
type="radio"
|
||||
name="http_streaming_encoding"
|
||||
checked={this.props.core.http_streaming_encoding == 'ogg'}
|
||||
onChange={e => this.props.coreActions.set({http_streaming_encoding: 'ogg'})} />
|
||||
<span className="label">ogg</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="field">
|
||||
<div className="name">Location</div>
|
||||
<div className="input">
|
||||
<input
|
||||
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
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 className="underline">Localization</h4>
|
||||
|
||||
<div className="field">
|
||||
<div className="name">Country</div>
|
||||
<div className="input">
|
||||
<input
|
||||
type="text"
|
||||
onChange={e => this.setState({country: e.target.value})}
|
||||
onFocus={e => this.setState({input_in_focus: 'country'})}
|
||||
onBlur={e => this.handleBlur('country',e.target.value)}
|
||||
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> country code (eg <em>NZ</em>)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="field">
|
||||
<div className="name">Locale</div>
|
||||
<div className="input">
|
||||
<input
|
||||
type="text"
|
||||
onChange={e => this.setState({locale: e.target.value})}
|
||||
onFocus={e => this.setState({input_in_focus: 'locale'})}
|
||||
onBlur={e => this.handleBlur('locale',e.target.value)}
|
||||
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>, joined by an underscore (eg <em>en_NZ</em>)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 className="underline">Spotify</h4>
|
||||
|
||||
<div className="field">
|
||||
<div className="name">Status</div>
|
||||
<div className="input">
|
||||
<div className="text">
|
||||
{this.renderSpotifyStatus()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="field current-user">
|
||||
<div className="name">Current user</div>
|
||||
<div className="input">
|
||||
<div className="text">
|
||||
{ this.renderSpotifyUser() }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="field">
|
||||
<div className="name">Authorization</div>
|
||||
<div className="input">
|
||||
<SpotifyAuthenticationFrame />
|
||||
{ this.renderSendAuthorizationButton() }
|
||||
{this.props.spotify.refreshing_token ? <button className="working">Refreshing...</button> : <button onClick={e => this.props.spotifyActions.refreshingToken()}>Force token refresh</button>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 className="underline">LastFM</h4>
|
||||
|
||||
{this.props.lastfm.session ? <div className="field current-user">
|
||||
<div className="name">Current user</div>
|
||||
<div className="input">
|
||||
<div className="text">
|
||||
{ this.renderLastfmUser() }
|
||||
</div>
|
||||
</div>
|
||||
</div> : null}
|
||||
|
||||
<div className="field">
|
||||
<div className="name">Authorization</div>
|
||||
<div className="input">
|
||||
<LastfmAuthenticationFrame />
|
||||
</div>
|
||||
</div>
|
||||
<h4 className="underline">Services</h4>
|
||||
<Services active={this.props.params.service} />
|
||||
|
||||
<h4 className="underline">Advanced</h4>
|
||||
|
||||
@ -492,15 +255,6 @@ class Settings extends React.Component {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="field">
|
||||
<div className="name">Extensions</div>
|
||||
<div className="input">
|
||||
<div className="text">
|
||||
<URISchemesList />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="field">
|
||||
<div className="name">Version</div>
|
||||
<div className="input">
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
@import 'components/sub-views';
|
||||
@import 'components/debug';
|
||||
@import 'components/tooltip';
|
||||
@import 'components/services';
|
||||
|
||||
@import 'views/artist';
|
||||
@import 'views/user';
|
||||
|
||||
82
src/scss/components/_services.scss
Executable file
82
src/scss/components/_services.scss
Executable file
@ -0,0 +1,82 @@
|
||||
|
||||
.services {
|
||||
|
||||
.menu {
|
||||
@include clearfix();
|
||||
margin: 0 -10px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.menu-item-wrapper {
|
||||
width: 25%;
|
||||
max-width: 200px;
|
||||
padding: 10px;
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
|
||||
.menu-item {
|
||||
@include animate();
|
||||
position: relative;
|
||||
padding: 30px 10px;
|
||||
border-radius: 3px;
|
||||
background: $darkest_grey;
|
||||
display: block;
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
border: 0;
|
||||
|
||||
&:hover {
|
||||
background: lighten($dark_grey, 4%);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: lighten($dark_grey, 4%);
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
|
||||
&:after {
|
||||
height: 10px;
|
||||
bottom: -10px;
|
||||
}
|
||||
}
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: lighten($dark_grey, 4%);
|
||||
}
|
||||
|
||||
.thumbnail {
|
||||
margin-bottom: 15px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.fa {
|
||||
font-size: 40px;
|
||||
height: 40px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.service {
|
||||
padding: 20px 20px 10px 20px;
|
||||
border-radius: 0 0 3px 3px;
|
||||
background: lighten($dark_grey, 4%);
|
||||
}
|
||||
}
|
||||
@ -31,42 +31,6 @@
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.services {
|
||||
@include clearfix();
|
||||
margin-bottom: -20px;
|
||||
|
||||
.service {
|
||||
margin-right: 20px;
|
||||
margin-bottom: 20px;
|
||||
padding-left: 46px;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
float: left;
|
||||
min-width: 150px;
|
||||
|
||||
.title {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.icon {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 0;
|
||||
width: 34px;
|
||||
height: 25px;
|
||||
padding-top: 9px;
|
||||
border: 2px solid $grey;
|
||||
text-align: center;
|
||||
border-radius: 50%;
|
||||
|
||||
.fa {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.field.current-user {
|
||||
.text {
|
||||
.user {
|
||||
@ -115,25 +79,6 @@
|
||||
padding-bottom: 60px;
|
||||
}
|
||||
|
||||
.services {
|
||||
text-align: center;
|
||||
|
||||
.service {
|
||||
padding: 40px 0 0 0;
|
||||
text-align: center;
|
||||
min-width: 100px;
|
||||
display: inline-block;
|
||||
margin-right: 0;
|
||||
float: none;
|
||||
|
||||
.icon {
|
||||
top: 0;
|
||||
left: 50%;
|
||||
margin-left: -18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.field.pusher-connections {
|
||||
.connection {
|
||||
.col {
|
||||
|
||||
Reference in New Issue
Block a user