Snapcast to BEM

This commit is contained in:
James Barnsley
2018-09-24 16:10:42 +12:00
parent 1bb0c80431
commit 06f8ee9060
11 changed files with 1914 additions and 1861 deletions

View File

@ -4445,111 +4445,118 @@ $icon-websocket: \e920;
.snapcast button { .snapcast button {
margin-bottom: 0px; } margin-bottom: 0px; }
.snapcast .volume-control .mute-control { .snapcast__group__volume-control {
display: inline-block;
float: left;
padding: 0 5px;
border: 0; }
.snapcast .volume-control .slider-wrapper {
margin-left: 30px; }
.snapcast .volume-control.group-volume-control {
padding: 10px 0 5px; padding: 10px 0 5px;
display: block; display: block;
width: 100%; width: 100%;
box-sizing: border-box; } box-sizing: border-box; }
.snapcast__group__volume-control .mute-control {
display: inline-block;
float: left;
padding: 0 5px;
border: 0; }
.snapcast__group__volume-control .slider-wrapper {
margin-left: 30px; }
.snapcast .volume-control.client-volume-control { .snapcast__groups {
padding-top: 11px;
padding-right: 10px;
display: block;
vertical-align: middle;
box-sizing: border-box; }
.snapcast .groups {
padding-top: 10px; } padding-top: 10px; }
.snapcast .groups .group {
padding-top: 10px; .snapcast__group {
border-top: 1px solid #383734; } padding-top: 10px;
.snapcast .groups .group:not(:last-child) { border-top: 1px solid #383734; }
padding-bottom: 20px; } .snapcast__group:not(:last-child) {
.snapcast .groups .group .clients { padding-bottom: 20px; }
padding: 0 10px; }
.snapcast .groups .group .clients .client { .snapcast__clients {
border: 0; padding: 0 10px; }
padding: 0;
clear: both; } .snapcast__client {
.snapcast .groups .group .clients .client::after { border: 0;
padding: 0;
clear: both; }
.snapcast__client::after {
content: '';
clear: both;
display: block; }
.snapcast__client:not(:first-child) {
padding-top: 8px; }
.snapcast__client__volume-control {
padding-top: 11px;
padding-right: 10px;
display: block;
vertical-align: middle;
box-sizing: border-box; }
.snapcast__client__volume-control .mute-control {
display: inline-block;
float: left;
padding: 0 5px;
border: 0; }
.snapcast__client__volume-control .slider-wrapper {
margin-left: 30px; }
.snapcast__client__name {
width: 40%;
padding-bottom: 4px;
position: relative;
display: block;
box-sizing: border-box;
border: 0; }
.snapcast__client__name input {
width: 100%;
padding-right: 30px; }
.snapcast__client__group-dropdown-field {
float: right;
margin-bottom: -3.2rem; }
.snapcast__client__group-dropdown-field .icon {
padding-right: 0; }
.snapcast__client__volume {
width: 28%;
padding-left: 2%; }
.snapcast__client__latency {
width: 28%;
padding-left: 2%; }
.snapcast__client__latency input[type="number"] {
width: 20%; }
.snapcast__client__latency .latency-control {
display: inline-block;
vertical-align: middle;
padding-top: 4px;
width: 80%;
padding-right: 10px;
box-sizing: border-box; }
.snapcast__client__latency .latency-control .zero {
position: absolute;
top: -4px;
left: 50%;
bottom: 0;
width: 1px;
background: #383734;
z-index: 0; }
.snapcast__client__latency .latency-control .progress.positive {
border-top-left-radius: 0;
border-bottom-left-radius: 0; }
.snapcast__client__latency .latency-control .progress.negative {
border-top-right-radius: 0;
border-bottom-right-radius: 0; }
.snapcast__client__latency .latency-control .progress.negative:after {
right: auto;
left: -1px; }
@media (max-width: 800px) {
.snapcast__client {
padding-left: 0 !important;
padding-right: 0 !important;
padding-top: 0 !important; }
.snapcast__client .col {
clear: both;
display: block !important;
float: none !important;
width: auto !important;
padding: 0; }
.snapcast__client .col::after {
content: ''; content: '';
clear: both; clear: both;
display: block; } display: block; }
.snapcast .groups .group .clients .client:not(:first-child) { .snapcast__client .col.volume, .snapcast__client .col.latency {
padding-top: 8px; } padding-top: 5px; } }
.snapcast .groups .group .clients .client > .name {
width: 40%;
padding-bottom: 4px;
position: relative;
display: block;
box-sizing: border-box;
border: 0; }
.snapcast .groups .group .clients .client > .name input {
width: 100%;
padding-right: 30px; }
.snapcast .groups .group .clients .client > .name .group-dropdown-field {
float: right;
margin-bottom: -3.2rem; }
.snapcast .groups .group .clients .client > .name .group-dropdown-field .icon {
padding-right: 0; }
.snapcast .groups .group .clients .client > .volume {
width: 28%;
padding-left: 2%; }
.snapcast .groups .group .clients .client > .latency {
width: 28%;
padding-left: 2%; }
.snapcast .groups .group .clients .client > .latency input[type="number"] {
width: 20%; }
.snapcast .groups .group .clients .client .latency-control {
display: inline-block;
vertical-align: middle;
padding-top: 4px;
width: 80%;
padding-right: 10px;
box-sizing: border-box; }
.snapcast .groups .group .clients .client .latency-control .zero {
position: absolute;
top: -4px;
left: 50%;
bottom: 0;
width: 1px;
background: #383734;
z-index: 0; }
.snapcast .groups .group .clients .client .latency-control .progress.positive {
border-top-left-radius: 0;
border-bottom-left-radius: 0; }
.snapcast .groups .group .clients .client .latency-control .progress.negative {
border-top-right-radius: 0;
border-bottom-right-radius: 0; }
.snapcast .groups .group .clients .client .latency-control .progress.negative:after {
right: auto;
left: -1px; }
@media (max-width: 800px) {
.snapcast .groups .group .clients .client {
padding-left: 0 !important;
padding-right: 0 !important;
padding-top: 0 !important; }
.snapcast .groups .group .clients .client .col {
clear: both;
display: block !important;
float: none !important;
width: auto !important;
padding: 0; }
.snapcast .groups .group .clients .client .col::after {
content: '';
clear: both;
display: block; }
.snapcast .groups .group .clients .client .col.volume, .snapcast .groups .group .clients .client .col.latency {
padding-top: 5px; } }
.output-control { .output-control {
position: relative; } position: relative; }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -98,7 +98,7 @@
// Release details // Release details
// These are automatically injected to built HTML // These are automatically injected to built HTML
var build = "1537746267"; var build = "1537753000";
var version = "3.26.2"; var version = "3.26.2";
// Construct the script tag // Construct the script tag

View File

@ -53,7 +53,7 @@ class Snapcast extends React.Component{
} }
return ( return (
<div className="list clients"> <div className="list snapcast__clients">
{ {
group.clients.map(client => { group.clients.map(client => {
var name = client.config.name ? client.config.name : client.host.name; var name = client.config.name ? client.config.name : client.host.name;
@ -78,10 +78,10 @@ class Snapcast extends React.Component{
}); });
return ( return (
<div className="list-item client" key={client.id}> <div className={"list-item snapcast__client "+(client.connected ? "snapcast__client--connected" : "snapcast__client--disconnected")} key={client.id}>
<div className="col name"> <div className="col name snapcast__client__name">
<DropdownField <DropdownField
className="group-dropdown-field" className="snapcast__client__group-dropdown-field"
icon="settings" icon="settings"
name="Group" name="Group"
no_label no_label
@ -96,16 +96,16 @@ class Snapcast extends React.Component{
value={name} value={name}
/> />
</div> </div>
<div className="col volume"> <div className="col snapcast__client__volume">
<VolumeControl <VolumeControl
className="client-volume-control" className="snapcast__client__volume-control"
volume={client.config.volume.percent} volume={client.config.volume.percent}
mute={client.config.volume.muted} mute={client.config.volume.muted}
onVolumeChange={percent => this.props.snapcastActions.setClientVolume(client.id, percent)} onVolumeChange={percent => this.props.snapcastActions.setClientVolume(client.id, percent)}
onMuteChange={mute => this.props.snapcastActions.setClientMute(client.id, mute)} onMuteChange={mute => this.props.snapcastActions.setClientMute(client.id, mute)}
/> />
</div> </div>
<div className="col latency"> <div className="col snapcast__client__latency">
<LatencyControl <LatencyControl
max="100" max="100"
value={client.config.latency} value={client.config.latency}
@ -201,7 +201,7 @@ class Snapcast extends React.Component{
</div> </div>
</div> </div>
<div className="groups"> <div className="snapcast__groups">
{ {
groups.map(group => { groups.map(group => {
@ -214,7 +214,7 @@ class Snapcast extends React.Component{
group_volume = group_volume / group.clients.length; group_volume = group_volume / group.clients.length;
return ( return (
<div className="group" key={group.id}> <div className="snapcast__group" key={group.id}>
<div className="field"> <div className="field">
<div className="name"> <div className="name">
Name Name
@ -250,7 +250,7 @@ class Snapcast extends React.Component{
</div> </div>
<div className="input"> <div className="input">
<VolumeControl <VolumeControl
className="group-volume-control" className="snapcast__group__volume-control"
volume={group_volume} volume={group_volume}
mute={group.muted} mute={group.muted}
onVolumeChange={(percent, old_percent) => this.props.snapcastActions.setGroupVolume(group.id, percent, old_percent)} onVolumeChange={(percent, old_percent) => this.props.snapcastActions.setGroupVolume(group.id, percent, old_percent)}

View File

@ -8,6 +8,16 @@ export function set(data){
} }
} }
export function request(method, params = null, response_callback = null, error_callback = null){
return {
type: 'MOPIDY_REQUEST',
method: method,
params: params,
response_callback: response_callback,
error_callback: error_callback
}
}
export function connect(){ export function connect(){
return { return {
type: 'MOPIDY_CONNECT' type: 'MOPIDY_CONNECT'

View File

@ -241,6 +241,28 @@ const MopidyMiddleware = (function(){
}) })
break; break;
case 'MOPIDY_REQUEST':
request(socket, store, action.method, action.params)
.then(
response => {
if (action.response_callback){
store.dispatch(action.response_callback.call(this, response));
}
},
error => {
if (action.error_callback){
store.dispatch(action.error_callback.call(this, error));
} else {
store.dispatch(coreActions.handleException(
'Mopidy request failed',
error,
action.method,
action
));
}
}
);
break
/** /**
* General playback * General playback

View File

@ -75,9 +75,9 @@ export function connectionRemoved(connection){
} }
} }
export function instruct(method, params = null, response_callback = null, error_callback = null){ export function request(method, params = null, response_callback = null, error_callback = null){
return { return {
type: 'PUSHER_INSTRUCT', type: 'PUSHER_REQUEST',
method: method, method: method,
params: params, params: params,
response_callback: response_callback, response_callback: response_callback,

View File

@ -244,7 +244,7 @@ const PusherMiddleware = (function(){
next(action); next(action);
break; break;
case 'PUSHER_INSTRUCT': case 'PUSHER_REQUEST':
request(store, action.method, action.params) request(store, action.method, action.params)
.then( .then(
response => { response => {
@ -257,8 +257,10 @@ const PusherMiddleware = (function(){
store.dispatch(action.error_callback.call(this, error)); store.dispatch(action.error_callback.call(this, error));
} else { } else {
store.dispatch(coreActions.handleException( store.dispatch(coreActions.handleException(
'Instruct failed', 'Pusher request failed',
error error,
action.method,
action
)); ));
} }
} }

View File

@ -12,7 +12,7 @@ const SnapcastMiddleware = (function(){
// A snapcast request is an alias of the Pusher request // A snapcast request is an alias of the Pusher request
const request = (store, params = null, response_callback = null, error_callback = null) => { const request = (store, params = null, response_callback = null, error_callback = null) => {
store.dispatch( store.dispatch(
pusherActions.instruct( pusherActions.request(
'snapcast_instruct', 'snapcast_instruct',
params, params,
response_callback, response_callback,

View File

@ -5,149 +5,159 @@
margin-bottom: 0px; margin-bottom: 0px;
} }
.volume-control { &__group {
&__volume-control {
.mute-control {
display: inline-block;
float: left;
padding: 0 5px;
border: 0;
}
.slider-wrapper {
margin-left: 30px;
}
&.group-volume-control {
padding: 10px 0 5px; padding: 10px 0 5px;
display: block; display: block;
width: 100%; width: 100%;
box-sizing: border-box; box-sizing: border-box;
.mute-control {
display: inline-block;
float: left;
padding: 0 5px;
border: 0;
}
.slider-wrapper {
margin-left: 30px;
}
}
}
&__groups {
padding-top: 10px;
}
&__group {
padding-top: 10px;
border-top: 1px solid $grey;
&:not(:last-child){
padding-bottom: 20px;
}
}
&__clients {
padding: 0 10px;
}
&__client {
@include clearfix();
border: 0;
padding: 0;
clear: both;
&:not(:first-child){
padding-top: 8px;
} }
&.client-volume-control { &__volume-control {
padding-top: 11px; padding-top: 11px;
padding-right: 10px; padding-right: 10px;
display: block; display: block;
vertical-align: middle; vertical-align: middle;
box-sizing: border-box; box-sizing: border-box;
}
}
.groups { .mute-control {
padding-top: 10px; display: inline-block;
float: left;
.group { padding: 0 5px;
padding-top: 10px; border: 0;
border-top: 1px solid $grey;
&:not(:last-child){
padding-bottom: 20px;
} }
.clients { .slider-wrapper {
padding: 0 10px; margin-left: 30px;
}
}
.client { &__name {
@include clearfix(); width: 40%;
border: 0; padding-bottom: 4px;
padding: 0; position: relative;
clear: both; display: block;
box-sizing: border-box;
border: 0;
&:not(:first-child){ input {
padding-top: 8px; width: 100%;
padding-right: 30px;
}
}
&__group-dropdown-field {
float: right;
margin-bottom: -3.2rem;
.icon {
padding-right: 0;
}
}
&__volume {
width: 28%;
padding-left: 2%;
}
&__latency {
width: 28%;
padding-left: 2%;
input[type="number"] {
width: 20%;
}
.latency-control {
display: inline-block;
vertical-align: middle;
padding-top: 4px;
width: 80%;
padding-right: 10px;
box-sizing: border-box;
.zero {
position: absolute;
top: -4px;
left: 50%;
bottom: 0;
width: 1px;
background: $grey;
z-index: 0;
}
.progress.positive {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.progress.negative {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
&:after {
right: auto;
left: -1px;
} }
}
}
}
& > .name { @include responsive($bp_medium){
width: 40%; padding-left: 0 !important;
padding-bottom: 4px; padding-right: 0 !important;
position: relative; padding-top: 0 !important;
display: block;
box-sizing: border-box;
border: 0;
input { .col {
width: 100%; @include clearfix();
padding-right: 30px; clear: both;
} display: block !important;
float: none !important;
width: auto !important;
padding: 0;
.group-dropdown-field { &.volume,
float: right; &.latency {
margin-bottom: -3.2rem; padding-top: 5px;
.icon {
padding-right: 0;
}
}
}
& > .volume {
width: 28%;
padding-left: 2%;
}
& > .latency {
width: 28%;
padding-left: 2%;
input[type="number"] {
width: 20%;
}
}
.latency-control {
display: inline-block;
vertical-align: middle;
padding-top: 4px;
width: 80%;
padding-right: 10px;
box-sizing: border-box;
.zero {
position: absolute;
top: -4px;
left: 50%;
bottom: 0;
width: 1px;
background: $grey;
z-index: 0;
}
.progress.positive {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.progress.negative {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
&:after {
right: auto;
left: -1px;
}
}
}
@include responsive($bp_medium){
padding-left: 0 !important;
padding-right: 0 !important;
padding-top: 0 !important;
.col {
@include clearfix();
clear: both;
display: block !important;
float: none !important;
width: auto !important;
padding: 0;
&.volume,
&.latency {
padding-top: 5px;
}
}
}
} }
} }
} }