Very basic local view

This commit is contained in:
James Barnsley
2016-11-01 07:37:18 +13:00
parent bab6c66852
commit 25c973205a
15 changed files with 424 additions and 59 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -3670,12 +3670,28 @@ main header h1 {
padding-top: 30px;
}
.album-view .main {
padding-left: 35%;
}
.album-view .main .title {
padding: 30px 40px;
}
.album-view .main .title h3 {
color: #AAAAAA;
}
.album-view .main .title h3 a:hover {
color: #777777;
}
.album-view .intro {
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 300px;
width: 35%;
background: #EEEEEE;
}
@ -3725,19 +3741,19 @@ main header h1 {
opacity: 1;
}
.album-view .main {
padding-left: 300px;
.playlist-view .main {
padding-left: 35%;
}
.album-view .main .title {
.playlist-view .main .title {
padding: 30px 40px;
}
.album-view .main .title h3 {
.playlist-view .main .title h3 {
color: #AAAAAA;
}
.album-view .main .title h3 a:hover {
.playlist-view .main .title h3 a:hover {
color: #777777;
}
@ -3746,7 +3762,7 @@ main header h1 {
top: 0;
left: 0;
bottom: 0;
width: 300px;
width: 35%;
background: #EEEEEE;
}
@ -3796,20 +3812,4 @@ main header h1 {
opacity: 1;
}
.playlist-view .main {
padding-left: 300px;
}
.playlist-view .main .title {
padding: 30px 40px;
}
.playlist-view .main .title h3 {
color: #AAAAAA;
}
.playlist-view .main .title h3 a:hover {
color: #777777;
}
/*# sourceMappingURL=app.css.map*/

File diff suppressed because one or more lines are too long

View File

@ -147,6 +147,14 @@
var _LibraryPlaylists2 = _interopRequireDefault(_LibraryPlaylists);
var _LibraryLocal = __webpack_require__(380);
var _LibraryLocal2 = _interopRequireDefault(_LibraryLocal);
var _LibraryLocalDirectory = __webpack_require__(381);
var _LibraryLocalDirectory2 = _interopRequireDefault(_LibraryLocalDirectory);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
@ -175,6 +183,8 @@
_react2.default.createElement(_reactRouter.Route, { path: '/library/albums', component: _LibraryAlbums2.default }),
_react2.default.createElement(_reactRouter.Route, { path: '/library/tracks', component: _LibraryTracks2.default }),
_react2.default.createElement(_reactRouter.Route, { path: '/library/playlists', component: _LibraryPlaylists2.default }),
_react2.default.createElement(_reactRouter.Route, { path: '/library/local', component: _LibraryLocal2.default }),
_react2.default.createElement(_reactRouter.Route, { path: '/library/local/directory/:uri', component: _LibraryLocalDirectory2.default }),
_react2.default.createElement(_reactRouter.Route, { path: '/album/:uri', component: _Album2.default }),
_react2.default.createElement(_reactRouter.Route, { path: '/artist/:uri', component: _Artist2.default }),
_react2.default.createElement(_reactRouter.Route, { path: '/playlist/:uri', component: _Playlist2.default }),
@ -1721,6 +1731,7 @@
exports.next = next;
exports.previous = previous;
exports.getPlaylists = getPlaylists;
exports.getBrowse = getBrowse;
/**
* Actions and Action Creators
@ -1816,6 +1827,14 @@
function getPlaylists() {
return { type: 'MOPIDY_PLAYLISTS' };
}
function getBrowse(uri) {
return {
type: 'MOPIDY_INSTRUCT',
call: 'library.browse',
value: { uri: uri }
};
}
/***/ },
/* 17 */
@ -18309,6 +18328,12 @@
{ activeClassName: 'active', disabled: !this.props.spotify.authorized, to: '/library/tracks' },
_react2.default.createElement(_Icon2.default, { name: 'music', className: 'white' }),
'Tracks'
),
_react2.default.createElement(
_reactRouter.Link,
{ activeClassName: 'active', to: '/library/local' },
_react2.default.createElement(_Icon2.default, { name: 'folder', className: 'white' }),
'Local'
)
),
_react2.default.createElement(
@ -19133,6 +19158,11 @@
volume: action.data
});
case 'MOPIDY_BROWSE':
return Object.assign({}, mopidy, {
browse: action.data
});
default:
return mopidy;
}
@ -48821,6 +48851,209 @@
exports.default = Dater;
/***/ },
/* 380 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(2);
var _react2 = _interopRequireDefault(_react);
var _reactRedux = __webpack_require__(8);
var _redux = __webpack_require__(6);
var _reactRouter = __webpack_require__(12);
var _Header = __webpack_require__(18);
var _Header2 = _interopRequireDefault(_Header);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var LibraryLocal = function (_React$Component) {
_inherits(LibraryLocal, _React$Component);
function LibraryLocal(props) {
_classCallCheck(this, LibraryLocal);
return _possibleConstructorReturn(this, (LibraryLocal.__proto__ || Object.getPrototypeOf(LibraryLocal)).call(this, props));
}
_createClass(LibraryLocal, [{
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
{ className: 'view library-local-view' },
_react2.default.createElement(_Header2.default, { icon: 'folder', title: 'Local' }),
_react2.default.createElement(
_reactRouter.Link,
{ to: '/library/local/directory/local:directory' },
'Folders'
)
);
}
}]);
return LibraryLocal;
}(_react2.default.Component);
exports.default = LibraryLocal;
/***/ },
/* 381 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(2);
var _react2 = _interopRequireDefault(_react);
var _reactRedux = __webpack_require__(8);
var _redux = __webpack_require__(6);
var _reactRouter = __webpack_require__(12);
var _Header = __webpack_require__(18);
var _Header2 = _interopRequireDefault(_Header);
var _actions = __webpack_require__(16);
var mopidyActions = _interopRequireWildcard(_actions);
var _actions2 = __webpack_require__(11);
var spotifyActions = _interopRequireWildcard(_actions2);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var LibraryLocalDirectory = function (_React$Component) {
_inherits(LibraryLocalDirectory, _React$Component);
function LibraryLocalDirectory(props) {
_classCallCheck(this, LibraryLocalDirectory);
return _possibleConstructorReturn(this, (LibraryLocalDirectory.__proto__ || Object.getPrototypeOf(LibraryLocalDirectory)).call(this, props));
}
// on render
_createClass(LibraryLocalDirectory, [{
key: 'componentDidMount',
value: function componentDidMount() {
this.loadDirectory();
}
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
// mopidy goes online
if (!this.props.mopidy.connected && nextProps.mopidy.connected) {
this.loadDirectory();
}
// our uri changes
if (nextProps.params.uri != this.props.params.uri) {
this.loadDirectory(nextProps.params.uri);
}
}
}, {
key: 'loadDirectory',
value: function loadDirectory() {
var uri = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props.params.uri;
if (this.props.mopidy.connected) {
this.props.mopidyActions.getBrowse(uri);
}
}
}, {
key: 'renderDirectory',
value: function renderDirectory() {
if (!this.props.mopidy.browse) return null;
return _react2.default.createElement(
'div',
null,
this.props.mopidy.browse.map(function (directory) {
return _react2.default.createElement(
'div',
{ key: directory.uri },
_react2.default.createElement(
_reactRouter.Link,
{ to: '/library/local/directory/' + encodeURIComponent(directory.uri) },
directory.name
)
);
})
);
}
}, {
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
{ className: 'view library-local-view' },
_react2.default.createElement(_Header2.default, { icon: 'music', title: 'Local' }),
this.renderDirectory()
);
}
}]);
return LibraryLocalDirectory;
}(_react2.default.Component);
/**
* Export our component
*
* We also integrate our global store, using connect()
**/
var mapStateToProps = function mapStateToProps(state, ownProps) {
return state;
};
var mapDispatchToProps = function mapDispatchToProps(dispatch) {
return {
mopidyActions: (0, _redux.bindActionCreators)(mopidyActions, dispatch),
spotifyActions: (0, _redux.bindActionCreators)(spotifyActions, dispatch)
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(LibraryLocalDirectory);
/***/ }
/******/ ])));
//# sourceMappingURL=app.js.map

