diff --git a/.bootstraprc b/.bootstraprc new file mode 100644 index 0000000..f0b6d58 --- /dev/null +++ b/.bootstraprc @@ -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 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c2c711e..0c4b086 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,13 +21,13 @@ A few `npm` scripts are provided: 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 translate, with an extra description provided as a comment at the end of the line, for some translation context. 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 -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 strings in the `./app/locales/$LOCALE/index.js` file you have just created. diff --git a/TODO b/TODO index cbc5f8f..d875c6d 100644 --- a/TODO +++ b/TODO @@ -5,12 +5,8 @@ 8. Search 9. Discover - # CSS - * Sidebar responsiveness - * Move CSS in modules - => https://github.com/gajus/react-css-modules - + * Focus stays on navbar # API middleware * https://github.com/reactjs/redux/issues/1824#issuecomment-228609501 @@ -18,6 +14,7 @@ * https://github.com/reactjs/redux/issues/644 * 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/erikras/multireducer * Immutable.js (?) + get rid of lodash diff --git a/app/components/Album.jsx b/app/components/Album.jsx index 42581d4..8184911 100644 --- a/app/components/Album.jsx +++ b/app/components/Album.jsx @@ -1,7 +1,10 @@ import React, { Component, PropTypes } from "react"; +import CSSModules from "react-css-modules"; import { formatLength } from "../utils"; +import css from "../styles/Album.scss"; + export class AlbumTrackRow extends Component { render () { const length = formatLength(this.props.track.length); @@ -40,28 +43,34 @@ AlbumTracksTable.propTypes = { tracks: PropTypes.array.isRequired }; -export class AlbumRow extends Component { +class AlbumRowCSS extends Component { render () { return ( -
-
+
+

{this.props.album.name}

-
-

{this.props.album.name}

+
+

{this.props.album.name}

