Move to CSS modules
Also includes misc fixes * Use CSS modules for all the CSS. * Fix a bug in the filterbar which was not filtering anything. * Fix a l10n issue in songs view. * Update hook to clean build repo before running, preventing to push dev built code. * Update webpack build code.
This commit is contained in:
parent
921028c073
commit
2d9747482b
116
.bootstraprc
Normal file
116
.bootstraprc
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
---
|
||||||
|
# Output debugging info
|
||||||
|
loglevel: disabled
|
||||||
|
|
||||||
|
# Major version of Bootstrap: 3 or 4
|
||||||
|
bootstrapVersion: 3
|
||||||
|
|
||||||
|
# If Bootstrap version 3 is used - turn on/off custom icon font path
|
||||||
|
useCustomIconFontPath: false
|
||||||
|
|
||||||
|
# Webpack loaders, order matters
|
||||||
|
styleLoaders:
|
||||||
|
- style
|
||||||
|
- css
|
||||||
|
- sass
|
||||||
|
|
||||||
|
# Extract styles to stand-alone css file
|
||||||
|
# Different settings for different environments can be used,
|
||||||
|
# It depends on value of NODE_ENV environment variable
|
||||||
|
# This param can also be set in webpack config:
|
||||||
|
# entry: 'bootstrap-loader/extractStyles'
|
||||||
|
extractStyles: true
|
||||||
|
# env:
|
||||||
|
# development:
|
||||||
|
# extractStyles: false
|
||||||
|
# production:
|
||||||
|
# extractStyles: true
|
||||||
|
|
||||||
|
|
||||||
|
# Customize Bootstrap variables that get imported before the original Bootstrap variables.
|
||||||
|
# Thus, derived Bootstrap variables can depend on values from here.
|
||||||
|
# See the Bootstrap _variables.scss file for examples of derived Bootstrap variables.
|
||||||
|
#
|
||||||
|
# preBootstrapCustomizations: ./path/to/bootstrap/pre-customizations.scss
|
||||||
|
|
||||||
|
|
||||||
|
# This gets loaded after bootstrap/variables is loaded
|
||||||
|
# Thus, you may customize Bootstrap variables
|
||||||
|
# based on the values established in the Bootstrap _variables.scss file
|
||||||
|
#
|
||||||
|
# bootstrapCustomizations: ./path/to/bootstrap/customizations.scss
|
||||||
|
|
||||||
|
|
||||||
|
# Import your custom styles here
|
||||||
|
# Usually this endpoint-file contains list of @imports of your application styles
|
||||||
|
#
|
||||||
|
# appStyles: ./path/to/your/app/styles/endpoint.scss
|
||||||
|
|
||||||
|
|
||||||
|
### Bootstrap styles
|
||||||
|
styles:
|
||||||
|
|
||||||
|
# Mixins
|
||||||
|
mixins: true
|
||||||
|
|
||||||
|
# Reset and dependencies
|
||||||
|
normalize: true
|
||||||
|
print: true
|
||||||
|
glyphicons: true
|
||||||
|
|
||||||
|
# Core CSS
|
||||||
|
scaffolding: true
|
||||||
|
type: true
|
||||||
|
code: true
|
||||||
|
grid: true
|
||||||
|
tables: true
|
||||||
|
forms: true
|
||||||
|
buttons: true
|
||||||
|
|
||||||
|
# Components
|
||||||
|
component-animations: true
|
||||||
|
dropdowns: true
|
||||||
|
button-groups: true
|
||||||
|
input-groups: true
|
||||||
|
navs: true
|
||||||
|
navbar: true
|
||||||
|
breadcrumbs: true
|
||||||
|
pagination: true
|
||||||
|
pager: true
|
||||||
|
labels: true
|
||||||
|
badges: true
|
||||||
|
jumbotron: true
|
||||||
|
thumbnails: true
|
||||||
|
alerts: true
|
||||||
|
progress-bars: true
|
||||||
|
media: true
|
||||||
|
list-group: true
|
||||||
|
panels: true
|
||||||
|
wells: true
|
||||||
|
responsive-embed: true
|
||||||
|
close: true
|
||||||
|
|
||||||
|
# Components w/ JavaScript
|
||||||
|
modals: true
|
||||||
|
tooltip: true
|
||||||
|
popovers: true
|
||||||
|
carousel: true
|
||||||
|
|
||||||
|
# Utility classes
|
||||||
|
utilities: true
|
||||||
|
responsive-utilities: true
|
||||||
|
|
||||||
|
### Bootstrap scripts
|
||||||
|
scripts:
|
||||||
|
transition: true
|
||||||
|
alert: true
|
||||||
|
button: true
|
||||||
|
carousel: true
|
||||||
|
collapse: true
|
||||||
|
dropdown: true
|
||||||
|
modal: true
|
||||||
|
tooltip: true
|
||||||
|
popover: true
|
||||||
|
scrollspy: true
|
||||||
|
tab: true
|
||||||
|
affix: true
|
@ -21,13 +21,13 @@ A few `npm` scripts are provided:
|
|||||||
|
|
||||||
Translations are handled by [react-intl](https://github.com/yahoo/react-intl/).
|
Translations are handled by [react-intl](https://github.com/yahoo/react-intl/).
|
||||||
|
|
||||||
`npm run extractTranslations` output a file containing all the english
|
`npm run --silent extractTranslations` output a file containing all the english
|
||||||
translations, in the expected form. It is a mapping of ids and strings to
|
translations, in the expected form. It is a mapping of ids and strings to
|
||||||
translate, with an extra description provided as a comment at the end of the
|
translate, with an extra description provided as a comment at the end of the
|
||||||
line, for some translation context.
|
line, for some translation context.
|
||||||
|
|
||||||
Typically, if you want to translate to another `$LOCALE` (say `fr-FR`), create
|
Typically, if you want to translate to another `$LOCALE` (say `fr-FR`), create
|
||||||
a folder `./app/locales/$LOCALE`, put inside the generated file from `npm run
|
a folder `./app/locales/$LOCALE`, put inside the generated file from `npm run
|
||||||
extractTranslations`, called `index.js`. Copy the lines in
|
--silent extractTranslations`, called `index.js`. Copy the lines in
|
||||||
`./app/locales/index.js` to include your new translation and translate all the
|
`./app/locales/index.js` to include your new translation and translate all the
|
||||||
strings in the `./app/locales/$LOCALE/index.js` file you have just created.
|
strings in the `./app/locales/$LOCALE/index.js` file you have just created.
|
||||||
|
7
TODO
7
TODO
@ -5,12 +5,8 @@
|
|||||||
8. Search
|
8. Search
|
||||||
9. Discover
|
9. Discover
|
||||||
|
|
||||||
|
|
||||||
# CSS
|
# CSS
|
||||||
* Sidebar responsiveness
|
* Focus stays on navbar
|
||||||
* Move CSS in modules
|
|
||||||
=> https://github.com/gajus/react-css-modules
|
|
||||||
|
|
||||||
|
|
||||||
# API middleware
|
# API middleware
|
||||||
* https://github.com/reactjs/redux/issues/1824#issuecomment-228609501
|
* https://github.com/reactjs/redux/issues/1824#issuecomment-228609501
|
||||||
@ -18,6 +14,7 @@
|
|||||||
* https://github.com/reactjs/redux/issues/644
|
* https://github.com/reactjs/redux/issues/644
|
||||||
* https://github.com/peterpme/redux-crud-api-middleware/blob/master/README.md
|
* https://github.com/peterpme/redux-crud-api-middleware/blob/master/README.md
|
||||||
* https://github.com/madou/armory-front/tree/master/src/app/reducers
|
* https://github.com/madou/armory-front/tree/master/src/app/reducers
|
||||||
|
* https://github.com/erikras/multireducer
|
||||||
* Immutable.js (?) + get rid of lodash
|
* Immutable.js (?) + get rid of lodash
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
import React, { Component, PropTypes } from "react";
|
import React, { Component, PropTypes } from "react";
|
||||||
|
import CSSModules from "react-css-modules";
|
||||||
|
|
||||||
import { formatLength } from "../utils";
|
import { formatLength } from "../utils";
|
||||||
|
|
||||||
|
import css from "../styles/Album.scss";
|
||||||
|
|
||||||
export class AlbumTrackRow extends Component {
|
export class AlbumTrackRow extends Component {
|
||||||
render () {
|
render () {
|
||||||
const length = formatLength(this.props.track.length);
|
const length = formatLength(this.props.track.length);
|
||||||
@ -40,28 +43,34 @@ AlbumTracksTable.propTypes = {
|
|||||||
tracks: PropTypes.array.isRequired
|
tracks: PropTypes.array.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export class AlbumRow extends Component {
|
class AlbumRowCSS extends Component {
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div className="row albumRow">
|
<div className="row" styleName="row">
|
||||||
<div className="col-sm-offset-2 col-xs-10 albumRowName">
|
<div className="col-sm-offset-2 col-xs-10" styleName="nameRow">
|
||||||
<h2>{this.props.album.name}</h2>
|
<h2>{this.props.album.name}</h2>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-xs-2 albumRowArt">
|
<div className="col-xs-2" styleName="artRow">
|
||||||
<p className="text-center"><img src={this.props.album.art} width="200" height="200" className="img-responsive img-circle 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-sm-10 table-responsive">
|
||||||
<AlbumTracksTable tracks={this.props.album.tracks} />
|
{
|
||||||
|
Array.isArray(this.props.album.tracks) ?
|
||||||
|
<AlbumTracksTable tracks={this.props.album.tracks} /> :
|
||||||
|
null
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AlbumRow.propTypes = {
|
AlbumRowCSS.propTypes = {
|
||||||
album: PropTypes.object.isRequired
|
album: PropTypes.object.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export let AlbumRow = CSSModules(AlbumRowCSS, css);
|
||||||
|
|
||||||
export default class Album extends Component {
|
export default class Album extends Component {
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
import React, { Component, PropTypes } from "react";
|
import React, { Component, PropTypes } from "react";
|
||||||
|
import CSSModules from "react-css-modules";
|
||||||
|
|
||||||
import { AlbumRow } from "./Album";
|
import { AlbumRow } from "./Album";
|
||||||
|
|
||||||
export default class Artist extends Component {
|
import css from "../styles/Artist.scss";
|
||||||
|
|
||||||
|
class ArtistCSS extends Component {
|
||||||
render () {
|
render () {
|
||||||
var albumsRows = [];
|
var albumsRows = [];
|
||||||
if (Array.isArray(this.props.artist.albums)) {
|
if (Array.isArray(this.props.artist.albums)) {
|
||||||
@ -12,7 +15,7 @@ export default class Artist extends Component {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="row artistNameRow">
|
<div className="row" styleName="name">
|
||||||
<div className="col-sm-12">
|
<div className="col-sm-12">
|
||||||
<h1>{this.props.artist.name}</h1>
|
<h1>{this.props.artist.name}</h1>
|
||||||
<hr/>
|
<hr/>
|
||||||
@ -23,7 +26,7 @@ export default class Artist extends Component {
|
|||||||
<p>{this.props.artist.summary}</p>
|
<p>{this.props.artist.summary}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-sm-3 text-center">
|
<div className="col-sm-3 text-center">
|
||||||
<p><img src={this.props.artist.art} width="200" height="200" className="img-responsive img-circle art" alt={this.props.artist.name}/></p>
|
<p><img src={this.props.artist.art} width="200" height="200" className="img-responsive img-circle" styleName="art" alt={this.props.artist.name}/></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{ albumsRows }
|
{ albumsRows }
|
||||||
@ -32,6 +35,8 @@ export default class Artist extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Artist.propTypes = {
|
ArtistCSS.propTypes = {
|
||||||
artist: PropTypes.object.isRequired
|
artist: PropTypes.object.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default CSSModules(ArtistCSS, css);
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
import React, { Component, PropTypes } from "react";
|
import React, { Component, PropTypes } from "react";
|
||||||
|
import CSSModules from "react-css-modules";
|
||||||
import { defineMessages, injectIntl, intlShape, FormattedMessage } from "react-intl";
|
import { defineMessages, injectIntl, intlShape, FormattedMessage } from "react-intl";
|
||||||
|
|
||||||
import { messagesMap } from "../utils";
|
import { messagesMap } from "../utils";
|
||||||
import messages from "../locales/messagesDescriptors/Login";
|
import messages from "../locales/messagesDescriptors/Login";
|
||||||
|
|
||||||
|
import css from "../styles/Login.scss";
|
||||||
|
|
||||||
const loginMessages = defineMessages(messagesMap(messages));
|
const loginMessages = defineMessages(messagesMap(messages));
|
||||||
|
|
||||||
class LoginFormIntl extends Component {
|
class LoginFormCSSIntl extends Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
@ -61,8 +64,8 @@ class LoginFormIntl extends Component {
|
|||||||
{
|
{
|
||||||
this.props.error ?
|
this.props.error ?
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="alert alert-danger">
|
<div className="alert alert-danger" id="loginFormError">
|
||||||
<p id="loginFormError">
|
<p>
|
||||||
<span className="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> { this.props.error }
|
<span className="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> { this.props.error }
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@ -105,7 +108,7 @@ class LoginFormIntl extends Component {
|
|||||||
<FormattedMessage {...loginMessages["app.login.rememberMe"]} />
|
<FormattedMessage {...loginMessages["app.login.rememberMe"]} />
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-sm-6 col-sm-12 submit text-right">
|
<div className="col-sm-6 col-xs-12 text-right" styleName="submit">
|
||||||
<input type="submit" className="btn btn-default" aria-label={formatMessage(loginMessages["app.login.signIn"])} defaultValue={formatMessage(loginMessages["app.login.signIn"])} disabled={this.props.isAuthenticating} />
|
<input type="submit" className="btn btn-default" aria-label={formatMessage(loginMessages["app.login.signIn"])} defaultValue={formatMessage(loginMessages["app.login.signIn"])} disabled={this.props.isAuthenticating} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -119,7 +122,7 @@ class LoginFormIntl extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LoginFormIntl.propTypes = {
|
LoginFormCSSIntl.propTypes = {
|
||||||
username: PropTypes.string,
|
username: PropTypes.string,
|
||||||
endpoint: PropTypes.string,
|
endpoint: PropTypes.string,
|
||||||
rememberMe: PropTypes.bool,
|
rememberMe: PropTypes.bool,
|
||||||
@ -130,10 +133,10 @@ LoginFormIntl.propTypes = {
|
|||||||
intl: intlShape.isRequired,
|
intl: intlShape.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export let LoginForm = injectIntl(LoginFormIntl);
|
export let LoginForm = injectIntl(CSSModules(LoginFormCSSIntl, css));
|
||||||
|
|
||||||
|
|
||||||
export default class Login extends Component {
|
class Login extends Component {
|
||||||
render () {
|
render () {
|
||||||
const greeting = (
|
const greeting = (
|
||||||
<p>
|
<p>
|
||||||
@ -141,8 +144,8 @@ export default class Login extends Component {
|
|||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<div className="login text-center container-fluid">
|
<div className="text-center container-fluid">
|
||||||
<h1><img src="./app/assets/img/ampache-blue.png" alt="A"/>mpache</h1>
|
<h1><img styleName="titleImage" src="./app/assets/img/ampache-blue.png" alt="A"/>mpache</h1>
|
||||||
<hr/>
|
<hr/>
|
||||||
{(!this.props.error && !this.props.info) ? greeting : null}
|
{(!this.props.error && !this.props.info) ? greeting : null}
|
||||||
<div className="col-sm-9 col-sm-offset-2 col-md-6 col-md-offset-3">
|
<div className="col-sm-9 col-sm-offset-2 col-md-6 col-md-offset-3">
|
||||||
@ -162,3 +165,5 @@ Login.propTypes = {
|
|||||||
error: PropTypes.string,
|
error: PropTypes.string,
|
||||||
info: PropTypes.string
|
info: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default CSSModules(Login, css);
|
||||||
|
@ -65,13 +65,13 @@ export class SongsTable extends Component {
|
|||||||
<FormattedMessage {...songsMessages["app.songs.title"]} />
|
<FormattedMessage {...songsMessages["app.songs.title"]} />
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<FormattedMessage {...songsMessages["app.common.artist"]} />
|
<FormattedMessage {...songsMessages["app.common.artist"]} values={{itemCount: 1}} />
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<FormattedMessage {...songsMessages["app.common.album"]} />
|
<FormattedMessage {...songsMessages["app.common.album"]} values={{itemCount: 1}} />
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<FormattedMessage {...songsMessages["app.common.genre"]} />
|
<FormattedMessage {...songsMessages["app.songs.genre"]} />
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<FormattedMessage {...songsMessages["app.songs.length"]} />
|
<FormattedMessage {...songsMessages["app.songs.length"]} />
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
import React, { Component, PropTypes } from "react";
|
import React, { Component, PropTypes } from "react";
|
||||||
|
import CSSModules from "react-css-modules";
|
||||||
import { defineMessages, injectIntl, intlShape, FormattedMessage } from "react-intl";
|
import { defineMessages, injectIntl, intlShape, FormattedMessage } from "react-intl";
|
||||||
|
|
||||||
import { messagesMap } from "../../utils";
|
import { messagesMap } from "../../utils";
|
||||||
import messages from "../../locales/messagesDescriptors/elements/FilterBar";
|
import messages from "../../locales/messagesDescriptors/elements/FilterBar";
|
||||||
|
|
||||||
|
import css from "../../styles/elements/FilterBar.scss";
|
||||||
|
|
||||||
const filterMessages = defineMessages(messagesMap(messages));
|
const filterMessages = defineMessages(messagesMap(messages));
|
||||||
|
|
||||||
class FilterBarIntl extends Component {
|
class FilterBarCSSIntl extends Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.handleChange = this.handleChange.bind(this);
|
this.handleChange = this.handleChange.bind(this);
|
||||||
@ -21,14 +24,14 @@ class FilterBarIntl extends Component {
|
|||||||
render () {
|
render () {
|
||||||
const {formatMessage} = this.props.intl;
|
const {formatMessage} = this.props.intl;
|
||||||
return (
|
return (
|
||||||
<div className="filter">
|
<div styleName="filter">
|
||||||
<p className="col-xs-12 col-sm-6 col-md-4 col-md-offset-1 filter-legend" id="filterInputDescription">
|
<p className="col-xs-12 col-sm-6 col-md-4 col-md-offset-1" styleName="legend" id="filterInputDescription">
|
||||||
<FormattedMessage {...filterMessages["app.filter.whatAreWeListeningToToday"]} />
|
<FormattedMessage {...filterMessages["app.filter.whatAreWeListeningToToday"]} />
|
||||||
</p>
|
</p>
|
||||||
<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">
|
<form className="form-inline" onSubmit={this.handleChange} aria-describedby="filterInputDescription">
|
||||||
<div className="form-group">
|
<div className="form-group" styleName="form-group">
|
||||||
<input type="text" className="form-control filter-input" placeholder={formatMessage(filterMessages["app.filter.filter"])} aria-label={formatMessage(filterMessages["app.filter.filter"])} value={this.props.filterText} onChange={this.handleChange} ref="filterTextInput" />
|
<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" />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@ -37,11 +40,10 @@ class FilterBarIntl extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FilterBarIntl.propTypes = {
|
FilterBarCSSIntl.propTypes = {
|
||||||
onUserInput: PropTypes.func,
|
onUserInput: PropTypes.func,
|
||||||
filterText: PropTypes.string,
|
filterText: PropTypes.string,
|
||||||
intl: intlShape.isRequired
|
intl: intlShape.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export let FilterBar = injectIntl(FilterBarIntl);
|
export default injectIntl(CSSModules(FilterBarCSSIntl, css));
|
||||||
export default FilterBar;
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React, { Component, PropTypes } from "react";
|
import React, { Component, PropTypes } from "react";
|
||||||
import { Link} from "react-router";
|
import { Link} from "react-router";
|
||||||
|
import CSSModules from "react-css-modules";
|
||||||
import imagesLoaded from "imagesloaded";
|
import imagesLoaded from "imagesloaded";
|
||||||
import Isotope from "isotope-layout";
|
import Isotope from "isotope-layout";
|
||||||
import Fuse from "fuse.js";
|
import Fuse from "fuse.js";
|
||||||
@ -8,7 +9,9 @@ import _ from "lodash";
|
|||||||
import FilterBar from "./FilterBar";
|
import FilterBar from "./FilterBar";
|
||||||
import Pagination from "./Pagination";
|
import Pagination from "./Pagination";
|
||||||
|
|
||||||
export class GridItem extends Component {
|
import css from "../../styles/elements/Grid.scss";
|
||||||
|
|
||||||
|
class GridItemCSS extends Component {
|
||||||
render () {
|
render () {
|
||||||
var nSubItems = this.props.item[this.props.subItemsType];
|
var nSubItems = this.props.item[this.props.subItemsType];
|
||||||
if (Array.isArray(nSubItems)) {
|
if (Array.isArray(nSubItems)) {
|
||||||
@ -27,10 +30,10 @@ export class GridItem extends Component {
|
|||||||
// TODO: i18n
|
// TODO: i18n
|
||||||
const title = "Go to " + this.props.itemsType.rstrip("s") + " page";
|
const title = "Go to " + this.props.itemsType.rstrip("s") + " page";
|
||||||
return (
|
return (
|
||||||
<div className="grid-item col-xs-6 col-sm-3 placeholders" id={id}>
|
<div className="grid-item col-xs-6 col-sm-3" styleName="placeholders" id={id}>
|
||||||
<div className="grid-item-content placeholder text-center">
|
<div className="grid-item-content text-center">
|
||||||
<Link title={title} to={to}><img src={this.props.item.art} width="200" height="200" className="img-responsive img-circle art" alt={this.props.item.name}/></Link>
|
<Link title={title} to={to}><img src={this.props.item.art} width="200" height="200" className="img-responsive img-circle art" styleName="art" alt={this.props.item.name}/></Link>
|
||||||
<h4 className="name">{this.props.item.name}</h4>
|
<h4 className="name" styleName="name">{this.props.item.name}</h4>
|
||||||
<span className="sub-items text-muted"><span className="n-sub-items">{nSubItems}</span> <span className="sub-items-type">{subItemsLabel}</span></span>
|
<span className="sub-items text-muted"><span className="n-sub-items">{nSubItems}</span> <span className="sub-items-type">{subItemsLabel}</span></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -38,12 +41,14 @@ export class GridItem extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GridItem.propTypes = {
|
GridItemCSS.propTypes = {
|
||||||
item: PropTypes.object.isRequired,
|
item: PropTypes.object.isRequired,
|
||||||
itemsType: PropTypes.string.isRequired,
|
itemsType: PropTypes.string.isRequired,
|
||||||
subItemsType: PropTypes.string.isRequired
|
subItemsType: PropTypes.string.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export let GridItem = CSSModules(GridItemCSS, css);
|
||||||
|
|
||||||
|
|
||||||
const ISOTOPE_OPTIONS = { /** Default options for Isotope grid layout. */
|
const ISOTOPE_OPTIONS = { /** Default options for Isotope grid layout. */
|
||||||
getSortData: {
|
getSortData: {
|
||||||
@ -93,9 +98,9 @@ export class Grid extends Component {
|
|||||||
|
|
||||||
// Apply filter on grid
|
// Apply filter on grid
|
||||||
this.iso.arrange({
|
this.iso.arrange({
|
||||||
filter: function () {
|
filter: function (item) {
|
||||||
var name = $(this).find(".name").text();
|
var name = $(item).find(".name").text();
|
||||||
return result.find(function (item) { return item.item.name == name; });
|
return result.find(function (i) { return i.item.name == name; });
|
||||||
},
|
},
|
||||||
transitionDuration: "0.4s",
|
transitionDuration: "0.4s",
|
||||||
getSortData: {
|
getSortData: {
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
import React, { Component, PropTypes } from "react";
|
import React, { Component, PropTypes } from "react";
|
||||||
import { Link, withRouter } from "react-router";
|
import { Link, withRouter } from "react-router";
|
||||||
|
import CSSModules from "react-css-modules";
|
||||||
import { defineMessages, injectIntl, intlShape, FormattedMessage, FormattedHTMLMessage } from "react-intl";
|
import { defineMessages, injectIntl, intlShape, FormattedMessage, FormattedHTMLMessage } from "react-intl";
|
||||||
|
|
||||||
import { messagesMap } from "../../utils";
|
import { messagesMap } from "../../utils";
|
||||||
import commonMessages from "../../locales/messagesDescriptors/common";
|
import commonMessages from "../../locales/messagesDescriptors/common";
|
||||||
import messages from "../../locales/messagesDescriptors/elements/Pagination";
|
import messages from "../../locales/messagesDescriptors/elements/Pagination";
|
||||||
|
|
||||||
|
import css from "../../styles/elements/Pagination.scss";
|
||||||
|
|
||||||
const paginationMessages = defineMessages(messagesMap(Array.concat([], commonMessages, messages)));
|
const paginationMessages = defineMessages(messagesMap(Array.concat([], commonMessages, messages)));
|
||||||
|
|
||||||
export class PaginationIntl extends Component {
|
class PaginationCSSIntl extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.buildLinkTo.bind(this);
|
this.buildLinkTo.bind(this);
|
||||||
@ -134,8 +137,8 @@ export class PaginationIntl extends Component {
|
|||||||
if (pagesButton.length > 1) {
|
if (pagesButton.length > 1) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<nav className="pagination-nav" aria-label={formatMessage(paginationMessages["app.pagination.pageNavigation"])}>
|
<nav className="pagination-nav" styleName="nav" aria-label={formatMessage(paginationMessages["app.pagination.pageNavigation"])}>
|
||||||
<ul className="pagination">
|
<ul className="pagination" styleName="pointer">
|
||||||
{ pagesButton }
|
{ pagesButton }
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
@ -171,12 +174,11 @@ export class PaginationIntl extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PaginationIntl.propTypes = {
|
PaginationCSSIntl.propTypes = {
|
||||||
currentPage: PropTypes.number.isRequired,
|
currentPage: PropTypes.number.isRequired,
|
||||||
location: PropTypes.object.isRequired,
|
location: PropTypes.object.isRequired,
|
||||||
nPages: PropTypes.number.isRequired,
|
nPages: PropTypes.number.isRequired,
|
||||||
intl: intlShape.isRequired,
|
intl: intlShape.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export let Pagination = withRouter(injectIntl(PaginationIntl));
|
export default withRouter(injectIntl(CSSModules(PaginationCSSIntl, css)));
|
||||||
export default Pagination;
|
|
||||||
|
@ -1,39 +1,42 @@
|
|||||||
import React, { Component, PropTypes } from "react";
|
import React, { Component, PropTypes } from "react";
|
||||||
import { IndexLink, Link} from "react-router";
|
import { IndexLink, Link} from "react-router";
|
||||||
|
import CSSModules from "react-css-modules";
|
||||||
import { defineMessages, injectIntl, intlShape, FormattedMessage } from "react-intl";
|
import { defineMessages, injectIntl, intlShape, FormattedMessage } from "react-intl";
|
||||||
|
|
||||||
import { messagesMap } from "../../utils";
|
import { messagesMap } from "../../utils";
|
||||||
import commonMessages from "../../locales/messagesDescriptors/common";
|
import commonMessages from "../../locales/messagesDescriptors/common";
|
||||||
import messages from "../../locales/messagesDescriptors/layouts/Sidebar";
|
import messages from "../../locales/messagesDescriptors/layouts/Sidebar";
|
||||||
|
|
||||||
|
import css from "../../styles/layouts/Sidebar.scss";
|
||||||
|
|
||||||
const sidebarLayoutMessages = defineMessages(messagesMap(Array.concat([], commonMessages, messages)));
|
const sidebarLayoutMessages = defineMessages(messagesMap(Array.concat([], commonMessages, messages)));
|
||||||
|
|
||||||
export default class SidebarLayoutIntl extends Component {
|
class SidebarLayoutIntl extends Component {
|
||||||
render () {
|
render () {
|
||||||
const { formatMessage } = this.props.intl;
|
const { formatMessage } = this.props.intl;
|
||||||
const isActive = {
|
const isActive = {
|
||||||
discover: (this.props.location.pathname == "/discover") ? "active" : "",
|
discover: (this.props.location.pathname == "/discover") ? "active" : "link",
|
||||||
browse: (this.props.location.pathname == "/browse") ? "active" : "",
|
browse: (this.props.location.pathname == "/browse") ? "active" : "link",
|
||||||
artists: (this.props.location.pathname == "/artists") ? "active" : "",
|
artists: (this.props.location.pathname == "/artists") ? "active" : "link",
|
||||||
albums: (this.props.location.pathname == "/albums") ? "active" : "",
|
albums: (this.props.location.pathname == "/albums") ? "active" : "link",
|
||||||
songs: (this.props.location.pathname == "/songs") ? "active" : "",
|
songs: (this.props.location.pathname == "/songs") ? "active" : "link",
|
||||||
search: (this.props.location.pathname == "/search") ? "active" : ""
|
search: (this.props.location.pathname == "/search") ? "active" : "link"
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="col-sm-1 col-md-2 sidebar hidden-xs">
|
<div className="col-sm-1 col-md-2 hidden-xs" styleName="sidebar">
|
||||||
<h1 className="text-center">
|
<h1 className="text-center" styleName="title">
|
||||||
<IndexLink to="/">
|
<IndexLink to="/" styleName="link">
|
||||||
<img alt="A" src="./app/assets/img/ampache-blue.png"/>
|
<img alt="A" src="./app/assets/img/ampache-blue.png" styleName="imgTitle" />
|
||||||
<span className="hidden-sm">mpache</span>
|
<span className="hidden-sm">mpache</span>
|
||||||
</IndexLink>
|
</IndexLink>
|
||||||
</h1>
|
</h1>
|
||||||
<nav aria-label={formatMessage(sidebarLayoutMessages["app.sidebarLayout.mainNavigationMenu"])}>
|
<nav aria-label={formatMessage(sidebarLayoutMessages["app.sidebarLayout.mainNavigationMenu"])}>
|
||||||
<div className="navbar text-center icon-navbar">
|
<div className="navbar text-center" styleName="icon-navbar">
|
||||||
<div className="container-fluid">
|
<div className="container-fluid">
|
||||||
<ul className="nav navbar-nav icon-navbar-nav">
|
<ul className="nav navbar-nav" styleName="nav">
|
||||||
<li>
|
<li>
|
||||||
<Link to="/" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.home"])}>
|
<Link to="/" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.home"])} styleName="link">
|
||||||
<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"]} />
|
||||||
@ -41,7 +44,7 @@ export default class SidebarLayoutIntl extends Component {
|
|||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<Link to="/settings" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.settings"])}>
|
<Link to="/settings" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.settings"])} styleName="link">
|
||||||
<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"]} />
|
||||||
@ -49,7 +52,7 @@ export default class SidebarLayoutIntl extends Component {
|
|||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<Link to="/logout" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.logout"])}>
|
<Link to="/logout" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.logout"])} styleName="link">
|
||||||
<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"]} />
|
||||||
@ -59,9 +62,9 @@ export default class SidebarLayoutIntl extends Component {
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul className="nav nav-sidebar">
|
<ul className="nav" styleName="nav">
|
||||||
<li>
|
<li>
|
||||||
<Link to="/discover" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.discover"])} className={isActive.discover}>
|
<Link to="/discover" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.discover"])} styleName={isActive.discover}>
|
||||||
<span className="glyphicon glyphicon-globe" aria-hidden="true"></span>
|
<span className="glyphicon glyphicon-globe" aria-hidden="true"></span>
|
||||||
<span className="hidden-sm">
|
<span className="hidden-sm">
|
||||||
<FormattedMessage {...sidebarLayoutMessages["app.sidebarLayout.discover"]} />
|
<FormattedMessage {...sidebarLayoutMessages["app.sidebarLayout.discover"]} />
|
||||||
@ -69,7 +72,7 @@ export default class SidebarLayoutIntl extends Component {
|
|||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<Link to="/browse" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.browse"])} className={isActive.browse}>
|
<Link to="/browse" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.browse"])} styleName={isActive.browse}>
|
||||||
<span className="glyphicon glyphicon-headphones" aria-hidden="true"></span>
|
<span className="glyphicon glyphicon-headphones" aria-hidden="true"></span>
|
||||||
<span className="hidden-sm">
|
<span className="hidden-sm">
|
||||||
<FormattedMessage {...sidebarLayoutMessages["app.sidebarLayout.browse"]} />
|
<FormattedMessage {...sidebarLayoutMessages["app.sidebarLayout.browse"]} />
|
||||||
@ -77,7 +80,7 @@ export default class SidebarLayoutIntl extends Component {
|
|||||||
</Link>
|
</Link>
|
||||||
<ul className="nav nav-list text-center">
|
<ul className="nav nav-list text-center">
|
||||||
<li>
|
<li>
|
||||||
<Link to="/artists" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.browseArtists"])} className={isActive.artists}>
|
<Link to="/artists" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.browseArtists"])} styleName={isActive.artists}>
|
||||||
<span className="glyphicon glyphicon-user" aria-hidden="true"></span>
|
<span className="glyphicon glyphicon-user" aria-hidden="true"></span>
|
||||||
<span className="sr-only">
|
<span className="sr-only">
|
||||||
<FormattedMessage {...sidebarLayoutMessages["app.common.artist"]} values={{itemCount: 42}} />
|
<FormattedMessage {...sidebarLayoutMessages["app.common.artist"]} values={{itemCount: 42}} />
|
||||||
@ -88,7 +91,7 @@ export default class SidebarLayoutIntl extends Component {
|
|||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<Link to="/albums" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.browseAlbums"])} className={isActive.albums}>
|
<Link to="/albums" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.browseAlbums"])} styleName={isActive.albums}>
|
||||||
<span className="glyphicon glyphicon-cd" aria-hidden="true"></span>
|
<span className="glyphicon glyphicon-cd" aria-hidden="true"></span>
|
||||||
<span className="sr-only"><FormattedMessage {...sidebarLayoutMessages["app.common.album"]} values={{itemCount: 42}} /></span>
|
<span className="sr-only"><FormattedMessage {...sidebarLayoutMessages["app.common.album"]} values={{itemCount: 42}} /></span>
|
||||||
<span className="hidden-sm">
|
<span className="hidden-sm">
|
||||||
@ -97,7 +100,7 @@ export default class SidebarLayoutIntl extends Component {
|
|||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<Link to="/songs" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.browseSongs"])} className={isActive.songs}>
|
<Link to="/songs" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.browseSongs"])} styleName={isActive.songs}>
|
||||||
<span className="glyphicon glyphicon-music" aria-hidden="true"></span>
|
<span className="glyphicon glyphicon-music" aria-hidden="true"></span>
|
||||||
<span className="sr-only">
|
<span className="sr-only">
|
||||||
<FormattedMessage {...sidebarLayoutMessages["app.common.song"]} values={{itemCount: 42}} />
|
<FormattedMessage {...sidebarLayoutMessages["app.common.song"]} values={{itemCount: 42}} />
|
||||||
@ -110,7 +113,7 @@ export default class SidebarLayoutIntl extends Component {
|
|||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<Link to="/search" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.search"])} className={isActive.search}>
|
<Link to="/search" title={formatMessage(sidebarLayoutMessages["app.sidebarLayout.search"])} styleName={isActive.search}>
|
||||||
<span className="glyphicon glyphicon-search" aria-hidden="true"></span>
|
<span className="glyphicon glyphicon-search" aria-hidden="true"></span>
|
||||||
<span className="hidden-sm">
|
<span className="hidden-sm">
|
||||||
<FormattedMessage {...sidebarLayoutMessages["app.sidebarLayout.search"]} />
|
<FormattedMessage {...sidebarLayoutMessages["app.sidebarLayout.search"]} />
|
||||||
@ -121,7 +124,7 @@ export default class SidebarLayoutIntl extends Component {
|
|||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-sm-11 col-sm-offset-1 col-md-10 col-md-offset-2 main-panel">
|
<div className="col-sm-11 col-sm-offset-1 col-md-10 col-md-offset-2" styleName="main-panel">
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -135,5 +138,4 @@ SidebarLayoutIntl.propTypes = {
|
|||||||
intl: intlShape.isRequired
|
intl: intlShape.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export let SidebarLayout = injectIntl(SidebarLayoutIntl);
|
export default injectIntl(CSSModules(SidebarLayoutIntl, css));
|
||||||
export default SidebarLayout;
|
|
||||||
|
6
app/dist/1.1.js
vendored
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
2
app/dist/1.1.js.map
vendored
File diff suppressed because one or more lines are too long
38
app/dist/3.3.js
vendored
38
app/dist/3.3.js
vendored
File diff suppressed because one or more lines are too long
2
app/dist/fix.ie9.js
vendored
2
app/dist/fix.ie9.js
vendored
@ -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(526);Object.keys(r).forEach(function(e){"default"!==e&&Object.defineProperty(t,e,{enumerable:!0,get:function(){return r[e]}})})},526: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(585);Object.keys(r).forEach(function(e){"default"!==e&&Object.defineProperty(t,e,{enumerable:!0,get:function(){return r[e]}})})},585: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
|
2
app/dist/fix.ie9.js.map
vendored
2
app/dist/fix.ie9.js.map
vendored
File diff suppressed because one or more lines are too long
47
app/dist/index.js
vendored
47
app/dist/index.js
vendored
File diff suppressed because one or more lines are too long
2
app/dist/index.js.map
vendored
2
app/dist/index.js.map
vendored
File diff suppressed because one or more lines are too long
1
app/dist/reactIntlMessages.json
vendored
1
app/dist/reactIntlMessages.json
vendored
@ -1 +0,0 @@
|
|||||||
[]
|
|
10
app/dist/style.css
vendored
10
app/dist/style.css
vendored
File diff suppressed because one or more lines are too long
27
app/styles/Album.scss
Normal file
27
app/styles/Album.scss
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
.row {
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.art {
|
||||||
|
composes: art from "./elements/Grid.scss";
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.nameRow h2 {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.artRow p,
|
||||||
|
.artRow img {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nameRow,
|
||||||
|
.artRow {
|
||||||
|
float: none;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
}
|
13
app/styles/Artist.scss
Normal file
13
app/styles/Artist.scss
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
.name > h1 {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name > hr {
|
||||||
|
margin-top: 0.5em; /* Default value. */
|
||||||
|
}
|
||||||
|
|
||||||
|
.art {
|
||||||
|
composes: art from "./elements/Grid.scss";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Use table-condensed if xs screen */
|
9
app/styles/Login.scss
Normal file
9
app/styles/Login.scss
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
.titleImage {
|
||||||
|
height: 46px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.submit {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
@ -1,248 +0,0 @@
|
|||||||
/* Firefox hack for responsive table */
|
|
||||||
@-moz-document url-prefix() {
|
|
||||||
fieldset {
|
|
||||||
display: table-cell;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sidebar
|
|
||||||
*/
|
|
||||||
.sidebar {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: 1000;
|
|
||||||
display: block;
|
|
||||||
padding: 20px;
|
|
||||||
overflow-x: hidden;
|
|
||||||
overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */
|
|
||||||
background-color: #333;
|
|
||||||
color: white;
|
|
||||||
border-right: 1px solid #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sidebar elements */
|
|
||||||
.sidebar a {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar h1 {
|
|
||||||
margin: 0;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar h1 img {
|
|
||||||
height: 46px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar h1 a {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sidebar navigation */
|
|
||||||
.sidebar .navbar {
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-sidebar {
|
|
||||||
margin-right: -20px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
margin-left: -20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-sidebar > li > a {
|
|
||||||
padding-right: 20px;
|
|
||||||
padding-left: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 991px) {
|
|
||||||
.sidebar,
|
|
||||||
.sidebar .navbar .container-fluid {
|
|
||||||
padding-left: 5px;
|
|
||||||
padding-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar .nav-list {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar .nav-sidebar > li > a {
|
|
||||||
padding-left: 20px;
|
|
||||||
padding-right: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar .nav-list > li > a {
|
|
||||||
padding-left: 20px;
|
|
||||||
padding-right: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-sidebar .nav-sidebar {
|
|
||||||
margin-bottom: 0; /* No margin bottom for nested nav-sidebar. */
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-sidebar > .active > a:focus,
|
|
||||||
.nav > li > a:focus {
|
|
||||||
color: #fff;
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-sidebar > .active > a,
|
|
||||||
.nav-sidebar > .active > a:hover,
|
|
||||||
.nav > li > a:hover {
|
|
||||||
color: #fff;
|
|
||||||
background-color: #222;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav > li > a.active {
|
|
||||||
background-color: #222;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-navbar {
|
|
||||||
background-color: #555;
|
|
||||||
font-size: 1.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-navbar-nav {
|
|
||||||
display: inline-block;
|
|
||||||
float: none;
|
|
||||||
vertical-align: top;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Main content
|
|
||||||
*/
|
|
||||||
.main-panel {
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
.main-panel {
|
|
||||||
padding-right: 40px;
|
|
||||||
padding-left: 40px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Filtering field
|
|
||||||
*/
|
|
||||||
div.filter {
|
|
||||||
margin-bottom: 34px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.filter-legend {
|
|
||||||
text-align: right;
|
|
||||||
line-height: 34px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 767px) {
|
|
||||||
.filter-legend {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 767px) {
|
|
||||||
.filter .form-group {
|
|
||||||
width: 75%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Placeholder dashboard ideas
|
|
||||||
*/
|
|
||||||
.placeholders {
|
|
||||||
margin-bottom: 30px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.placeholders h4 {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.placeholder img:hover {
|
|
||||||
transform: scale(1.1);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pager
|
|
||||||
*/
|
|
||||||
.pagination-nav {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pagination > li > span {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Login screen
|
|
||||||
*/
|
|
||||||
.login h1 img {
|
|
||||||
height: 46px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 767px) {
|
|
||||||
.login .submit {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Misc
|
|
||||||
*/
|
|
||||||
|
|
||||||
.art {
|
|
||||||
display: inline-block;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
width: 75%;
|
|
||||||
height: auto;
|
|
||||||
|
|
||||||
/* doiuse-disable viewport-units */
|
|
||||||
|
|
||||||
max-width: 25vw;
|
|
||||||
max-height: 25vw;
|
|
||||||
|
|
||||||
/* doiuse-enable viewport-units */
|
|
||||||
}
|
|
||||||
|
|
||||||
.albumRow {
|
|
||||||
margin-top: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.artistNameRow h1 {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.artistNameRow hr {
|
|
||||||
margin-top: 0.5em; /* Default value. */
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 767px) {
|
|
||||||
.table-responsive {
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.albumRowName h2 {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.albumRowArt p,
|
|
||||||
.albumRowArt img {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.albumRowName,
|
|
||||||
.albumRowArt {
|
|
||||||
float: none;
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: middle;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: Use table-condensed if xs screen */
|
|
7
app/styles/common/common.scss
Normal file
7
app/styles/common/common.scss
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
:global {
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.table-responsive {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
8
app/styles/common/hacks.scss
Normal file
8
app/styles/common/hacks.scss
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
:global {
|
||||||
|
/* Firefox hack for responsive table */
|
||||||
|
@-moz-document url-prefix() {
|
||||||
|
fieldset {
|
||||||
|
display: table-cell;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2
app/styles/common/index.js
Normal file
2
app/styles/common/index.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from "./hacks.scss";
|
||||||
|
export * from "./common.scss";
|
20
app/styles/elements/FilterBar.scss
Normal file
20
app/styles/elements/FilterBar.scss
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
.filter {
|
||||||
|
margin-bottom: 34px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend {
|
||||||
|
text-align: right;
|
||||||
|
line-height: 34px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.legend {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 767px) {
|
||||||
|
.form-group {
|
||||||
|
width: 75%;
|
||||||
|
}
|
||||||
|
}
|
26
app/styles/elements/Grid.scss
Normal file
26
app/styles/elements/Grid.scss
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
.placeholders {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.art {
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
width: 75%;
|
||||||
|
height: auto;
|
||||||
|
|
||||||
|
/* doiuse-disable viewport-units */
|
||||||
|
|
||||||
|
max-width: 25vw;
|
||||||
|
|
||||||
|
/* doiuse-enable viewport-units */
|
||||||
|
}
|
||||||
|
|
||||||
|
.art:hover {
|
||||||
|
transform: scale(1.1);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
7
app/styles/elements/Pagination.scss
Normal file
7
app/styles/elements/Pagination.scss
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
.nav {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
100
app/styles/layouts/Sidebar.scss
Normal file
100
app/styles/layouts/Sidebar.scss
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
$background: #333;
|
||||||
|
$hoverBackground: #222;
|
||||||
|
$activeBackground: $hoverBackground;
|
||||||
|
$foreground: white;
|
||||||
|
$lightgrey: #eee;
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
display: block;
|
||||||
|
padding: 20px;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */
|
||||||
|
background-color: $background;
|
||||||
|
color: white;
|
||||||
|
border-right: 1px solid $lightgrey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sidebar elements */
|
||||||
|
.link {
|
||||||
|
color: $foreground;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link:hover,
|
||||||
|
.link:focus {
|
||||||
|
color: $foreground;
|
||||||
|
background-color: $hoverBackground !important; /* TODO: important */
|
||||||
|
}
|
||||||
|
|
||||||
|
.active {
|
||||||
|
composes: link;
|
||||||
|
background-color: $activeBackground;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin: 0;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.imgTitle {
|
||||||
|
height: 46px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sidebar navigation */
|
||||||
|
.icon-navbar {
|
||||||
|
background-color: #555;
|
||||||
|
font-size: 1.25em;
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
.nav {
|
||||||
|
display: inline-block;
|
||||||
|
float: none;
|
||||||
|
vertical-align: top;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Main content
|
||||||
|
*/
|
||||||
|
.main-panel {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Media queries
|
||||||
|
* TODO: Sidebar responsiveness
|
||||||
|
*/
|
||||||
|
/*@media (max-width: 991px) {
|
||||||
|
.sidebar,
|
||||||
|
.sidebar .navbar .container-fluid {
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar .nav-list {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar .nav-sidebar > li > a {
|
||||||
|
padding-left: 20px;
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar .nav-list > li > a {
|
||||||
|
padding-left: 20px;
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.main-panel {
|
||||||
|
padding-right: 40px;
|
||||||
|
padding-left: 40px;
|
||||||
|
}
|
||||||
|
}*/
|
@ -4,7 +4,6 @@ then
|
|||||||
against=HEAD
|
against=HEAD
|
||||||
else
|
else
|
||||||
# Initial commit
|
# Initial commit
|
||||||
# TODO
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -17,5 +16,7 @@ then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Rebuilding dist JavaScript files…"
|
echo "Rebuilding dist JavaScript files…"
|
||||||
NODE_ENV=production npm run build
|
export NODE_ENV=production
|
||||||
|
npm run clean
|
||||||
|
npm run build
|
||||||
git add app/dist
|
git add app/dist
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
// Export
|
|
||||||
import "bootstrap";
|
|
||||||
import "bootstrap/dist/css/bootstrap.css";
|
|
||||||
import "./app/styles/ampache.css";
|
|
||||||
|
|
||||||
// Handle app init
|
// Handle app init
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
|
10
package.json
10
package.json
@ -11,12 +11,13 @@
|
|||||||
"watch": "./node_modules/.bin/webpack --progress --watch",
|
"watch": "./node_modules/.bin/webpack --progress --watch",
|
||||||
"prod": "NODE_ENV=production ./node_modules/.bin/webpack --progress",
|
"prod": "NODE_ENV=production ./node_modules/.bin/webpack --progress",
|
||||||
"extractTranslations": "./node_modules/.bin/babel-node scripts/extractTranslations.js",
|
"extractTranslations": "./node_modules/.bin/babel-node scripts/extractTranslations.js",
|
||||||
"clean": "./node_modules/.bin/rimraf app/dist"
|
"clean": "./node_modules/.bin/rimraf .cache && ./node_modules/.bin/rimraf app/dist"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"babel-polyfill": "^6.9.1",
|
"babel-polyfill": "^6.9.1",
|
||||||
"babel-preset-es2015": "^6.9.0",
|
"babel-preset-es2015": "^6.9.0",
|
||||||
"bootstrap": "^3.3.6",
|
"bootstrap-loader": "^1.0.10",
|
||||||
|
"bootstrap-sass": "^3.3.7",
|
||||||
"fuse.js": "^2.3.0",
|
"fuse.js": "^2.3.0",
|
||||||
"html5shiv": "^3.7.3",
|
"html5shiv": "^3.7.3",
|
||||||
"humps": "^1.1.0",
|
"humps": "^1.1.0",
|
||||||
@ -29,6 +30,7 @@
|
|||||||
"jssha": "^2.1.0",
|
"jssha": "^2.1.0",
|
||||||
"lodash": "^4.13.1",
|
"lodash": "^4.13.1",
|
||||||
"react": "^15.2.0",
|
"react": "^15.2.0",
|
||||||
|
"react-css-modules": "^3.7.9",
|
||||||
"react-dom": "^15.2.0",
|
"react-dom": "^15.2.0",
|
||||||
"react-intl": "^2.1.3",
|
"react-intl": "^2.1.3",
|
||||||
"react-redux": "^4.4.5",
|
"react-redux": "^4.4.5",
|
||||||
@ -44,7 +46,6 @@
|
|||||||
"babel-core": "^6.10.4",
|
"babel-core": "^6.10.4",
|
||||||
"babel-loader": "^6.2.4",
|
"babel-loader": "^6.2.4",
|
||||||
"babel-plugin-react-intl": "^2.1.3",
|
"babel-plugin-react-intl": "^2.1.3",
|
||||||
"babel-plugin-transform-runtime": "^6.12.0",
|
|
||||||
"babel-preset-react": "^6.11.1",
|
"babel-preset-react": "^6.11.1",
|
||||||
"css-loader": "^0.23.1",
|
"css-loader": "^0.23.1",
|
||||||
"doiuse": "^2.4.1",
|
"doiuse": "^2.4.1",
|
||||||
@ -55,6 +56,7 @@
|
|||||||
"extract-text-webpack-plugin": "^1.0.1",
|
"extract-text-webpack-plugin": "^1.0.1",
|
||||||
"file-loader": "^0.9.0",
|
"file-loader": "^0.9.0",
|
||||||
"glob": "^7.0.5",
|
"glob": "^7.0.5",
|
||||||
|
"node-sass": "^3.8.0",
|
||||||
"postcss": "^5.1.0",
|
"postcss": "^5.1.0",
|
||||||
"postcss-loader": "^0.9.1",
|
"postcss-loader": "^0.9.1",
|
||||||
"postcss-reporter": "^1.4.1",
|
"postcss-reporter": "^1.4.1",
|
||||||
@ -63,7 +65,9 @@
|
|||||||
"react-intl-webpack-plugin": "0.0.3",
|
"react-intl-webpack-plugin": "0.0.3",
|
||||||
"redbox-react": "^1.2.10",
|
"redbox-react": "^1.2.10",
|
||||||
"redux-logger": "^2.6.1",
|
"redux-logger": "^2.6.1",
|
||||||
|
"resolve-url-loader": "^1.6.0",
|
||||||
"rimraf": "^2.5.4",
|
"rimraf": "^2.5.4",
|
||||||
|
"sass-loader": "^4.0.0",
|
||||||
"style-loader": "^0.13.1",
|
"style-loader": "^0.13.1",
|
||||||
"stylelint": "^7.0.3",
|
"stylelint": "^7.0.3",
|
||||||
"stylelint-config-standard": "^11.0.0",
|
"stylelint-config-standard": "^11.0.0",
|
||||||
|
@ -11,7 +11,7 @@ var browsers = ["ie >= 9", "> 1%", "last 3 versions", "not op_mini all"];
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
entry: {
|
entry: {
|
||||||
"index": ["babel-polyfill", "./index.js"],
|
"index": ["babel-polyfill", "bootstrap-loader", "./app/styles/common/index.js", "./index.js"],
|
||||||
"fix.ie9": "./fix.ie9.js"
|
"fix.ie9": "./fix.ie9.js"
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -40,24 +40,22 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
include: __dirname
|
include: __dirname
|
||||||
},
|
},
|
||||||
// Do not postcss vendor modules
|
|
||||||
{
|
{
|
||||||
test: /\.css$/,
|
test: /\.css$/,
|
||||||
exclude: /node_modules/,
|
loader: ExtractTextPlugin.extract(
|
||||||
loader: ExtractTextPlugin.extract("style-loader", "css-loader!postcss-loader")
|
"style-loader",
|
||||||
},
|
"css-loader?modules&importLoaders=1&localIdentName=[name]__[local]__[hash:base64:5]" +
|
||||||
{
|
"!postcss-loader"
|
||||||
test: /\.css$/,
|
)
|
||||||
exclude: /app/,
|
|
||||||
loader: ExtractTextPlugin.extract("style-loader", "css-loader")
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.less$/,
|
|
||||||
loader: ExtractTextPlugin.extract("style-loader", "css-loader!less-loader")
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.scss$/,
|
test: /\.scss$/,
|
||||||
loader: ExtractTextPlugin.extract("style-loader", "css-loader!sass-loader")
|
loader: ExtractTextPlugin.extract(
|
||||||
|
"style-loader",
|
||||||
|
"css-loader?modules&importLoaders=1&localIdentName=[name]__[local]__[hash:base64:5]" +
|
||||||
|
// TODO: "!postcss-loader" +
|
||||||
|
"!sass-loader"
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
|
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
|
||||||
@ -86,9 +84,7 @@ module.exports = {
|
|||||||
new ExtractTextPlugin("style.css", { allChunks: true })
|
new ExtractTextPlugin("style.css", { allChunks: true })
|
||||||
],
|
],
|
||||||
|
|
||||||
postcss: function () {
|
postcss: [doiuse({ browsers: browsers }), stylelint, precss, autoprefixer({ browsers: browsers }), postcssReporter({ throwError: true, clearMessages: true })],
|
||||||
return [doiuse({ browsers: browsers }), stylelint, precss, autoprefixer({ browsers: browsers }), postcssReporter({ throwError: true, clearMessages: true })];
|
|
||||||
},
|
|
||||||
|
|
||||||
resolve: {
|
resolve: {
|
||||||
// Include empty string "" to resolve files by their explicit extension
|
// Include empty string "" to resolve files by their explicit extension
|
||||||
|
@ -4,9 +4,9 @@ var config = require("./webpack.config.base.js");
|
|||||||
config.devtool = "cheap-module-eval-source-map";
|
config.devtool = "cheap-module-eval-source-map";
|
||||||
|
|
||||||
// necessary for hot reloading with IE:
|
// necessary for hot reloading with IE:
|
||||||
config.entry.eventsourcePolyfill = 'eventsource-polyfill';
|
config.entry.index.splice(1, 0, 'eventsource-polyfill');
|
||||||
// listen to code updates emitted by hot middleware:
|
// listen to code updates emitted by hot middleware:
|
||||||
config.entry.webpackHotMiddlewareClient = 'webpack-hot-middleware/client';
|
config.entry.index.splice(2, 0, 'webpack-hot-middleware/client');
|
||||||
|
|
||||||
config.plugins = config.plugins.concat([
|
config.plugins = config.plugins.concat([
|
||||||
new webpack.HotModuleReplacementPlugin()
|
new webpack.HotModuleReplacementPlugin()
|
||||||
|
Loading…
Reference in New Issue
Block a user