Beginning of Discover page and remove dead code

This commit is contained in:
Lucas Verney 2016-08-03 15:44:29 +02:00
parent b450365af0
commit df9dca3a11
27 changed files with 310 additions and 135 deletions

View File

@ -10,6 +10,7 @@ React.
Just drop this repo in a location served by a webserver and head your browser Just drop this repo in a location served by a webserver and head your browser
to the correct URL :) to the correct URL :)
Or you can use the [hosted version](https://phyks.github.io/ampache_react/).
## Support ## Support

View File

@ -51,7 +51,7 @@ export default function (action, requestType, successType, failureType) {
dispatch: [ dispatch: [
fetchItemsRequest, fetchItemsRequest,
jsonData => dispatch => { jsonData => dispatch => {
dispatch(fetchItemsSuccess(jsonData[itemName], jsonData[action], pageNumber)); dispatch(fetchItemsSuccess(jsonData[itemName], jsonData.totalCount, pageNumber));
}, },
fetchItemsFailure fetchItemsFailure
], ],

View File

@ -10,16 +10,18 @@ import css from "../styles/Album.scss";
const albumMessages = defineMessages(messagesMap(commonMessages)); const albumMessages = defineMessages(messagesMap(commonMessages));
export class AlbumTrackRow extends Component { class AlbumTrackRowCSS extends Component {
render () { render () {
const length = formatLength(this.props.track.length); const length = formatLength(this.props.track.time);
return ( return (
<tr> <tr>
<td> <td>
<button styleName="play">
<span className="sr-only"> <span className="sr-only">
<FormattedMessage {...albumMessages["app.common.play"]} /> <FormattedMessage {...albumMessages["app.common.play"]} />
</span> </span>
<span className="glyphicon glyphicon-play-circle" aria-hidden="true"></span> <span className="glyphicon glyphicon-play-circle" aria-hidden="true"></span>
</button>
</td> </td>
<td>{this.props.track.track}</td> <td>{this.props.track.track}</td>
<td>{this.props.track.name}</td> <td>{this.props.track.name}</td>
@ -29,10 +31,12 @@ export class AlbumTrackRow extends Component {
} }
} }
AlbumTrackRow.propTypes = { AlbumTrackRowCSS.propTypes = {
track: PropTypes.object.isRequired track: PropTypes.object.isRequired
}; };
export let AlbumTrackRow = CSSModules(AlbumTrackRowCSS, css);
class AlbumTracksTableCSS extends Component { class AlbumTracksTableCSS extends Component {
render () { render () {
@ -60,13 +64,13 @@ class AlbumRowCSS extends Component {
render () { render () {
return ( return (
<div className="row" styleName="row"> <div className="row" styleName="row">
<div className="col-sm-offset-2 col-xs-10" styleName="nameRow"> <div className="col-sm-offset-2 col-xs-9 col-sm-10" styleName="nameRow">
<h2>{this.props.album.name}</h2> <h2>{this.props.album.name}</h2>
</div> </div>
<div className="col-xs-2" styleName="artRow"> <div className="col-xs-3 col-sm-2" styleName="artRow">
<p className="text-center"><img src={this.props.album.art} width="200" height="200" className="img-responsive img-circle" styleName="art" alt={this.props.album.name} /></p> <p className="text-center"><img src={this.props.album.art} width="200" height="200" className="img-responsive img-circle" styleName="art" alt={this.props.album.name} /></p>
</div> </div>
<div className="col-sm-10 table-responsive"> <div className="col-xs-9 col-sm-10 table-responsive">
{ {
Array.isArray(this.props.album.tracks) ? Array.isArray(this.props.album.tracks) ?
<AlbumTracksTable tracks={this.props.album.tracks} /> : <AlbumTracksTable tracks={this.props.album.tracks} /> :

126
app/components/Discover.jsx Normal file
View File

@ -0,0 +1,126 @@
import React, { Component } from "react";
import CSSModules from "react-css-modules";
import css from "../styles/Discover.scss";
export default class DiscoverCSS extends Component {
render () {
const artistsAlbumsSongsDropdown = (
<div className="btn-group">
<button type="button" className="btn btn-default dropdown-toggle" styleName="h2Title" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span styleName="dashedUnderline">albums</span>
<span className="caret" styleName="caret"></span>
</button>
<ul className="dropdown-menu" styleName="dropdown-menu">
<li><a href="#" role="button">artists</a></li>
<li className="active"><a href="#" role="button">albums</a></li>
<li><a href="#" role="button">songs</a></li>
</ul>
</div>
);
const bobDylan = (
<div className="col-xs-4 col-sm-2">
<div className="text-center">
<a title="Aller à la page de l'artiste" href="#/artist/15">
<img src="" width="200" height="200" className="img-responsive img-circle art" alt="Bob Dylan"/>
</a>
<h4>
Bob Dylan
</h4>
</div>
</div>
);
return (
<div className="row">
<h2 styleName="noMarginTop">
<span className="glyphicon glyphicon-heart" aria-hidden="true"></span>&nbsp;
More { artistsAlbumsSongsDropdown } you might like
</h2>
<div className="col-xs-12">
<div className="row">
<div className="col-xs-4 col-sm-2 col-sm-offset-1">
<div className="text-center">
<a title="Aller à la page de l'artiste" href="#/artist/15">
<img src="" width="200" height="200" className="img-responsive img-circle art" alt="Bob Dylan"/>
</a>
<h4>
Bob Dylan
</h4>
</div>
</div>
{ bobDylan }
{ bobDylan }
{ bobDylan }
{ bobDylan }
</div>
<hr/>
</div>
<h2>
<span className="glyphicon glyphicon-hand-up" aria-hidden="true"></span>&nbsp;
Popular { artistsAlbumsSongsDropdown }
</h2>
<div className="col-xs-12">
<div className="row">
<div className="col-xs-4 col-sm-2 col-sm-offset-1">
<div className="text-center">
<a title="Aller à la page de l'artiste" href="#/artist/15">
<img src="" width="200" height="200" className="img-responsive img-circle art" alt="Bob Dylan"/>
</a>
<h4>
Bob Dylan
</h4>
</div>
</div>
{ bobDylan }
{ bobDylan }
{ bobDylan }
{ bobDylan }
</div>
<hr/>
</div>
<h2>
<span className="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>&nbsp;
Recent additions
</h2>
<div className="col-xs-12">
<div className="row">
<div className="col-xs-4 col-sm-2 col-sm-offset-1">
<div className="text-center">
<a title="Aller à la page de l'artiste" href="#/artist/15">
<img src="" width="200" height="200" className="img-responsive img-circle art" alt="Bob Dylan"/>
</a>
<h4>
Bob Dylan
</h4>
</div>
</div>
{ bobDylan }
{ bobDylan }
{ bobDylan }
{ bobDylan }
</div>
<hr/>
</div>
<h2>
<span className="glyphicon glyphicon-volume-up" aria-hidden="true"></span>&nbsp;
Currently playing
</h2>
<table>
</table>
</div>
);
}
}
DiscoverCSS.propTypes = {
};
export default CSSModules(DiscoverCSS, css);

View File

@ -16,7 +16,7 @@ import css from "../styles/Songs.scss";
const songsMessages = defineMessages(messagesMap(Array.concat([], commonMessages, messages))); const songsMessages = defineMessages(messagesMap(Array.concat([], commonMessages, messages)));
export class SongsTableRow extends Component { class SongsTableRowCSS extends Component {
render () { render () {
const length = formatLength(this.props.song.time); const length = formatLength(this.props.song.time);
const linkToArtist = "/artist/" + this.props.song.artist.id; const linkToArtist = "/artist/" + this.props.song.artist.id;
@ -24,10 +24,12 @@ export class SongsTableRow extends Component {
return ( return (
<tr> <tr>
<td> <td>
<button styleName="play">
<span className="sr-only"> <span className="sr-only">
<FormattedMessage {...songsMessages["app.common.play"]} /> <FormattedMessage {...songsMessages["app.common.play"]} />
</span> </span>
<span className="glyphicon glyphicon-play-circle" aria-hidden="true"></span> <span className="glyphicon glyphicon-play-circle" aria-hidden="true"></span>
</button>
</td> </td>
<td className="title">{this.props.song.name}</td> <td className="title">{this.props.song.name}</td>
<td className="artist"><Link to={linkToArtist}>{this.props.song.artist.name}</Link></td> <td className="artist"><Link to={linkToArtist}>{this.props.song.artist.name}</Link></td>
@ -39,10 +41,12 @@ export class SongsTableRow extends Component {
} }
} }
SongsTableRow.propTypes = { SongsTableRowCSS.propTypes = {
song: PropTypes.object.isRequired song: PropTypes.object.isRequired
}; };
export let SongsTableRow = CSSModules(SongsTableRowCSS, css);
class SongsTableCSS extends Component { class SongsTableCSS extends Component {
render () { render () {

View File

@ -31,7 +31,7 @@ class FilterBarCSSIntl extends Component {
<div className="col-xs-12 col-sm-6 col-md-4 input-group"> <div className="col-xs-12 col-sm-6 col-md-4 input-group">
<form className="form-inline" onSubmit={this.handleChange} aria-describedby="filterInputDescription" role="search" aria-label={formatMessage(filterMessages["app.filter.filter"])}> <form className="form-inline" onSubmit={this.handleChange} aria-describedby="filterInputDescription" role="search" aria-label={formatMessage(filterMessages["app.filter.filter"])}>
<div className="form-group" styleName="form-group"> <div className="form-group" styleName="form-group">
<input type="text" className="form-control" placeholder={formatMessage(filterMessages["app.filter.filter"])} aria-label={formatMessage(filterMessages["app.filter.filter"])} value={this.props.filterText} onChange={this.handleChange} ref="filterTextInput" /> <input type="search" className="form-control" placeholder={formatMessage(filterMessages["app.filter.filter"])} aria-label={formatMessage(filterMessages["app.filter.filter"])} value={this.props.filterText} onChange={this.handleChange} ref="filterTextInput" />
</div> </div>
</form> </form>
</div> </div>

View File

@ -17,7 +17,7 @@ class PaginationCSSIntl extends Component {
var lowerLimit = currentPage; var lowerLimit = currentPage;
var upperLimit = currentPage; var upperLimit = currentPage;
for (var b = 1; b < maxNumberPagesShown && b < nPages;) { for (let b = 1; b < maxNumberPagesShown && b < nPages;) {
if (lowerLimit > 1 ) { if (lowerLimit > 1 ) {
lowerLimit--; lowerLimit--;
b++; b++;
@ -84,8 +84,7 @@ class PaginationCSSIntl extends Component {
key++; key++;
} }
} }
var i = 0; for (let i = lowerLimit; i < upperLimit; i++) {
for (i = lowerLimit; i < upperLimit; i++) {
var className = "page-item"; var className = "page-item";
var currentSpan = null; var currentSpan = null;
if (this.props.currentPage == i) { if (this.props.currentPage == i) {
@ -103,8 +102,8 @@ class PaginationCSSIntl extends Component {
); );
key++; key++;
} }
if (i < this.props.nPages) { if (upperLimit < this.props.nPages) {
if (i < this.props.nPages - 1) { if (upperLimit < this.props.nPages - 1) {
// Eventually push "" // Eventually push ""
pagesButton.push( pagesButton.push(
<li className="page-item" key={key}> <li className="page-item" key={key}>

View File

@ -22,6 +22,9 @@ class SidebarLayoutIntl extends Component {
songs: (this.props.location.pathname == "/songs") ? "active" : "link", songs: (this.props.location.pathname == "/songs") ? "active" : "link",
search: (this.props.location.pathname == "/search") ? "active" : "link" search: (this.props.location.pathname == "/search") ? "active" : "link"
}; };
const collapseHamburger = function () {
$("#main-navbar").collapse("hide");
};
return ( return (
<div> <div>
<div className="col-xs-12 col-md-1 col-lg-2" styleName="sidebar"> <div className="col-xs-12 col-md-1 col-lg-2" styleName="sidebar">
@ -34,7 +37,7 @@ class SidebarLayoutIntl extends Component {
<span className="icon-bar" styleName="icon-bar"></span> <span className="icon-bar" styleName="icon-bar"></span>
</button> </button>
<h1 className="text-center" styleName="title"> <h1 className="text-center" styleName="title">
<IndexLink to="/" styleName="link"> <IndexLink styleName="link" to="/" styleName="link" onClick={collapseHamburger}>
<img alt="A" src="./app/assets/img/ampache-blue.png" styleName="imgTitle" /> <img alt="A" src="./app/assets/img/ampache-blue.png" styleName="imgTitle" />
<span className="hidden-md">mpache</span> <span className="hidden-md">mpache</span>
</IndexLink> </IndexLink>
@ -44,7 +47,7 @@ class SidebarLayoutIntl extends Component {
<div className="container-fluid" styleName="container-fluid"> <div className="container-fluid" styleName="container-fluid">
<ul className="nav navbar-nav" styleName="nav"> <ul className="nav navbar-nav" styleName="nav">
<li> <li>
<Link to="/" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.home"])} styleName="link"> <Link to="/" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.home"])} styleName="link" onClick={collapseHamburger}>
<span className="glyphicon glyphicon-home" aria-hidden="true"></span> <span className="glyphicon glyphicon-home" aria-hidden="true"></span>
<span className="sr-only"> <span className="sr-only">
<FormattedMessage {...sidebarLayoutMessages["app.sidebarLayout.home"]} /> <FormattedMessage {...sidebarLayoutMessages["app.sidebarLayout.home"]} />
@ -52,7 +55,7 @@ class SidebarLayoutIntl extends Component {
</Link> </Link>
</li> </li>
<li> <li>
<Link to="/settings" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.settings"])} styleName="link"> <Link to="/settings" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.settings"])} styleName="link" onClick={collapseHamburger}>
<span className="glyphicon glyphicon-wrench" aria-hidden="true"></span> <span className="glyphicon glyphicon-wrench" aria-hidden="true"></span>
<span className="sr-only"> <span className="sr-only">
<FormattedMessage {...sidebarLayoutMessages["app.sidebarLayout.settings"]} /> <FormattedMessage {...sidebarLayoutMessages["app.sidebarLayout.settings"]} />
@ -60,7 +63,7 @@ class SidebarLayoutIntl extends Component {
</Link> </Link>
</li> </li>
<li> <li>
<Link to="/logout" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.logout"])} styleName="link"> <Link to="/logout" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.logout"])} styleName="link" onClick={collapseHamburger}>
<span className="glyphicon glyphicon-off" aria-hidden="true"></span> <span className="glyphicon glyphicon-off" aria-hidden="true"></span>
<span className="sr-only"> <span className="sr-only">
<FormattedMessage {...sidebarLayoutMessages["app.sidebarLayout.logout"]} /> <FormattedMessage {...sidebarLayoutMessages["app.sidebarLayout.logout"]} />
@ -72,7 +75,7 @@ class SidebarLayoutIntl extends Component {
</div> </div>
<ul className="nav" styleName="nav"> <ul className="nav" styleName="nav">
<li> <li>
<Link to="/discover" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.discover"])} styleName={isActive.discover}> <Link to="/discover" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.discover"])} styleName={isActive.discover} onClick={collapseHamburger}>
<span className="glyphicon glyphicon-globe" aria-hidden="true"></span> <span className="glyphicon glyphicon-globe" aria-hidden="true"></span>
<span className="hidden-md"> <span className="hidden-md">
&nbsp;<FormattedMessage {...sidebarLayoutMessages["app.sidebarLayout.discover"]} /> &nbsp;<FormattedMessage {...sidebarLayoutMessages["app.sidebarLayout.discover"]} />
@ -80,7 +83,7 @@ class SidebarLayoutIntl extends Component {
</Link> </Link>
</li> </li>
<li> <li>
<Link to="/browse" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.browse"])} styleName={isActive.browse}> <Link to="/browse" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.browse"])} styleName={isActive.browse} onClick={collapseHamburger}>
<span className="glyphicon glyphicon-headphones" aria-hidden="true"></span> <span className="glyphicon glyphicon-headphones" aria-hidden="true"></span>
<span className="hidden-md"> <span className="hidden-md">
&nbsp;<FormattedMessage {...sidebarLayoutMessages["app.sidebarLayout.browse"]} /> &nbsp;<FormattedMessage {...sidebarLayoutMessages["app.sidebarLayout.browse"]} />
@ -88,7 +91,7 @@ class SidebarLayoutIntl extends Component {
</Link> </Link>
<ul className="nav text-center" styleName="nav-list"> <ul className="nav text-center" styleName="nav-list">
<li> <li>
<Link to="/artists" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.browseArtists"])} styleName={isActive.artists}> <Link to="/artists" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.browseArtists"])} styleName={isActive.artists} onClick={collapseHamburger}>
<span className="glyphicon glyphicon-user" aria-hidden="true"></span> <span className="glyphicon glyphicon-user" aria-hidden="true"></span>
<span className="sr-only text-capitalize"> <span className="sr-only text-capitalize">
<FormattedMessage {...sidebarLayoutMessages["app.common.artist"]} values={{itemCount: 42}} /> <FormattedMessage {...sidebarLayoutMessages["app.common.artist"]} values={{itemCount: 42}} />
@ -99,7 +102,7 @@ class SidebarLayoutIntl extends Component {
</Link> </Link>
</li> </li>
<li> <li>
<Link to="/albums" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.browseAlbums"])} styleName={isActive.albums}> <Link to="/albums" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.browseAlbums"])} styleName={isActive.albums} onClick={collapseHamburger}>
<span className="glyphicon glyphicon-cd" aria-hidden="true"></span> <span className="glyphicon glyphicon-cd" aria-hidden="true"></span>
<span className="sr-only text-capitalize"> <span className="sr-only text-capitalize">
<FormattedMessage {...sidebarLayoutMessages["app.common.album"]} values={{itemCount: 42}} /> <FormattedMessage {...sidebarLayoutMessages["app.common.album"]} values={{itemCount: 42}} />
@ -110,7 +113,7 @@ class SidebarLayoutIntl extends Component {
</Link> </Link>
</li> </li>
<li> <li>
<Link to="/songs" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.browseSongs"])} styleName={isActive.songs}> <Link to="/songs" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.browseSongs"])} styleName={isActive.songs} onClick={collapseHamburger}>
<span className="glyphicon glyphicon-music" aria-hidden="true"></span> <span className="glyphicon glyphicon-music" aria-hidden="true"></span>
<span className="sr-only text-capitalize"> <span className="sr-only text-capitalize">
<FormattedMessage {...sidebarLayoutMessages["app.common.track"]} values={{itemCount: 42}} /> <FormattedMessage {...sidebarLayoutMessages["app.common.track"]} values={{itemCount: 42}} />
@ -123,7 +126,7 @@ class SidebarLayoutIntl extends Component {
</ul> </ul>
</li> </li>
<li> <li>
<Link to="/search" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.search"])} styleName={isActive.search}> <Link to="/search" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.search"])} styleName={isActive.search} onClick={collapseHamburger}>
<span className="glyphicon glyphicon-search" aria-hidden="true"></span> <span className="glyphicon glyphicon-search" aria-hidden="true"></span>
<span className="hidden-md"> <span className="hidden-md">
&nbsp;<FormattedMessage {...sidebarLayoutMessages["app.sidebarLayout.search"]} /> &nbsp;<FormattedMessage {...sidebarLayoutMessages["app.sidebarLayout.search"]} />
@ -134,7 +137,7 @@ class SidebarLayoutIntl extends Component {
</nav> </nav>
</div> </div>
<div className="col-sm-11 col-sm-offset-1 col-md-10 col-md-offset-2" styleName="main-panel"> <div className="col-xs-12 col-md-11 col-md-offset-1 col-lg-10 col-lg-offset-2" styleName="main-panel" onClick={collapseHamburger}>
{this.props.children} {this.props.children}
</div> </div>
</div> </div>

View File

@ -1,6 +1,7 @@
import React, { Component, PropTypes } from "react"; import React, { Component, PropTypes } from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
// TODO: Handle expired session
export class RequireAuthentication extends Component { export class RequireAuthentication extends Component {
componentWillMount () { componentWillMount () {
this.checkAuth(this.props.isAuthenticated); this.checkAuth(this.props.isAuthenticated);

6
app/dist/1.1.js vendored

File diff suppressed because one or more lines are too long

2
app/dist/1.1.js.map vendored

File diff suppressed because one or more lines are too long

2
app/dist/fix.ie9.js vendored
View File

@ -1,2 +1,2 @@
!function(e){function t(r){if(n[r])return n[r].exports;var a=n[r]={exports:{},id:r,loaded:!1};return e[r].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var n={};return t.m=e,t.c=n,t.p="./",t(0)}({0:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(599);Object.keys(r).forEach(function(e){"default"!==e&&Object.defineProperty(t,e,{enumerable:!0,get:function(){return r[e]}})})},599:function(e,t){!function(t,n){function r(e,t){var n=e.createElement("p"),r=e.getElementsByTagName("head")[0]||e.documentElement;return n.innerHTML="x<style>"+t+"</style>",r.insertBefore(n.lastChild,r.firstChild)}function a(){var e=b.elements;return"string"==typeof e?e.split(" "):e}function o(e,t){var n=b.elements;"string"!=typeof n&&(n=n.join(" ")),"string"!=typeof e&&(e=e.join(" ")),b.elements=n+" "+e,s(t)}function c(e){var t=E[e[v]];return t||(t={},y++,e[v]=y,E[y]=t),t}function i(e,t,r){if(t||(t=n),f)return t.createElement(e);r||(r=c(t));var a;return a=r.cache[e]?r.cache[e].cloneNode():g.test(e)?(r.cache[e]=r.createElem(e)).cloneNode():r.createElem(e),!a.canHaveChildren||p.test(e)||a.tagUrn?a:r.frag.appendChild(a)}function l(e,t){if(e||(e=n),f)return e.createDocumentFragment();t=t||c(e);for(var r=t.frag.cloneNode(),o=0,i=a(),l=i.length;o<l;o++)r.createElement(i[o]);return r}function u(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return b.shivMethods?i(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+a().join().replace(/[\w\-:]+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(b,t.frag)}function s(e){e||(e=n);var t=c(e);return!b.shivCSS||d||t.hasCSS||(t.hasCSS=!!r(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),f||u(e,t),e}var d,f,m="3.7.3-pre",h=t.html5||{},p=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,g=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",y=0,E={};!function(){try{var e=n.createElement("a");e.innerHTML="<xyz></xyz>",d="hidden"in e,f=1==e.childNodes.length||function(){n.createElement("a");var e=n.createDocumentFragment();return"undefined"==typeof e.cloneNode||"undefined"==typeof e.createDocumentFragment||"undefined"==typeof e.createElement}()}catch(t){d=!0,f=!0}}();var b={elements:h.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:h.shivCSS!==!1,supportsUnknownElements:f,shivMethods:h.shivMethods!==!1,type:"default",shivDocument:s,createElement:i,createDocumentFragment:l,addElements:o};t.html5=b,s(n),"object"==typeof e&&e.exports&&(e.exports=b)}("undefined"!=typeof window?window:this,document)}}); !function(e){function t(r){if(n[r])return n[r].exports;var a=n[r]={exports:{},id:r,loaded:!1};return e[r].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var n={};return t.m=e,t.c=n,t.p="./",t(0)}({0:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(602);Object.keys(r).forEach(function(e){"default"!==e&&Object.defineProperty(t,e,{enumerable:!0,get:function(){return r[e]}})})},602:function(e,t){!function(t,n){function r(e,t){var n=e.createElement("p"),r=e.getElementsByTagName("head")[0]||e.documentElement;return n.innerHTML="x<style>"+t+"</style>",r.insertBefore(n.lastChild,r.firstChild)}function a(){var e=b.elements;return"string"==typeof e?e.split(" "):e}function o(e,t){var n=b.elements;"string"!=typeof n&&(n=n.join(" ")),"string"!=typeof e&&(e=e.join(" ")),b.elements=n+" "+e,s(t)}function c(e){var t=E[e[v]];return t||(t={},y++,e[v]=y,E[y]=t),t}function i(e,t,r){if(t||(t=n),f)return t.createElement(e);r||(r=c(t));var a;return a=r.cache[e]?r.cache[e].cloneNode():g.test(e)?(r.cache[e]=r.createElem(e)).cloneNode():r.createElem(e),!a.canHaveChildren||p.test(e)||a.tagUrn?a:r.frag.appendChild(a)}function l(e,t){if(e||(e=n),f)return e.createDocumentFragment();t=t||c(e);for(var r=t.frag.cloneNode(),o=0,i=a(),l=i.length;o<l;o++)r.createElement(i[o]);return r}function u(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return b.shivMethods?i(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+a().join().replace(/[\w\-:]+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(b,t.frag)}function s(e){e||(e=n);var t=c(e);return!b.shivCSS||d||t.hasCSS||(t.hasCSS=!!r(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),f||u(e,t),e}var d,f,m="3.7.3-pre",h=t.html5||{},p=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,g=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",y=0,E={};!function(){try{var e=n.createElement("a");e.innerHTML="<xyz></xyz>",d="hidden"in e,f=1==e.childNodes.length||function(){n.createElement("a");var e=n.createDocumentFragment();return"undefined"==typeof e.cloneNode||"undefined"==typeof e.createDocumentFragment||"undefined"==typeof e.createElement}()}catch(t){d=!0,f=!0}}();var b={elements:h.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:h.shivCSS!==!1,supportsUnknownElements:f,shivMethods:h.shivMethods!==!1,type:"default",shivDocument:s,createElement:i,createDocumentFragment:l,addElements:o};t.html5=b,s(n),"object"==typeof e&&e.exports&&(e.exports=b)}("undefined"!=typeof window?window:this,document)}});
//# sourceMappingURL=fix.ie9.js.map //# sourceMappingURL=fix.ie9.js.map

File diff suppressed because one or more lines are too long

48
app/dist/index.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
app/dist/style.css vendored

File diff suppressed because one or more lines are too long

View File

@ -46,17 +46,7 @@ function _checkAPIErrors (jsonData) {
return jsonData; return jsonData;
} }
function _uglyFixes () { function _uglyFixes (jsonData) {
if (typeof _uglyFixes.artistsCount === "undefined" ) {
_uglyFixes.artistsCount = 0;
}
if (typeof _uglyFixes.albumsCount === "undefined" ) {
_uglyFixes.albumsCount = 0;
}
if (typeof _uglyFixes.songsCount === "undefined" ) {
_uglyFixes.songsCount = 0;
}
var _uglyFixesSongs = function (songs) { var _uglyFixesSongs = function (songs) {
return songs.map(function (song) { return songs.map(function (song) {
// Fix for cdata left in artist and album // Fix for cdata left in artist and album
@ -121,7 +111,6 @@ function _uglyFixes () {
}); });
}; };
return jsonData => {
// Ensure items are always wrapped in an array // Ensure items are always wrapped in an array
if (jsonData.artist && !Array.isArray(jsonData.artist)) { if (jsonData.artist && !Array.isArray(jsonData.artist)) {
jsonData.artist = [jsonData.artist]; jsonData.artist = [jsonData.artist];
@ -133,41 +122,21 @@ function _uglyFixes () {
jsonData.song = [jsonData.song]; jsonData.song = [jsonData.song];
} }
// TODO
// Keep track of artists count
if (jsonData.artists) {
_uglyFixes.artistsCount = parseInt(jsonData.artists);
}
// Keep track of albums count
if (jsonData.albums) {
_uglyFixes.albumsCount = parseInt(jsonData.albums);
}
// Keep track of songs count
if (jsonData.songs) {
_uglyFixes.songsCount = parseInt(jsonData.songs);
}
// Fix artists // Fix artists
if (jsonData.artist) { if (jsonData.artist) {
jsonData.artist = _uglyFixesArtists(jsonData.artist); jsonData.artist = _uglyFixesArtists(jsonData.artist);
// Store the total number of items
jsonData.artists = _uglyFixes.artistsCount;
} }
// Fix albums // Fix albums
if (jsonData.album) { if (jsonData.album) {
// Fix albums // Fix albums
jsonData.album = _uglyFixesAlbums(jsonData.album); jsonData.album = _uglyFixesAlbums(jsonData.album);
// Store the total number of items
jsonData.albums = _uglyFixes.albumsCount;
} }
// Fix songs // Fix songs
if (jsonData.song) { if (jsonData.song) {
// Fix songs // Fix songs
jsonData.song = _uglyFixesSongs(jsonData.song); jsonData.song = _uglyFixesSongs(jsonData.song);
// Store the total number of items
jsonData.songs = _uglyFixes.songsCount;
} }
// TODO // TODO
@ -178,7 +147,6 @@ function _uglyFixes () {
} }
return jsonData; return jsonData;
};
} }
function _normalizeResponse(jsonData) { function _normalizeResponse(jsonData) {
@ -207,7 +175,7 @@ function doAPICall (endpoint, action, auth, username, extraParams) {
.then(_parseToJSON) .then(_parseToJSON)
.then(_checkAPIErrors) .then(_checkAPIErrors)
.then(jsonData => humps.camelizeKeys(jsonData)) // Camelize .then(jsonData => humps.camelizeKeys(jsonData)) // Camelize
.then(_uglyFixes()) .then(_uglyFixes)
.then(_normalizeResponse); .then(_normalizeResponse);
} }

View File

@ -6,6 +6,7 @@ import App from "./containers/App";
import SimpleLayout from "./components/layouts/Simple"; import SimpleLayout from "./components/layouts/Simple";
import SidebarLayout from "./components/layouts/Sidebar"; import SidebarLayout from "./components/layouts/Sidebar";
import BrowsePage from "./views/BrowsePage"; import BrowsePage from "./views/BrowsePage";
import DiscoverPage from "./views/DiscoverPage";
import HomePage from "./views/HomePage"; import HomePage from "./views/HomePage";
import LoginPage from "./views/LoginPage"; import LoginPage from "./views/LoginPage";
import LogoutPage from "./views/LogoutPage"; import LogoutPage from "./views/LogoutPage";
@ -23,9 +24,7 @@ export default (
<Route component={SidebarLayout}> <Route component={SidebarLayout}>
<Route path="logout" component={LogoutPage} /> <Route path="logout" component={LogoutPage} />
<Route component={RequireAuthentication}> <Route component={RequireAuthentication}>
{/*
<Route path="discover" component={DiscoverPage} /> <Route path="discover" component={DiscoverPage} />
*/}
<Route path="browse" component={BrowsePage} /> <Route path="browse" component={BrowsePage} />
<Route path="artists" component={ArtistsPage} /> <Route path="artists" component={ArtistsPage} />
<Route path="artist/:id" component={ArtistPage} /> <Route path="artist/:id" component={ArtistPage} />

View File

@ -9,6 +9,14 @@ $rowMarginBottom: 10px;
composes: art from "./elements/Grid.scss"; composes: art from "./elements/Grid.scss";
} }
.art:hover {
cursor: initial;
}
.play {
composes: play from "./Songs.scss";
}
@media (max-width: 767px) { @media (max-width: 767px) {
.nameRow h2 { .nameRow h2 {
margin-top: 0; margin-top: 0;

37
app/styles/Discover.scss Normal file
View File

@ -0,0 +1,37 @@
.noMarginTop {
margin-top: 0;
}
.h2Title {
border: none;
font-size: $font-size-h2;
padding: 0 25px 0 0;
line-height: 1em;
position: relative;
}
.h2Title:active,
.h2Title:hover,
.h2Title:focus {
background-color: transparent;
}
.caret {
position: absolute;
bottom: -4px;
right: 0;
}
.h2Title .caret {
margin-left: 3px;
}
.dashedUnderline {
border-bottom: 1px dotted black;
}
.dropdown-menu {
left: 0;
right: 0;
min-width: 0;
}

View File

@ -1,3 +1,11 @@
.play {
background-color: transparent;
border: none;
text-align: center;
vertical-align: middle;
line-height: 1em;
}
@media (max-width: 767px) { @media (max-width: 767px) {
.songs { .songs {
> thead, > thead,

View File

@ -35,11 +35,13 @@ $condensedNavPadding: 5px;
.link:hover { .link:hover {
color: $foreground; color: $foreground;
background-color: $hoverBackground !important; background-color: $hoverBackground !important;
text-decoration: none;
} }
.link:focus { .link:focus {
color: $foreground; color: $foreground;
background-color: transparent !important; background-color: transparent !important;
text-decoration: none;
} }
.active { .active {
@ -97,7 +99,7 @@ button.toggle {
*/ */
.main-panel { .main-panel {
padding: $mainPadding; padding: $mainPadding;
z-index: -10; z-index: -10; /** TODO: z-index issue */
} }
/* /*

View File

@ -8,7 +8,7 @@
$.fn.shake = function(intShakes, intDistance, intDuration) { $.fn.shake = function(intShakes, intDistance, intDuration) {
this.each(function() { this.each(function() {
$(this).css("position","relative"); $(this).css("position","relative");
for (var x=1; x<=intShakes; x++) { for (let x=1; x<=intShakes; x++) {
$(this).animate({left:(intDistance*-1)}, (((intDuration/intShakes)/4))) $(this).animate({left:(intDistance*-1)}, (((intDuration/intShakes)/4)))
.animate({left:intDistance}, ((intDuration/intShakes)/2)) .animate({left:intDistance}, ((intDuration/intShakes)/2))
.animate({left:0}, (((intDuration/intShakes)/4))); .animate({left:0}, (((intDuration/intShakes)/4)));

View File

@ -6,6 +6,8 @@ import * as actionCreators from "../actions";
import Album from "../components/Album"; import Album from "../components/Album";
// TODO: AlbumPage should be scrolled ArtistPage
export class AlbumPage extends Component { export class AlbumPage extends Component {
componentWillMount () { componentWillMount () {
// Load the data // Load the data

View File

@ -57,9 +57,10 @@ ArtistsPageIntl.propTypes = {
const mapStateToProps = (state) => ({ const mapStateToProps = (state) => ({
isFetching: state.pagination.artists.isFetching, isFetching: state.pagination.artists.isFetching,
error: state.pagination.artists.error,
artistsList: state.pagination.artists.items, artistsList: state.pagination.artists.items,
currentPage: state.pagination.artists.currentPage, currentPage: state.pagination.artists.currentPage,
nPages: state.pagination.artists.nPages nPages: state.pagination.artists.nPages,
}); });
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({

View File

@ -0,0 +1,11 @@
import React, { Component } from "react";
import Discover from "../components/Discover";
export default class DiscoverPage extends Component {
render () {
return (
<Discover />
);
}
}

View File

@ -57,6 +57,7 @@ SongsPageIntl.propTypes = {
const mapStateToProps = (state) => ({ const mapStateToProps = (state) => ({
isFetching: state.pagination.songs.isFetching, isFetching: state.pagination.songs.isFetching,
error: state.pagination.songs.error,
songsList: state.pagination.songs.items, songsList: state.pagination.songs.items,
currentPage: state.pagination.songs.currentPage, currentPage: state.pagination.songs.currentPage,
nPages: state.pagination.songs.nPages nPages: state.pagination.songs.nPages