- + { + Array.isArray(this.props.album.tracks) ? + : + null + }
); } } -AlbumRow.propTypes = { +AlbumRowCSS.propTypes = { album: PropTypes.object.isRequired }; +export let AlbumRow = CSSModules(AlbumRowCSS, css); + export default class Album extends Component { render () { return ( diff --git a/app/components/Artist.jsx b/app/components/Artist.jsx index 7fb1eae..f2c1648 100644 --- a/app/components/Artist.jsx +++ b/app/components/Artist.jsx @@ -1,8 +1,11 @@ import React, { Component, PropTypes } from "react"; +import CSSModules from "react-css-modules"; import { AlbumRow } from "./Album"; -export default class Artist extends Component { +import css from "../styles/Artist.scss"; + +class ArtistCSS extends Component { render () { var albumsRows = []; if (Array.isArray(this.props.artist.albums)) { @@ -12,7 +15,7 @@ export default class Artist extends Component { } return (
-
+

{this.props.artist.name}


@@ -23,7 +26,7 @@ export default class Artist extends Component {

{this.props.artist.summary}

-

{this.props.artist.name}/

+

{this.props.artist.name}/

{ albumsRows } @@ -32,6 +35,8 @@ export default class Artist extends Component { } } -Artist.propTypes = { +ArtistCSS.propTypes = { artist: PropTypes.object.isRequired }; + +export default CSSModules(ArtistCSS, css); diff --git a/app/components/Login.jsx b/app/components/Login.jsx index 3c4535b..969326b 100644 --- a/app/components/Login.jsx +++ b/app/components/Login.jsx @@ -1,12 +1,15 @@ import React, { Component, PropTypes } from "react"; +import CSSModules from "react-css-modules"; import { defineMessages, injectIntl, intlShape, FormattedMessage } from "react-intl"; import { messagesMap } from "../utils"; import messages from "../locales/messagesDescriptors/Login"; +import css from "../styles/Login.scss"; + const loginMessages = defineMessages(messagesMap(messages)); -class LoginFormIntl extends Component { +class LoginFormCSSIntl extends Component { constructor (props) { super(props); @@ -61,8 +64,8 @@ class LoginFormIntl extends Component { { this.props.error ?
-
-

+

+

{ this.props.error }

@@ -105,7 +108,7 @@ class LoginFormIntl extends Component {
-
+
@@ -119,7 +122,7 @@ class LoginFormIntl extends Component { } } -LoginFormIntl.propTypes = { +LoginFormCSSIntl.propTypes = { username: PropTypes.string, endpoint: PropTypes.string, rememberMe: PropTypes.bool, @@ -130,10 +133,10 @@ LoginFormIntl.propTypes = { 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 () { const greeting = (

@@ -141,8 +144,8 @@ export default class Login extends Component {

); return ( -
-

Ampache

+
+

Ampache


{(!this.props.error && !this.props.info) ? greeting : null}
@@ -162,3 +165,5 @@ Login.propTypes = { error: PropTypes.string, info: PropTypes.string }; + +export default CSSModules(Login, css); diff --git a/app/components/Songs.jsx b/app/components/Songs.jsx index 82b774b..ebdd2d4 100644 --- a/app/components/Songs.jsx +++ b/app/components/Songs.jsx @@ -65,13 +65,13 @@ export class SongsTable extends Component { - + - + - + diff --git a/app/components/elements/FilterBar.jsx b/app/components/elements/FilterBar.jsx index b7fc551..67e0f7c 100644 --- a/app/components/elements/FilterBar.jsx +++ b/app/components/elements/FilterBar.jsx @@ -1,12 +1,15 @@ import React, { Component, PropTypes } from "react"; +import CSSModules from "react-css-modules"; import { defineMessages, injectIntl, intlShape, FormattedMessage } from "react-intl"; import { messagesMap } from "../../utils"; import messages from "../../locales/messagesDescriptors/elements/FilterBar"; +import css from "../../styles/elements/FilterBar.scss"; + const filterMessages = defineMessages(messagesMap(messages)); -class FilterBarIntl extends Component { +class FilterBarCSSIntl extends Component { constructor (props) { super(props); this.handleChange = this.handleChange.bind(this); @@ -21,14 +24,14 @@ class FilterBarIntl extends Component { render () { const {formatMessage} = this.props.intl; return ( -
-

+

+

-
- +
+
@@ -37,11 +40,10 @@ class FilterBarIntl extends Component { } } -FilterBarIntl.propTypes = { +FilterBarCSSIntl.propTypes = { onUserInput: PropTypes.func, filterText: PropTypes.string, intl: intlShape.isRequired }; -export let FilterBar = injectIntl(FilterBarIntl); -export default FilterBar; +export default injectIntl(CSSModules(FilterBarCSSIntl, css)); diff --git a/app/components/elements/Grid.jsx b/app/components/elements/Grid.jsx index d69d03a..b544e5b 100644 --- a/app/components/elements/Grid.jsx +++ b/app/components/elements/Grid.jsx @@ -1,5 +1,6 @@ import React, { Component, PropTypes } from "react"; import { Link} from "react-router"; +import CSSModules from "react-css-modules"; import imagesLoaded from "imagesloaded"; import Isotope from "isotope-layout"; import Fuse from "fuse.js"; @@ -8,7 +9,9 @@ import _ from "lodash"; import FilterBar from "./FilterBar"; import Pagination from "./Pagination"; -export class GridItem extends Component { +import css from "../../styles/elements/Grid.scss"; + +class GridItemCSS extends Component { render () { var nSubItems = this.props.item[this.props.subItemsType]; if (Array.isArray(nSubItems)) { @@ -27,10 +30,10 @@ export class GridItem extends Component { // TODO: i18n const title = "Go to " + this.props.itemsType.rstrip("s") + " page"; return ( -
-
- {this.props.item.name}/ -

{this.props.item.name}

+
+
+ {this.props.item.name}/ +

{this.props.item.name}

{nSubItems} {subItemsLabel}
@@ -38,12 +41,14 @@ export class GridItem extends Component { } } -GridItem.propTypes = { +GridItemCSS.propTypes = { item: PropTypes.object.isRequired, itemsType: PropTypes.string.isRequired, subItemsType: PropTypes.string.isRequired }; +export let GridItem = CSSModules(GridItemCSS, css); + const ISOTOPE_OPTIONS = { /** Default options for Isotope grid layout. */ getSortData: { @@ -93,9 +98,9 @@ export class Grid extends Component { // Apply filter on grid this.iso.arrange({ - filter: function () { - var name = $(this).find(".name").text(); - return result.find(function (item) { return item.item.name == name; }); + filter: function (item) { + var name = $(item).find(".name").text(); + return result.find(function (i) { return i.item.name == name; }); }, transitionDuration: "0.4s", getSortData: { diff --git a/app/components/elements/Pagination.jsx b/app/components/elements/Pagination.jsx index 2bd296e..0945def 100644 --- a/app/components/elements/Pagination.jsx +++ b/app/components/elements/Pagination.jsx @@ -1,14 +1,17 @@ import React, { Component, PropTypes } from "react"; import { Link, withRouter } from "react-router"; +import CSSModules from "react-css-modules"; import { defineMessages, injectIntl, intlShape, FormattedMessage, FormattedHTMLMessage } from "react-intl"; import { messagesMap } from "../../utils"; import commonMessages from "../../locales/messagesDescriptors/common"; import messages from "../../locales/messagesDescriptors/elements/Pagination"; +import css from "../../styles/elements/Pagination.scss"; + const paginationMessages = defineMessages(messagesMap(Array.concat([], commonMessages, messages))); -export class PaginationIntl extends Component { +class PaginationCSSIntl extends Component { constructor(props) { super(props); this.buildLinkTo.bind(this); @@ -134,8 +137,8 @@ export class PaginationIntl extends Component { if (pagesButton.length > 1) { return (
-