Album art on the selection screen

This commit is contained in:
Matt Claypotch 2015-01-11 19:22:13 -08:00
Родитель ea750eda54
Коммит 151a9521b0
5 изменённых файлов: 201 добавлений и 166 удалений

Просмотреть файл

@ -13,7 +13,9 @@
"dependencies": {
"express": "^4.10.6",
"request": "^2.51.0",
"socket.io": "^1.2.1",
"socket.io": "^1.2.1"
},
"devDependencies": {
"react-tools": "^0.12.2"
},
"repository": {

Просмотреть файл

@ -73,8 +73,11 @@ var ZoneOverview = React.createClass({
if (this.props.nowPlaying) {
return (
<div>
<div>{this.props.name}</div>
<div>{this.props.nowPlaying.sArtist} - {this.props.nowPlaying.sSong}</div>
<AlbumArt url={this.props.nowPlaying.sArtwork} />
<div className="info">
<div>{this.props.name}</div>
<div>{this.props.nowPlaying.sArtist} - {this.props.nowPlaying.sSong}</div>
</div>
</div>
);
}
@ -130,9 +133,6 @@ var ZoneDetail = React.createClass({
if (z) {
var now = z.aData.aNowPlaying;
var queue = z.aData.aQueue;
var style = {
backgroundImage: 'url(' + now.sArtwork + ')'
};
return (
<section className="detail">
<header>
@ -140,7 +140,7 @@ var ZoneDetail = React.createClass({
<h1>{z.name}</h1>
</header>
<div className="nowplaying">
<div className="art" style={style} />
<AlbumArt url={now.sArtwork} />
<div className="info">
<h1>{now.sArtist} - {now.sSong}</h1>
<User className="user" avatar={now.sUserImage} name={now.sUser} />
@ -161,8 +161,17 @@ var ZoneDetail = React.createClass({
}
});
var AlbumArt = React.createClass({
render: function () {
var style = {
backgroundImage: 'url(' + this.props.url + ')'
};
return <div className="art" style={style} />;
}
});
var User = React.createClass({
render: function() {
render: function () {
var style = {
backgroundImage: 'url(' + this.props.avatar + ')'
};

Просмотреть файл

@ -4,157 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<link href='//fonts.googleapis.com/css?family=Fira+Sans:300italic,300' rel='stylesheet' type='text/css'>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
height: 100%;
margin: 0;
}
body {
background: #000;
color: #fff;
font-family: 'Fira Sans', sans-serif;
overflow: hidden;
font-size: 4vmin;
height: 100%;
}
#app {
height: 100vh;
width: 100vw;
overflow: hidden;
}
.app {
width: 300vw;
display: flex;
flex-direction: row;
align-items: stretch;
height: 100vh;
transition: 300ms transform ease-out;
}
.app > section {
height: 100vh;
width: 100vw;
}
.app[data-mode="overview"] {
transform: translate(0, 0);
}
.app[data-mode="detail"] {
transform: translate(-100vw, 0);
}
.detail > * + * {
margin-top: 1rem;
}
.queue-container {
position: relative;
flex: 1;
overflow: hidden;
}
.queue {
height: 100%;
overflow: auto;
font-size: 5vmin;
}
.queue-item {
display: flex;
flex-direction: row;
align-items: center;
}
.queue-item > * + * {
margin-left: 1em;
}
.queue-item .info {
flex: 1;
}
.queue .user {
height: 1em;
width: 1em;
}
.queue .up, .queue .down {
white-space: nowrap;
width: 10vmin;
text-align: center;
}
.detail {
display: flex;
padding: 1em;
flex-direction: column;
}
.overview {
height: 100%;
display: flex;
flex-direction: column;
}
.overview .zone-item {
flex: 1;
display: flex;
align-items: center;
font-size: 4vmin;
}
header {
display: flex;
flex-direction: row;
align-items: center;
padding: 0 1rem 0 0;
font-size: 4vmin;
}
header > * + * {
margin-left: 1em;
}
header a {
padding: 1rem 1rem 1rem 0;
}
header > h1 {
flex: 1;
}
.user {
border-radius: 100%;
background-size: cover;
background-position: center;
}
.upnext {
font-style: italic;
font-size: 5vmin;
margin-top: 2rem;
}
.nowplaying {
display: flex;
flex-direction: row;
}
.nowplaying .info {
display: flex;
font-size: 4vmin;
line-height: 6vmin;
margin-left: 1em;
flex-direction: column;
justify-content: flex-end;
align-items: flex-start;
}
.nowplaying .art {
flex-shrink: 0;
height: 30vmin;
width: 30vmin;
}
.nowplaying .user {
height: 8vmin;
width: 8vmin;
margin-top: 1rem;
}
.art {
background-position: center;
background-size: cover;
}
a:link, a:visited, a:active {
color: #fff;
text-decoration: none;
}
</style>
<link rel="stylesheet" href='/main.css'>
</head>
<body>
<div id="app">

165
static/main.css Normal file
Просмотреть файл

@ -0,0 +1,165 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
height: 100%;
margin: 0;
}
body {
background: #000;
color: #fff;
font-family: 'Fira Sans', sans-serif;
overflow: hidden;
font-size: 4vmin;
height: 100%;
}
a:link, a:visited, a:active {
color: #fff;
text-decoration: none;
}
/* App */
#app {
height: 100vh;
width: 100vw;
overflow: hidden;
}
.app {
width: 300vw;
display: flex;
flex-direction: row;
align-items: stretch;
height: 100vh;
transition: 300ms transform ease-out;
}
.app > section {
height: 100vh;
width: 100vw;
}
.app[data-mode="overview"] {
transform: translate(0, 0);
}
.app[data-mode="detail"] {
transform: translate(-100vw, 0);
}
/* Queue */
.queue-container {
position: relative;
flex: 1;
overflow: hidden;
}
.queue {
height: 100%;
overflow: auto;
font-size: 4vmin;
}
.queue-item {
display: flex;
flex-direction: row;
align-items: center;
}
.queue-item > * + * {
margin-left: 1em;
}
.queue-item .info {
flex: 1;
}
.queue .user {
height: 1em;
width: 1em;
}
.queue .up, .queue .down {
white-space: nowrap;
width: 10vmin;
text-align: center;
}
/* Detail */
.detail {
display: flex;
padding: 1em;
flex-direction: column;
}
.detail > * + * {
margin-top: 1rem;
}
header {
display: flex;
flex-direction: row;
align-items: center;
font-size: 3vmin;
}
header > * + * {
margin-left: 1em;
}
header a {
padding: 1rem 1rem 1rem 0;
}
header > h1 {
flex: 1;
}
.user {
border-radius: 100%;
background-size: cover;
background-position: center;
}
.upnext {
font-style: italic;
font-size: 5vmin;
margin-top: 2rem;
}
.nowplaying {
display: flex;
flex-direction: row;
}
.nowplaying .info {
display: flex;
font-size: 4vmin;
line-height: 6vmin;
margin-left: 1em;
flex-direction: column;
justify-content: flex-end;
align-items: flex-start;
}
.nowplaying .art {
flex-shrink: 0;
height: 30vmin;
width: 30vmin;
}
.nowplaying .user {
height: 8vmin;
width: 8vmin;
margin-top: 1rem;
}
.art {
background-position: center;
background-size: cover;
}
/* Overview */
.overview {
height: 100%;
display: flex;
flex-direction: column;
}
.overview .zone-item {
flex: 1;
font-size: 4vmin;
}
.zone-item > div {
display: flex;
flex-direction: row;
align-items: center;
}
.zone-item .art {
height: 20vh;
width: 20vh;
flex-shrink: 0;
margin-right: 1em;
}

Просмотреть файл

@ -73,8 +73,11 @@ var ZoneOverview = React.createClass({displayName: "ZoneOverview",
if (this.props.nowPlaying) {
return (
React.createElement("div", null,
React.createElement("div", null, this.props.name),
React.createElement("div", null, this.props.nowPlaying.sArtist, " - ", this.props.nowPlaying.sSong)
React.createElement(AlbumArt, {url: this.props.nowPlaying.sArtwork}),
React.createElement("div", {className: "info"},
React.createElement("div", null, this.props.name),
React.createElement("div", null, this.props.nowPlaying.sArtist, " - ", this.props.nowPlaying.sSong)
)
)
);
}
@ -130,9 +133,6 @@ var ZoneDetail = React.createClass({displayName: "ZoneDetail",
if (z) {
var now = z.aData.aNowPlaying;
var queue = z.aData.aQueue;
var style = {
backgroundImage: 'url(' + now.sArtwork + ')'
};
return (
React.createElement("section", {className: "detail"},
React.createElement("header", null,
@ -140,7 +140,7 @@ var ZoneDetail = React.createClass({displayName: "ZoneDetail",
React.createElement("h1", null, z.name)
),
React.createElement("div", {className: "nowplaying"},
React.createElement("div", {className: "art", style: style}),
React.createElement(AlbumArt, {url: now.sArtwork}),
React.createElement("div", {className: "info"},
React.createElement("h1", null, now.sArtist, " - ", now.sSong),
React.createElement(User, {className: "user", avatar: now.sUserImage, name: now.sUser})
@ -161,8 +161,17 @@ var ZoneDetail = React.createClass({displayName: "ZoneDetail",
}
});
var AlbumArt = React.createClass({displayName: "AlbumArt",
render: function () {
var style = {
backgroundImage: 'url(' + this.props.url + ')'
};
return React.createElement("div", {className: "art", style: style});
}
});
var User = React.createClass({displayName: "User",
render: function() {
render: function () {
var style = {
backgroundImage: 'url(' + this.props.avatar + ')'
};