File diff suppressed because one or more lines are too long

View File

@ -70,6 +70,10 @@ class Sidebar extends React.Component{
<Icon name="music" className="white" />
Tracks
</Link>
<Link activeClassName="active" to="/library/local">
<Icon name="folder" className="white" />
Local
</Link>
</section>
<section>

View File

@ -29,6 +29,8 @@ import LibraryArtists from './views/library/LibraryArtists'
import LibraryAlbums from './views/library/LibraryAlbums'
import LibraryTracks from './views/library/LibraryTracks'
import LibraryPlaylists from './views/library/LibraryPlaylists'
import LibraryLocal from './views/library/LibraryLocal'
import LibraryLocalDirectory from './views/library/LibraryLocalDirectory'
ReactDOM.render(
<Provider store={store}>
@ -48,6 +50,8 @@ ReactDOM.render(
<Route path="/library/albums" component={LibraryAlbums} />
<Route path="/library/tracks" component={LibraryTracks} />
<Route path="/library/playlists" component={LibraryPlaylists} />
<Route path="/library/local" component={LibraryLocal} />
<Route path="/library/local/directory/:uri" component={LibraryLocalDirectory} />
<Route path="/album/:uri" component={Album} />
<Route path="/artist/:uri" component={Artist} />

View File

@ -95,3 +95,11 @@ export function getPlaylists(){
return { type: 'MOPIDY_PLAYLISTS' }
}
export function getBrowse( uri ){
return {
type: 'MOPIDY_INSTRUCT',
call: 'library.browse',
value: { uri: uri }
}
}

View File

@ -72,6 +72,11 @@ export default function reducer(mopidy = {}, action){
volume: action.data
});
case 'MOPIDY_BROWSE':
return Object.assign({}, mopidy, {
browse: action.data
});
default:
return mopidy
}

View File

@ -0,0 +1,23 @@
import React, { PropTypes } from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { Link } from 'react-router'
import Header from '../../components/Header'
export default class LibraryLocal extends React.Component{
constructor(props) {
super(props);
}
render(){
return (
<div className="view library-local-view">
<Header icon="folder" title="Local" />
<Link to="/library/local/directory/local:directory">Folders</Link>
</div>
);
}
}

View File

@ -0,0 +1,90 @@
import React, { PropTypes } from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { Link } from 'react-router'
import Header from '../../components/Header'
import * as mopidyActions from '../../services/mopidy/actions'
import * as spotifyActions from '../../services/spotify/actions'
class LibraryLocalDirectory extends React.Component{
constructor(props) {
super(props);
}
// on render
componentDidMount(){
this.loadDirectory()
}
componentWillReceiveProps( nextProps ){
// mopidy goes online
if( !this.props.mopidy.connected && nextProps.mopidy.connected ){
this.loadDirectory();
}
// our uri changes
if( nextProps.params.uri != this.props.params.uri ){
this.loadDirectory(nextProps.params.uri);
}
}
loadDirectory(uri = this.props.params.uri){
if( this.props.mopidy.connected ){
this.props.mopidyActions.getBrowse(uri);
}
}
renderDirectory(){
if( !this.props.mopidy.browse ) return null
return (
<div>
{
this.props.mopidy.browse.map( directory => {
return (
<div key={directory.uri}>
<Link to={'/library/local/directory/'+encodeURIComponent(directory.uri)}>
{ directory.name }
</Link>
</div>
)
})
}
</div>
)
}
render(){
return (
<div className="view library-local-view">
<Header icon="music" title="Local" />
{ this.renderDirectory() }
</div>
);
}
}
/**
* Export our component
*
* We also integrate our global store, using connect()
**/
const mapStateToProps = (state, ownProps) => {
return state;
}
const mapDispatchToProps = (dispatch) => {
return {
mopidyActions: bindActionCreators(mopidyActions, dispatch),
spotifyActions: bindActionCreators(spotifyActions, dispatch)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(LibraryLocalDirectory)

View File

@ -1,11 +1,26 @@
.album-view {
.main {
padding-left: 35%;
.title {
padding: 30px 40px;
h3 {
color: $mid_grey;
a:hover {
color: darken($mid_grey, 20%);
}
}
}
}
.intro {
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 300px;
width: 35%;
background: $faint_grey;
.thumbnail {
@ -53,20 +68,4 @@
}
}
}
.main {
.title {
padding: 30px 40px;
h3 {
color: $mid_grey;
a:hover {
color: darken($mid_grey, 20%);
}
}
}
padding-left: 300px;
}
}

View File

@ -1,11 +1,26 @@
.playlist-view {
.main {
padding-left: 35%;
.title {
padding: 30px 40px;
h3 {
color: $mid_grey;
a:hover {
color: darken($mid_grey, 20%);
}
}
}
}
.intro {
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 300px;
width: 35%;
background: $faint_grey;
.thumbnail {
@ -53,20 +68,4 @@
}
}
}
.main {
.title {
padding: 30px 40px;
h3 {
color: $mid_grey;
a:hover {
color: darken($mid_grey, 20%);
}
}
}
padding-left: 300px;
}
}