More destructuring and removing componentWillReceiveProps
This commit is contained in:
@ -54211,9 +54211,7 @@ exports.default = (0, _react.memo)(function (props) {
|
||||
|
||||
return _react2.default.createElement(
|
||||
'span',
|
||||
{ className: className, onClick: function onClick(e) {
|
||||
return handleClick(e);
|
||||
} },
|
||||
{ className: className, onClick: handleClick },
|
||||
_react2.default.createElement(_Icon2.default, { name: 'more_horiz' })
|
||||
);
|
||||
});
|
||||
@ -54236,10 +54234,6 @@ Object.defineProperty(exports, "__esModule", {
|
||||
|
||||
var _react = __webpack_require__(/*! react */ "./node_modules/react/index.js");
|
||||
|
||||
var _react2 = _interopRequireDefault(_react);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
/**
|
||||
* Format time duration
|
||||
*
|
||||
@ -54376,7 +54370,7 @@ var _reactRedux = __webpack_require__(/*! react-redux */ "./node_modules/react-r
|
||||
|
||||
var _redux = __webpack_require__(/*! redux */ "./node_modules/redux/es/redux.js");
|
||||
|
||||
var _util = __webpack_require__(/*! ../util */ "./src/js/util/index.js");
|
||||
var _storage = __webpack_require__(/*! ../util/storage */ "./src/js/util/storage.js");
|
||||
|
||||
var _helpers = __webpack_require__(/*! ../util/helpers */ "./src/js/util/helpers.js");
|
||||
|
||||
@ -54397,10 +54391,10 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
|
||||
var DebugInfo = function (_React$Component) {
|
||||
_inherits(DebugInfo, _React$Component);
|
||||
|
||||
function DebugInfo(props) {
|
||||
function DebugInfo() {
|
||||
_classCallCheck(this, DebugInfo);
|
||||
|
||||
return _possibleConstructorReturn(this, (DebugInfo.__proto__ || Object.getPrototypeOf(DebugInfo)).call(this, props));
|
||||
return _possibleConstructorReturn(this, (DebugInfo.__proto__ || Object.getPrototypeOf(DebugInfo)).apply(this, arguments));
|
||||
}
|
||||
|
||||
_createClass(DebugInfo, [{
|
||||
@ -54428,32 +54422,13 @@ var DebugInfo = function (_React$Component) {
|
||||
}, {
|
||||
key: 'renderLoadQueue',
|
||||
value: function renderLoadQueue() {
|
||||
if (!this.props.ui.load_queue) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var load_queue = this.props.ui.load_queue;
|
||||
|
||||
var queue = [];
|
||||
|
||||
return _react2.default.createElement(
|
||||
if (!load_queue) return _react2.default.createElement(
|
||||
'div',
|
||||
{ className: 'debug-info-item' },
|
||||
queue
|
||||
{ className: 'debug-info-item mid_grey-text' },
|
||||
'Nothing loading'
|
||||
);
|
||||
}
|
||||
}, {
|
||||
key: 'renderLoadQueue',
|
||||
value: function renderLoadQueue() {
|
||||
if (!this.props.ui.load_queue) {
|
||||
return _react2.default.createElement(
|
||||
'div',
|
||||
{ className: 'debug-info-item mid_grey-text' },
|
||||
'Nothing loading'
|
||||
);
|
||||
}
|
||||
|
||||
var load_queue = this.props.ui.load_queue;
|
||||
|
||||
var queue = [];
|
||||
for (var key in load_queue) {
|
||||
@ -54574,7 +54549,7 @@ var DebugInfo = function (_React$Component) {
|
||||
{ className: 'debug-info-item' },
|
||||
'Cached URLs:',
|
||||
' ',
|
||||
Object.keys(_util.storage.get('cache')).length
|
||||
Object.keys((0, _storage.get)('cache')).length
|
||||
)
|
||||
),
|
||||
_react2.default.createElement(
|
||||
@ -54747,10 +54722,15 @@ var Dragger = function (_React$Component) {
|
||||
}, {
|
||||
key: 'handleMouseMove',
|
||||
value: function handleMouseMove(e) {
|
||||
if (!this.props.dragger) return null;
|
||||
var _props = this.props,
|
||||
dragger = _props.dragger,
|
||||
dragActive = _props.uiActions.dragActive;
|
||||
var target = e.target;
|
||||
|
||||
if (!dragger) return null;
|
||||
|
||||
var threshold = 10;
|
||||
if (e.clientX > this.props.dragger.start_x + threshold || e.clientX < this.props.dragger.start_x - threshold || e.clientY > this.props.dragger.start_y + threshold || e.clientY < this.props.dragger.start_y - threshold) {
|
||||
if (e.clientX > dragger.start_x + threshold || e.clientX < dragger.start_x - threshold || e.clientY > dragger.start_y + threshold || e.clientY < dragger.start_y - threshold) {
|
||||
this.setState({
|
||||
position_x: e.clientX,
|
||||
position_y: e.clientY
|
||||
@ -54761,38 +54741,47 @@ var Dragger = function (_React$Component) {
|
||||
dropzones[i].classList.remove('hover');
|
||||
}
|
||||
|
||||
if (e.target.classList.contains('dropzone') && !e.target.classList.contains('hover')) {
|
||||
e.target.className += ' hover';
|
||||
if (target.classList.contains('dropzone') && !target.classList.contains('hover')) {
|
||||
target.className += ' hover';
|
||||
}
|
||||
|
||||
// if not already, activate
|
||||
if (!this.props.dragger.active) this.props.uiActions.dragActive();
|
||||
if (!dragger.active) dragActive();
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: 'handleMouseUp',
|
||||
value: function handleMouseUp(e) {
|
||||
if (!this.props.dragger) return null;
|
||||
this.props.uiActions.dragEnd(e);
|
||||
var _props2 = this.props,
|
||||
dragger = _props2.dragger,
|
||||
dragEnd = _props2.uiActions.dragEnd;
|
||||
|
||||
if (!dragger) return null;
|
||||
dragEnd(e);
|
||||
}
|
||||
}, {
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
if (!this.props.dragger || !this.props.dragger.active) return null;
|
||||
var _props$dragger = this.props.dragger;
|
||||
_props$dragger = _props$dragger === undefined ? {} : _props$dragger;
|
||||
var active = _props$dragger.active,
|
||||
victims = _props$dragger.victims;
|
||||
var _state = this.state,
|
||||
position_x = _state.position_x,
|
||||
position_y = _state.position_y;
|
||||
|
||||
var style = {
|
||||
left: this.state.position_x,
|
||||
top: this.state.position_y
|
||||
};
|
||||
|
||||
if (!active) return null;
|
||||
|
||||
return _react2.default.createElement(
|
||||
'div',
|
||||
{ className: 'dragger', style: style },
|
||||
'Dragging',
|
||||
' ',
|
||||
this.props.dragger.victims.length,
|
||||
' ',
|
||||
'things'
|
||||
{
|
||||
className: 'dragger', style: {
|
||||
left: position_x,
|
||||
top: position_y
|
||||
}
|
||||
},
|
||||
'Dragging ' + victims.length + ' things'
|
||||
);
|
||||
}
|
||||
}]);
|
||||
@ -54800,7 +54789,7 @@ var Dragger = function (_React$Component) {
|
||||
return Dragger;
|
||||
}(_react2.default.Component);
|
||||
|
||||
var mapStateToProps = function mapStateToProps(state, ownProps) {
|
||||
var mapStateToProps = function mapStateToProps(state) {
|
||||
return {
|
||||
dragger: state.ui.dragger
|
||||
};
|
||||
@ -54858,10 +54847,33 @@ var ErrorBoundary = function (_React$Component) {
|
||||
|
||||
var _this = _possibleConstructorReturn(this, (ErrorBoundary.__proto__ || Object.getPrototypeOf(ErrorBoundary)).call(this, props));
|
||||
|
||||
_this.render = function () {
|
||||
var _this$state = _this.state,
|
||||
hasError = _this$state.hasError,
|
||||
_this$state$info = _this$state.info;
|
||||
_this$state$info = _this$state$info === undefined ? {} : _this$state$info;
|
||||
var componentStack = _this$state$info.componentStack;
|
||||
var children = _this.props.children;
|
||||
|
||||
|
||||
if (hasError) {
|
||||
return _react2.default.createElement(
|
||||
_ErrorMessage2.default,
|
||||
{ type: 'error-boundary' },
|
||||
componentStack && _react2.default.createElement(
|
||||
'pre',
|
||||
{ className: 'error-message__trace' },
|
||||
componentStack
|
||||
)
|
||||
);
|
||||
}
|
||||
return children;
|
||||
};
|
||||
|
||||
_this.state = {
|
||||
hasError: false,
|
||||
error: null,
|
||||
info: null
|
||||
info: {}
|
||||
};
|
||||
return _this;
|
||||
}
|
||||
@ -54876,22 +54888,6 @@ var ErrorBoundary = function (_React$Component) {
|
||||
});
|
||||
console.error(error, info);
|
||||
}
|
||||
}, {
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
if (this.state.hasError) {
|
||||
return _react2.default.createElement(
|
||||
_ErrorMessage2.default,
|
||||
{ type: 'error-boundary' },
|
||||
this.state.info ? _react2.default.createElement(
|
||||
'pre',
|
||||
{ className: 'error-message__trace' },
|
||||
this.state.info.componentStack
|
||||
) : null
|
||||
);
|
||||
}
|
||||
return this.props.children;
|
||||
}
|
||||
}]);
|
||||
|
||||
return ErrorBoundary;
|
||||
@ -54921,10 +54917,13 @@ var _react2 = _interopRequireDefault(_react);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
exports.default = (0, _react.memo)(function (props) {
|
||||
exports.default = (0, _react.memo)(function (_ref) {
|
||||
var type = _ref.type,
|
||||
title = _ref.title,
|
||||
children = _ref.children;
|
||||
return _react2.default.createElement(
|
||||
'div',
|
||||
{ className: 'error-message' + (props.type ? ' error-message--' + props.type : '') },
|
||||
{ className: 'error-message' + (type ? ' error-message--' + type : '') },
|
||||
_react2.default.createElement(
|
||||
'i',
|
||||
{ className: 'error-message__icon icon icon--material' },
|
||||
@ -54933,12 +54932,12 @@ exports.default = (0, _react.memo)(function (props) {
|
||||
_react2.default.createElement(
|
||||
'h4',
|
||||
{ className: 'error-message__title' },
|
||||
props.title ? props.title : 'Unknown error'
|
||||
title ? title : 'Unknown error'
|
||||
),
|
||||
_react2.default.createElement(
|
||||
'div',
|
||||
{ className: 'error-message__content' },
|
||||
props.children
|
||||
children
|
||||
)
|
||||
);
|
||||
});
|
||||
@ -58501,8 +58500,6 @@ 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__(/*! react */ "./node_modules/react/index.js");
|
||||
|
||||
var _react2 = _interopRequireDefault(_react);
|
||||
@ -58527,76 +58524,82 @@ var Header = function (_React$Component) {
|
||||
|
||||
var _this = _possibleConstructorReturn(this, (Header.__proto__ || Object.getPrototypeOf(Header)).call(this, props));
|
||||
|
||||
_this.handleContextMenuTrigger = function (e, options) {
|
||||
var _this$props = _this.props,
|
||||
title = _this$props.title,
|
||||
handleContextMenuTrigger = _this$props.handleContextMenuTrigger,
|
||||
showContextMenu = _this$props.uiActions.showContextMenu;
|
||||
|
||||
|
||||
if (handleContextMenuTrigger) return handleContextMenuTrigger(e);
|
||||
|
||||
e.preventDefault();
|
||||
var data = {
|
||||
e: e,
|
||||
context: 'custom',
|
||||
title: title,
|
||||
options: options
|
||||
};
|
||||
showContextMenu(data);
|
||||
};
|
||||
|
||||
_this.renderContextMenuTrigger = function () {
|
||||
var _this$props2 = _this.props,
|
||||
handleContextMenuTrigger = _this$props2.handleContextMenuTrigger,
|
||||
options = _this$props2.options;
|
||||
|
||||
|
||||
if (!handleContextMenuTrigger && !options) return null;
|
||||
|
||||
return _react2.default.createElement(_ContextMenuTrigger2.default, { onTrigger: function onTrigger(e) {
|
||||
return _this.handleContextMenuTrigger(e, options);
|
||||
} });
|
||||
};
|
||||
|
||||
_this.renderOptions = function () {
|
||||
var _this$props3 = _this.props,
|
||||
handleContextMenuTrigger = _this$props3.handleContextMenuTrigger,
|
||||
options = _this$props3.options;
|
||||
|
||||
|
||||
if (!options && !handleContextMenuTrigger) return null;
|
||||
|
||||
return _react2.default.createElement(
|
||||
'div',
|
||||
{ className: 'header__options' },
|
||||
_this.renderContextMenuTrigger(),
|
||||
_react2.default.createElement(
|
||||
'div',
|
||||
{ className: 'header__options__wrapper' },
|
||||
options || null
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
_this.render = function () {
|
||||
var _this$props4 = _this.props,
|
||||
className = _this$props4.className,
|
||||
children = _this$props4.children;
|
||||
|
||||
|
||||
return _react2.default.createElement(
|
||||
'header',
|
||||
{ className: className },
|
||||
_react2.default.createElement(
|
||||
'h1',
|
||||
null,
|
||||
children
|
||||
),
|
||||
_this.renderOptions()
|
||||
);
|
||||
};
|
||||
|
||||
_this.state = {
|
||||
expanded: false
|
||||
};
|
||||
return _this;
|
||||
}
|
||||
|
||||
_createClass(Header, [{
|
||||
key: 'handleContextMenuTrigger',
|
||||
value: function handleContextMenuTrigger(e, options) {
|
||||
// We have an override trigger (eg Album, Playlist)
|
||||
if (this.props.handleContextMenuTrigger) {
|
||||
return this.props.handleContextMenuTrigger(e);
|
||||
}
|
||||
e.preventDefault();
|
||||
var data = {
|
||||
e: e,
|
||||
context: 'custom',
|
||||
title: this.props.title,
|
||||
options: options
|
||||
};
|
||||
this.props.uiActions.showContextMenu(data);
|
||||
}
|
||||
}, {
|
||||
key: 'renderContextMenuTrigger',
|
||||
value: function renderContextMenuTrigger() {
|
||||
var _this2 = this;
|
||||
|
||||
// No custom trigger, nor any options
|
||||
if (!this.props.handleContextMenuTrigger && !this.props.options) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return _react2.default.createElement(_ContextMenuTrigger2.default, { onTrigger: function onTrigger(e) {
|
||||
return _this2.handleContextMenuTrigger(e, _this2.props.options);
|
||||
} });
|
||||
}
|
||||
}, {
|
||||
key: 'renderOptions',
|
||||
value: function renderOptions() {
|
||||
if (!this.props.options && !this.props.handleContextMenuTrigger) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return _react2.default.createElement(
|
||||
'div',
|
||||
{ className: 'header__options' },
|
||||
this.renderContextMenuTrigger(),
|
||||
_react2.default.createElement(
|
||||
'div',
|
||||
{ className: 'header__options__wrapper' },
|
||||
this.props.options || null
|
||||
)
|
||||
);
|
||||
}
|
||||
}, {
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
return _react2.default.createElement(
|
||||
'header',
|
||||
{ className: this.props.className ? this.props.className : null },
|
||||
_react2.default.createElement(
|
||||
'h1',
|
||||
null,
|
||||
this.props.children ? this.props.children : null
|
||||
),
|
||||
this.renderOptions()
|
||||
);
|
||||
}
|
||||
}]);
|
||||
|
||||
return Header;
|
||||
}(_react2.default.Component);
|
||||
|
||||
@ -58878,51 +58881,43 @@ var _reactFontawesome2 = _interopRequireDefault(_reactFontawesome);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
exports.default = (0, _react.memo)(function (props) {
|
||||
if (!props.name || props.name === '') {
|
||||
return null;
|
||||
}
|
||||
exports.default = (0, _react.memo)(function (_ref) {
|
||||
var name = _ref.name,
|
||||
type = _ref.type,
|
||||
className = _ref.className,
|
||||
onClick = _ref.onClick;
|
||||
|
||||
var className = 'icon icon--' + (props.type ? props.type : 'material');
|
||||
if (props.className) {
|
||||
className += ' ' + props.className;
|
||||
}
|
||||
if (!name || name === '') return null;
|
||||
|
||||
switch (props.type) {
|
||||
var fullClassName = 'icon icon--' + (type || 'material') + ' ' + className;
|
||||
|
||||
switch (type) {
|
||||
case 'svg':
|
||||
return _react2.default.createElement('img', { className: className, src: '/iris/assets/icons/' + props.name + '.svg', onClick: function onClick(e) {
|
||||
return props.onClick ? props.onClick(e) : null;
|
||||
} });
|
||||
return _react2.default.createElement('img', { className: fullClassName, src: '/iris/assets/icons/' + name + '.svg', onClick: onClick });
|
||||
|
||||
case 'gif':
|
||||
return _react2.default.createElement('img', { className: className, src: '/iris/assets/icons/' + props.name + '.gif', onClick: function onClick(e) {
|
||||
return props.onClick ? props.onClick(e) : null;
|
||||
} });
|
||||
return _react2.default.createElement('img', { className: fullClassName, src: '/iris/assets/icons/' + name + '.gif', onClick: onClick });
|
||||
|
||||
case 'fontawesome':
|
||||
return _react2.default.createElement(_reactFontawesome2.default, { className: className, type: 'fontawesome', name: props.name, onClick: function onClick(e) {
|
||||
return props.onClick ? props.onClick(e) : null;
|
||||
} });
|
||||
return _react2.default.createElement(_reactFontawesome2.default, { className: fullClassName, type: 'fontawesome', name: name, onClick: onClick });
|
||||
|
||||
case 'css':
|
||||
switch (props.name) {
|
||||
case 'playing':
|
||||
return _react2.default.createElement(
|
||||
'i',
|
||||
{ className: className + ' icon--playing' },
|
||||
_react2.default.createElement('span', null),
|
||||
_react2.default.createElement('span', null),
|
||||
_react2.default.createElement('span', null)
|
||||
);
|
||||
if (name === 'playing') {
|
||||
return _react2.default.createElement(
|
||||
'i',
|
||||
{ className: fullClassName + ' icon--playing' },
|
||||
_react2.default.createElement('span', null),
|
||||
_react2.default.createElement('span', null),
|
||||
_react2.default.createElement('span', null)
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return _react2.default.createElement(
|
||||
'i',
|
||||
{ className: className, onClick: function onClick(e) {
|
||||
return props.onClick ? props.onClick(e) : null;
|
||||
} },
|
||||
props.name
|
||||
{ className: fullClassName, onClick: onClick },
|
||||
name
|
||||
);
|
||||
}
|
||||
});
|
||||
@ -59058,7 +59053,7 @@ 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 _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
||||
|
||||
var _react = __webpack_require__(/*! react */ "./node_modules/react/index.js");
|
||||
|
||||
@ -59085,99 +59080,90 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
|
||||
var CustomLink = function (_React$Component) {
|
||||
_inherits(CustomLink, _React$Component);
|
||||
|
||||
function CustomLink(props) {
|
||||
function CustomLink() {
|
||||
var _ref;
|
||||
|
||||
var _temp, _this, _ret;
|
||||
|
||||
_classCallCheck(this, CustomLink);
|
||||
|
||||
return _possibleConstructorReturn(this, (CustomLink.__proto__ || Object.getPrototypeOf(CustomLink)).call(this, props));
|
||||
}
|
||||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
|
||||
args[_key] = arguments[_key];
|
||||
}
|
||||
|
||||
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = CustomLink.__proto__ || Object.getPrototypeOf(CustomLink)).call.apply(_ref, [this].concat(args))), _this), _this.handleClick = function () {
|
||||
var _this$props = _this.props,
|
||||
state = _this$props.location.state,
|
||||
history = _this$props.history,
|
||||
retainScroll = _this$props.retainScroll,
|
||||
scrollToProp = _this$props.scrollTo;
|
||||
|
||||
// Fetch the current scroll position of our #main element and save to our history's state, so
|
||||
// clicking 'back' etc will restore the previous scroll position.
|
||||
// This doesn't trigger lazy-load elements (unless scrolling exposes the LazyLoader component).
|
||||
|
||||
_createClass(CustomLink, [{
|
||||
key: 'handleClick',
|
||||
value: function handleClick(e) {
|
||||
// Fetch the current scroll position of our #main element and
|
||||
// save to our history's state, so clicking 'back' etc will restore
|
||||
// the previous scroll position.
|
||||
// Note that this doesn't trigger lazy-load elements (unless scrolling
|
||||
// exposes the LazyLoader component).
|
||||
var main = document.getElementById('main');
|
||||
var state = this.props.location && this.props.location.state ? this.props.location.state : {};
|
||||
state.scroll_position = main.scrollTop;
|
||||
|
||||
this.props.history.replace({ state: state });
|
||||
history.replace(_extends({}, state, {
|
||||
scroll_position: main.scrollTop
|
||||
}));
|
||||
|
||||
// Allow a link to disable auto-scrolling to the top of the page
|
||||
// on navigation. Useful for tabs, etc.
|
||||
if (!this.props.retainScroll) {
|
||||
(0, _helpers.scrollTo)(this.props.scrollTo, this.props.scrollTo);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: 'handleContextMenu',
|
||||
value: function handleContextMenu(e) {
|
||||
if (this.props.onContextMenu) {
|
||||
this.props.onContextMenu(e);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: 'isLinkActive',
|
||||
value: function isLinkActive(link) {
|
||||
// Decode both links
|
||||
// This handles issues where one link is encoded and the other isn't,
|
||||
// but they're otherwise identical
|
||||
if (!retainScroll) (0, _helpers.scrollTo)(scrollToProp, scrollToProp);
|
||||
}, _this.handleContextMenu = function (e) {
|
||||
var onContextMenu = _this.props.onContextMenu;
|
||||
|
||||
|
||||
if (onContextMenu) onContextMenu(e);
|
||||
}, _this.isLinkActive = function (link) {
|
||||
var _this$props2 = _this.props,
|
||||
exact = _this$props2.exact,
|
||||
_this$props2$history = _this$props2.history;
|
||||
_this$props2$history = _this$props2$history === undefined ? {} : _this$props2$history;
|
||||
var _this$props2$history$ = _this$props2$history.location;
|
||||
_this$props2$history$ = _this$props2$history$ === undefined ? {} : _this$props2$history$;
|
||||
var pathname = _this$props2$history$.pathname;
|
||||
|
||||
// Decode both links. This handles issues where one link is encoded and the other isn't, but
|
||||
// they're otherwise identical
|
||||
|
||||
link = decodeURIComponent(link);
|
||||
var current_link = decodeURIComponent(this.props.history.location.pathname);
|
||||
var current_link = decodeURIComponent(pathname);
|
||||
|
||||
if (this.props.exact) {
|
||||
return current_link === link;
|
||||
}
|
||||
if (exact) return current_link === link;
|
||||
return current_link.startsWith(link);
|
||||
}
|
||||
}, {
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
var _this2 = this;
|
||||
}, _this.render = function () {
|
||||
var _this$props3 = _this.props,
|
||||
className = _this$props3.className,
|
||||
activeClassName = _this$props3.activeClassName,
|
||||
to = _this$props3.to,
|
||||
children = _this$props3.children,
|
||||
history = _this$props3.history;
|
||||
|
||||
var className = '';
|
||||
if (this.props.className) {
|
||||
className += this.props.className;
|
||||
}
|
||||
|
||||
if (!this.props.to) {
|
||||
return _react2.default.createElement(
|
||||
'span',
|
||||
{ className: className },
|
||||
this.props.children
|
||||
);
|
||||
}
|
||||
if (!to) return _react2.default.createElement(
|
||||
'span',
|
||||
{ className: className },
|
||||
children
|
||||
);
|
||||
|
||||
// We have an active detector method
|
||||
// This is used almost solely by the Sidebar navigation
|
||||
if (this.props.history !== undefined) {
|
||||
if (this.isLinkActive(this.props.to)) {
|
||||
if (this.props.activeClassName) {
|
||||
className += ' ' + this.props.activeClassName;
|
||||
} else {
|
||||
className += ' active';
|
||||
}
|
||||
}
|
||||
}
|
||||
var active = history && _this.isLinkActive(to) ? activeClassName || 'active' : '';
|
||||
|
||||
return _react2.default.createElement(
|
||||
_reactRouterDom.Link,
|
||||
{
|
||||
onClick: function onClick(e) {
|
||||
return _this2.handleClick(e);
|
||||
},
|
||||
onContextMenu: function onContextMenu(e) {
|
||||
return _this2.handleContextMenu(e);
|
||||
},
|
||||
className: className,
|
||||
to: this.props.to
|
||||
onClick: _this.handleClick,
|
||||
onContextMenu: _this.handleContextMenu,
|
||||
className: className + ' ' + active,
|
||||
to: to
|
||||
},
|
||||
this.props.children
|
||||
children
|
||||
);
|
||||
}
|
||||
}]);
|
||||
}, _temp), _possibleConstructorReturn(_this, _ret);
|
||||
}
|
||||
|
||||
return CustomLink;
|
||||
}(_react2.default.Component);
|
||||
@ -59210,57 +59196,63 @@ var _URILink2 = _interopRequireDefault(_URILink);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
exports.default = (0, _react.memo)(function (props) {
|
||||
if (!props.items) {
|
||||
return _react2.default.createElement(
|
||||
'span',
|
||||
{ className: props.className ? props.className + ' links-sentence' : 'links-sentence' },
|
||||
'-'
|
||||
);
|
||||
}
|
||||
exports.default = (0, _react.memo)(function (_ref) {
|
||||
var items = _ref.items,
|
||||
className = _ref.className,
|
||||
nolinks = _ref.nolinks;
|
||||
|
||||
if (!items) return _react2.default.createElement(
|
||||
'span',
|
||||
{ className: className + ' links-sentence' },
|
||||
'-'
|
||||
);
|
||||
|
||||
return _react2.default.createElement(
|
||||
'span',
|
||||
{ className: props.className ? props.className + ' links-sentence' : 'links-sentence' },
|
||||
props.items.map(function (item, index) {
|
||||
if (!item) {
|
||||
return _react2.default.createElement(
|
||||
'span',
|
||||
null,
|
||||
'-'
|
||||
);
|
||||
}
|
||||
{ className: className + ' links-sentence' },
|
||||
items.map(function (_ref2, index) {
|
||||
var name = _ref2.name,
|
||||
uri = _ref2.uri;
|
||||
|
||||
if (!name) return _react2.default.createElement(
|
||||
'span',
|
||||
null,
|
||||
'-'
|
||||
);
|
||||
|
||||
var separator = null;
|
||||
if (index == props.items.length - 2) {
|
||||
if (index == items.length - 2) {
|
||||
separator = ' and ';
|
||||
} else if (index < props.items.length - 2) {
|
||||
} else if (index < items.length - 2) {
|
||||
separator = ', ';
|
||||
}
|
||||
|
||||
if (!item.name) {
|
||||
if (!name) {
|
||||
var content = _react2.default.createElement(
|
||||
'span',
|
||||
null,
|
||||
'-'
|
||||
);
|
||||
} else if (!item.uri || props.nolinks) {
|
||||
} else if (!uri || nolinks) {
|
||||
var content = _react2.default.createElement(
|
||||
'span',
|
||||
null,
|
||||
item.name
|
||||
name
|
||||
);
|
||||
} else {
|
||||
var content = _react2.default.createElement(
|
||||
_URILink2.default,
|
||||
{ className: 'links-sentence__item links-sentence__item--link', uri: item.uri },
|
||||
item.name
|
||||
{
|
||||
className: 'links-sentence__item links-sentence__item--link',
|
||||
uri: uri
|
||||
},
|
||||
name
|
||||
);
|
||||
}
|
||||
|
||||
return _react2.default.createElement(
|
||||
'span',
|
||||
{ key: 'index_' + item.uri },
|
||||
{ key: 'index_' + uri },
|
||||
content,
|
||||
separator
|
||||
);
|
||||
@ -78840,42 +78832,6 @@ exports.default = {
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "./src/js/util/index.js":
|
||||
/*!******************************!*\
|
||||
!*** ./src/js/util/index.js ***!
|
||||
\******************************/
|
||||
/*! no static exports found */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _helpers = __webpack_require__(/*! ./helpers */ "./src/js/util/helpers.js");
|
||||
|
||||
var helpers = _interopRequireWildcard(_helpers);
|
||||
|
||||
var _storage = __webpack_require__(/*! ./storage */ "./src/js/util/storage.js");
|
||||
|
||||
var storage = _interopRequireWildcard(_storage);
|
||||
|
||||
var _format = __webpack_require__(/*! ./format */ "./src/js/util/format.js");
|
||||
|
||||
var format = _interopRequireWildcard(_format);
|
||||
|
||||
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; } }
|
||||
|
||||
exports.default = {
|
||||
helpers: helpers,
|
||||
storage: storage,
|
||||
format: format
|
||||
};
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "./src/js/util/storage.js":
|
||||
/*!********************************!*\
|
||||
!*** ./src/js/util/storage.js ***!
|
||||
@ -87023,7 +86979,7 @@ var _actions2 = __webpack_require__(/*! ../../services/mopidy/actions */ "./src/
|
||||
|
||||
var mopidyActions = _interopRequireWildcard(_actions2);
|
||||
|
||||
var _helpers = __webpack_require__(/*! ../../util/helpers */ "./src/js/util/helpers.js");
|
||||
var _format = __webpack_require__(/*! ../../util/format */ "./src/js/util/format.js");
|
||||
|
||||
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; } }
|
||||
|
||||
@ -87127,7 +87083,7 @@ var LibraryBrowse = function (_React$Component) {
|
||||
grid_items.push({
|
||||
name: subdirectory.name,
|
||||
link: '/library/browse/' + encodeURIComponent(subdirectory.uri),
|
||||
icons: (0, _helpers.formatImages)(subdirectory.icons)
|
||||
icons: (0, _format.formatImages)(subdirectory.icons)
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -100,7 +100,7 @@
|
||||
|
||||
// Release details
|
||||
// These are automatically injected to built HTML
|
||||
var build = "1583309322";
|
||||
var build = "1583394938";
|
||||
var version = "3.45.1";
|
||||
|
||||
// Construct the script tag
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
import React, { memo } from 'react';
|
||||
import Icon from './Icon';
|
||||
|
||||
export default memo((props) => {
|
||||
export default memo((props) => {
|
||||
const handleClick = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@ -15,7 +15,7 @@ export default memo((props) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<span className={className} onClick={(e) => handleClick(e)}>
|
||||
<span className={className} onClick={handleClick}>
|
||||
<Icon name="more_horiz" />
|
||||
</span>
|
||||
);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
|
||||
import React, { memo } from 'react';
|
||||
import { memo } from 'react';
|
||||
|
||||
/**
|
||||
* Format time duration
|
||||
|
||||
@ -2,15 +2,11 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { storage } from '../util';
|
||||
import { get as getStorage } from '../util/storage';
|
||||
import { isTouchDevice } from '../util/helpers';
|
||||
import * as uiActions from '../services/ui/actions';
|
||||
|
||||
class DebugInfo extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
localStorageSize() {
|
||||
let data = '';
|
||||
|
||||
@ -33,26 +29,9 @@ class DebugInfo extends React.Component {
|
||||
}
|
||||
|
||||
renderLoadQueue() {
|
||||
if (!this.props.ui.load_queue) {
|
||||
return null;
|
||||
}
|
||||
const { ui: { load_queue } } = this.props;
|
||||
if (!load_queue) return <div className="debug-info-item mid_grey-text">Nothing loading</div>;
|
||||
|
||||
const { load_queue } = this.props.ui;
|
||||
const queue = [];
|
||||
|
||||
return (
|
||||
<div className="debug-info-item">
|
||||
{queue}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderLoadQueue() {
|
||||
if (!this.props.ui.load_queue) {
|
||||
return <div className="debug-info-item mid_grey-text">Nothing loading</div>;
|
||||
}
|
||||
|
||||
const { load_queue } = this.props.ui;
|
||||
const queue = [];
|
||||
for (const key in load_queue) {
|
||||
if (load_queue.hasOwnProperty(key)) {
|
||||
@ -134,7 +113,7 @@ class DebugInfo extends React.Component {
|
||||
<div className="debug-info-item">
|
||||
Cached URLs:
|
||||
{' '}
|
||||
{Object.keys(storage.get('cache')).length}
|
||||
{Object.keys(getStorage('cache')).length}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ import * as uiActions from '../services/ui/actions';
|
||||
import * as mopidyActions from '../services/mopidy/actions';
|
||||
import * as spotifyActions from '../services/spotify/actions';
|
||||
|
||||
class Dragger extends React.Component {
|
||||
class Dragger extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleMouseMove = this.handleMouseMove.bind(this);
|
||||
@ -31,14 +31,16 @@ class Dragger extends React.Component {
|
||||
}
|
||||
|
||||
handleMouseMove(e) {
|
||||
if (!this.props.dragger) return null;
|
||||
const { dragger, uiActions: { dragActive } } = this.props;
|
||||
const { target } = e;
|
||||
if (!dragger) return null;
|
||||
|
||||
const threshold = 10;
|
||||
if (
|
||||
e.clientX > this.props.dragger.start_x + threshold
|
||||
|| e.clientX < this.props.dragger.start_x - threshold
|
||||
|| e.clientY > this.props.dragger.start_y + threshold
|
||||
|| e.clientY < this.props.dragger.start_y - threshold) {
|
||||
e.clientX > dragger.start_x + threshold
|
||||
|| e.clientX < dragger.start_x - threshold
|
||||
|| e.clientY > dragger.start_y + threshold
|
||||
|| e.clientY < dragger.start_y - threshold) {
|
||||
this.setState({
|
||||
position_x: e.clientX,
|
||||
position_y: e.clientY,
|
||||
@ -49,41 +51,41 @@ class Dragger extends React.Component {
|
||||
dropzones[i].classList.remove('hover');
|
||||
}
|
||||
|
||||
if (e.target.classList.contains('dropzone') && !e.target.classList.contains('hover')) {
|
||||
e.target.className += ' hover';
|
||||
if (target.classList.contains('dropzone') && !target.classList.contains('hover')) {
|
||||
target.className += ' hover';
|
||||
}
|
||||
|
||||
// if not already, activate
|
||||
if (!this.props.dragger.active) this.props.uiActions.dragActive();
|
||||
if (!dragger.active) dragActive();
|
||||
}
|
||||
}
|
||||
|
||||
handleMouseUp(e) {
|
||||
if (!this.props.dragger) return null;
|
||||
this.props.uiActions.dragEnd(e);
|
||||
const { dragger, uiActions: { dragEnd } } = this.props;
|
||||
if (!dragger) return null;
|
||||
dragEnd(e);
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.props.dragger || !this.props.dragger.active) return null;
|
||||
const { dragger: { active, victims } = {} } = this.props;
|
||||
const { position_x, position_y } = this.state;
|
||||
|
||||
const style = {
|
||||
left: this.state.position_x,
|
||||
top: this.state.position_y,
|
||||
};
|
||||
if (!active) return null;
|
||||
|
||||
return (
|
||||
<div className="dragger" style={style}>
|
||||
Dragging
|
||||
{' '}
|
||||
{ this.props.dragger.victims.length }
|
||||
{' '}
|
||||
things
|
||||
<div
|
||||
className="dragger" style={{
|
||||
left: position_x,
|
||||
top: position_y,
|
||||
}}
|
||||
>
|
||||
{`Dragging ${victims.length} things`}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state, ownProps) => ({
|
||||
const mapStateToProps = (state) => ({
|
||||
dragger: state.ui.dragger,
|
||||
});
|
||||
|
||||
@ -93,4 +95,4 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
mopidyActions: bindActionCreators(mopidyActions, dispatch),
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Dragger);
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Dragger);
|
||||
|
||||
@ -2,13 +2,13 @@
|
||||
import React from 'react';
|
||||
import ErrorMessage from './ErrorMessage';
|
||||
|
||||
export default class ErrorBoundary extends React.Component {
|
||||
export default class ErrorBoundary extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
hasError: false,
|
||||
error: null,
|
||||
info: null,
|
||||
info: {},
|
||||
};
|
||||
}
|
||||
|
||||
@ -21,14 +21,17 @@ export default class ErrorBoundary extends React.Component {
|
||||
console.error(error, info);
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.hasError) {
|
||||
render = () => {
|
||||
const { hasError, info: { componentStack } = {} } = this.state;
|
||||
const { children } = this.props;
|
||||
|
||||
if (hasError) {
|
||||
return (
|
||||
<ErrorMessage type="error-boundary">
|
||||
{this.state.info ? <pre className="error-message__trace">{this.state.info.componentStack}</pre> : null}
|
||||
{componentStack && <pre className="error-message__trace">{componentStack}</pre>}
|
||||
</ErrorMessage>
|
||||
);
|
||||
}
|
||||
return this.props.children;
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,18 +1,14 @@
|
||||
|
||||
import React, { memo } from 'react';
|
||||
|
||||
export default memo((props) => (
|
||||
<div className={`error-message${props.type ? ` error-message--${props.type}` : ''}`}>
|
||||
|
||||
export default memo(({ type, title, children }) => (
|
||||
<div className={`error-message${type ? ` error-message--${type}` : ''}`}>
|
||||
<i className="error-message__icon icon icon--material">error</i>
|
||||
|
||||
<h4 className="error-message__title">
|
||||
{props.title ? props.title : 'Unknown error'}
|
||||
{title ? title : 'Unknown error'}
|
||||
</h4>
|
||||
|
||||
<div className="error-message__content">
|
||||
{props.children}
|
||||
{children}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
));
|
||||
|
||||
@ -1,100 +0,0 @@
|
||||
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import LinksSentence from './LinksSentence';
|
||||
import Thumbnail from './Thumbnail';
|
||||
|
||||
import * as uiActions from '../services/ui/actions';
|
||||
|
||||
class GridSlider extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this._pagelimit = 3;
|
||||
|
||||
this.state = {
|
||||
page: 0,
|
||||
};
|
||||
}
|
||||
|
||||
handleClick(e, link) {
|
||||
if (e.target.tagName.toLowerCase() !== 'a') {
|
||||
this.props.history.push(link);
|
||||
}
|
||||
}
|
||||
|
||||
handleContextMenu(e, item) {
|
||||
e.preventDefault();
|
||||
const data = {
|
||||
uris: [item.uri],
|
||||
item,
|
||||
};
|
||||
this.props.uiActions.showContextMenu(e, data, 'album', 'click');
|
||||
}
|
||||
|
||||
next() {
|
||||
if (this.state.page >= this._pagelimit) return false;
|
||||
this.setState({ page: this.state.page + 1 });
|
||||
}
|
||||
|
||||
previous() {
|
||||
if (this.state.page <= 0) return false;
|
||||
this.setState({ page: this.state.page - 1 });
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.props.tracks) {
|
||||
let className = 'grid-slider-wrapper';
|
||||
if (this.props.className) className += ` ${this.props.className}`;
|
||||
|
||||
const style = {
|
||||
left: `-${this.state.page * 100}%`,
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
{ this.props.title ? this.props.title : null }
|
||||
<div className="controls">
|
||||
<Icon type="fontawesome" name="chevron-left" disabled={this.state.page <= 0} onClick={() => this.previous()} />
|
||||
<Icon type="fontawesome" name="chevron-right" disabled={this.state.page >= this._pagelimit} onClick={() => this.next()} />
|
||||
</div>
|
||||
<div className="grid-slider">
|
||||
<div className="grid artist-grid liner" style={style}>
|
||||
{
|
||||
this.props.tracks.map(
|
||||
(track, index) => {
|
||||
const album = { ...track.album, artists: track.artists };
|
||||
return (
|
||||
<div
|
||||
className="grid-item"
|
||||
key={index}
|
||||
onClick={(e) => this.handleClick(e, `/album/${album.uri}`)}
|
||||
onContextMenu={(e) => this.handleContextMenu(e, album)}
|
||||
>
|
||||
<Thumbnail size="medium" images={album.images} />
|
||||
<div className="name">{ album.name }</div>
|
||||
<div className="secondary">
|
||||
{ album.artists ? <LinksSentence items={album.artists} /> : <span>-</span> }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state, ownProps) => ({});
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
uiActions: bindActionCreators(uiActions, dispatch),
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(GridSlider);
|
||||
@ -11,50 +11,63 @@ export default class Header extends React.Component {
|
||||
};
|
||||
}
|
||||
|
||||
handleContextMenuTrigger(e, options) {
|
||||
// We have an override trigger (eg Album, Playlist)
|
||||
if (this.props.handleContextMenuTrigger) {
|
||||
return this.props.handleContextMenuTrigger(e);
|
||||
}
|
||||
handleContextMenuTrigger = (e, options) => {
|
||||
const {
|
||||
title,
|
||||
handleContextMenuTrigger,
|
||||
uiActions: {
|
||||
showContextMenu,
|
||||
},
|
||||
} = this.props;
|
||||
|
||||
if (handleContextMenuTrigger) return handleContextMenuTrigger(e);
|
||||
|
||||
e.preventDefault();
|
||||
const data = {
|
||||
e,
|
||||
context: 'custom',
|
||||
title: this.props.title,
|
||||
title,
|
||||
options,
|
||||
};
|
||||
this.props.uiActions.showContextMenu(data);
|
||||
showContextMenu(data);
|
||||
}
|
||||
|
||||
renderContextMenuTrigger() {
|
||||
// No custom trigger, nor any options
|
||||
if (!this.props.handleContextMenuTrigger && !this.props.options) {
|
||||
return null;
|
||||
}
|
||||
renderContextMenuTrigger = () => {
|
||||
const {
|
||||
handleContextMenuTrigger,
|
||||
options,
|
||||
} = this.props;
|
||||
|
||||
return <ContextMenuTrigger onTrigger={(e) => this.handleContextMenuTrigger(e, this.props.options)} />;
|
||||
if (!handleContextMenuTrigger && !options) return null;
|
||||
|
||||
return <ContextMenuTrigger onTrigger={(e) => this.handleContextMenuTrigger(e, options)} />;
|
||||
}
|
||||
|
||||
renderOptions() {
|
||||
if (!this.props.options && !this.props.handleContextMenuTrigger) {
|
||||
return null;
|
||||
}
|
||||
renderOptions = () => {
|
||||
const {
|
||||
handleContextMenuTrigger,
|
||||
options,
|
||||
} = this.props;
|
||||
|
||||
if (!options && !handleContextMenuTrigger) return null;
|
||||
|
||||
return (
|
||||
<div className="header__options">
|
||||
{this.renderContextMenuTrigger()}
|
||||
<div className="header__options__wrapper">
|
||||
{this.props.options || null}
|
||||
{options || null}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
render = () => {
|
||||
const { className, children } = this.props;
|
||||
|
||||
return (
|
||||
<header className={(this.props.className ? this.props.className : null)}>
|
||||
<header className={className}>
|
||||
<h1>
|
||||
{this.props.children ? this.props.children : null}
|
||||
{children}
|
||||
</h1>
|
||||
{this.renderOptions()}
|
||||
</header>
|
||||
|
||||
@ -2,39 +2,34 @@
|
||||
import React, { memo } from 'react';
|
||||
import FontAwesome from 'react-fontawesome';
|
||||
|
||||
export default memo((props) => {
|
||||
if (!props.name || props.name === '') {
|
||||
return null;
|
||||
}
|
||||
export default memo(({ name, type, className, onClick }) => {
|
||||
if (!name || name === '') return null;
|
||||
|
||||
let className = `icon icon--${props.type ? props.type : 'material'}`;
|
||||
if (props.className) {
|
||||
className += ` ${props.className}`;
|
||||
}
|
||||
const fullClassName = `icon icon--${type || 'material'} ${className}`;
|
||||
|
||||
switch (props.type) {
|
||||
switch (type) {
|
||||
case 'svg':
|
||||
return <img className={className} src={`/iris/assets/icons/${props.name}.svg`} onClick={(e) => (props.onClick ? props.onClick(e) : null)} />;
|
||||
return <img className={fullClassName} src={`/iris/assets/icons/${name}.svg`} onClick={onClick} />;
|
||||
|
||||
case 'gif':
|
||||
return <img className={className} src={`/iris/assets/icons/${props.name}.gif`} onClick={(e) => (props.onClick ? props.onClick(e) : null)} />;
|
||||
return <img className={fullClassName} src={`/iris/assets/icons/${name}.gif`} onClick={onClick} />;
|
||||
|
||||
case 'fontawesome':
|
||||
return <FontAwesome className={className} type="fontawesome" name={props.name} onClick={(e) => (props.onClick ? props.onClick(e) : null)} />;
|
||||
return <FontAwesome className={fullClassName} type="fontawesome" name={name} onClick={onClick} />;
|
||||
|
||||
case 'css':
|
||||
switch (props.name) {
|
||||
case 'playing':
|
||||
return (
|
||||
<i className={`${className} icon--playing`}>
|
||||
<span />
|
||||
<span />
|
||||
<span />
|
||||
</i>
|
||||
);
|
||||
if (name === 'playing') {
|
||||
return (
|
||||
<i className={`${fullClassName} icon--playing`}>
|
||||
<span />
|
||||
<span />
|
||||
<span />
|
||||
</i>
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return <i className={className} onClick={(e) => (props.onClick ? props.onClick(e) : null)}>{props.name}</i>;
|
||||
return <i className={fullClassName} onClick={onClick}>{name}</i>;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
import React from 'react';
|
||||
import { withRouter } from 'react-router';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import { scrollTo } from '../util/helpers';
|
||||
|
||||
/**
|
||||
@ -10,78 +9,79 @@ import { scrollTo } from '../util/helpers';
|
||||
* which lets us scroll to the top of our <main> for a more traditional navigation experience
|
||||
* */
|
||||
class CustomLink extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
handleClick = () => {
|
||||
const {
|
||||
location: {
|
||||
state,
|
||||
},
|
||||
history,
|
||||
retainScroll,
|
||||
scrollTo: scrollToProp,
|
||||
} = this.props;
|
||||
|
||||
handleClick(e) {
|
||||
// Fetch the current scroll position of our #main element and
|
||||
// save to our history's state, so clicking 'back' etc will restore
|
||||
// the previous scroll position.
|
||||
// Note that this doesn't trigger lazy-load elements (unless scrolling
|
||||
// exposes the LazyLoader component).
|
||||
// Fetch the current scroll position of our #main element and save to our history's state, so
|
||||
// clicking 'back' etc will restore the previous scroll position.
|
||||
// This doesn't trigger lazy-load elements (unless scrolling exposes the LazyLoader component).
|
||||
const main = document.getElementById('main');
|
||||
const state = (this.props.location && this.props.location.state ? this.props.location.state : {});
|
||||
state.scroll_position = main.scrollTop;
|
||||
|
||||
this.props.history.replace({ state });
|
||||
history.replace({
|
||||
...state,
|
||||
scroll_position: main.scrollTop,
|
||||
});
|
||||
|
||||
// Allow a link to disable auto-scrolling to the top of the page
|
||||
// on navigation. Useful for tabs, etc.
|
||||
if (!this.props.retainScroll) {
|
||||
scrollTo(this.props.scrollTo, (this.props.scrollTo));
|
||||
}
|
||||
if (!retainScroll) scrollTo(scrollToProp, (scrollToProp));
|
||||
}
|
||||
|
||||
handleContextMenu(e) {
|
||||
if (this.props.onContextMenu) {
|
||||
this.props.onContextMenu(e);
|
||||
}
|
||||
handleContextMenu = (e) => {
|
||||
const { onContextMenu } = this.props;
|
||||
|
||||
if (onContextMenu) onContextMenu(e);
|
||||
}
|
||||
|
||||
isLinkActive(link) {
|
||||
// Decode both links
|
||||
// This handles issues where one link is encoded and the other isn't,
|
||||
// but they're otherwise identical
|
||||
isLinkActive = (link) => {
|
||||
const {
|
||||
exact,
|
||||
history: {
|
||||
location: {
|
||||
pathname,
|
||||
} = {},
|
||||
} = {},
|
||||
} = this.props;
|
||||
|
||||
// Decode both links. This handles issues where one link is encoded and the other isn't, but
|
||||
// they're otherwise identical
|
||||
link = decodeURIComponent(link);
|
||||
const current_link = decodeURIComponent(this.props.history.location.pathname);
|
||||
const current_link = decodeURIComponent(pathname);
|
||||
|
||||
if (this.props.exact) {
|
||||
return current_link === link;
|
||||
}
|
||||
if (exact) return current_link === link;
|
||||
return current_link.startsWith(link);
|
||||
}
|
||||
|
||||
render() {
|
||||
let className = '';
|
||||
if (this.props.className) {
|
||||
className += this.props.className;
|
||||
}
|
||||
render = () => {
|
||||
const {
|
||||
className,
|
||||
activeClassName,
|
||||
to,
|
||||
children,
|
||||
history,
|
||||
} = this.props;
|
||||
|
||||
if (!this.props.to) {
|
||||
return <span className={className}>{this.props.children}</span>;
|
||||
}
|
||||
if (!to) return <span className={className}>{children}</span>;
|
||||
|
||||
// We have an active detector method
|
||||
// This is used almost solely by the Sidebar navigation
|
||||
if (this.props.history !== undefined) {
|
||||
if (this.isLinkActive(this.props.to)) {
|
||||
if (this.props.activeClassName) {
|
||||
className += ` ${this.props.activeClassName}`;
|
||||
} else {
|
||||
className += ' active';
|
||||
}
|
||||
}
|
||||
}
|
||||
const active = history && this.isLinkActive(to) ? (activeClassName || 'active') : '';
|
||||
|
||||
return (
|
||||
<Link
|
||||
onClick={(e) => this.handleClick(e)}
|
||||
onContextMenu={(e) => this.handleContextMenu(e)}
|
||||
className={className}
|
||||
to={this.props.to}
|
||||
onClick={this.handleClick}
|
||||
onContextMenu={this.handleContextMenu}
|
||||
className={`${className} ${active}`}
|
||||
to={to}
|
||||
>
|
||||
{this.props.children}
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
@ -2,38 +2,41 @@
|
||||
import React, { memo } from 'react';
|
||||
import URILink from './URILink';
|
||||
|
||||
export default memo((props) => {
|
||||
if (!props.items) {
|
||||
return <span className={props.className ? `${props.className} links-sentence` : 'links-sentence'}>-</span>;
|
||||
}
|
||||
export default memo(({ items, className, nolinks }) => {
|
||||
if (!items) return <span className={`${className} links-sentence`}>-</span>;
|
||||
|
||||
return (
|
||||
<span className={props.className ? `${props.className} links-sentence` : 'links-sentence'}>
|
||||
<span className={`${className} links-sentence`}>
|
||||
{
|
||||
props.items.map((item, index) => {
|
||||
if (!item) {
|
||||
return <span>-</span>;
|
||||
}
|
||||
items.map(({ name, uri }, index) => {
|
||||
if (!name) return <span>-</span>;
|
||||
|
||||
let separator = null;
|
||||
if (index == props.items.length - 2) {
|
||||
if (index == items.length - 2) {
|
||||
separator = ' and ';
|
||||
} else if (index < props.items.length - 2) {
|
||||
} else if (index < items.length - 2) {
|
||||
separator = ', ';
|
||||
}
|
||||
|
||||
if (!item.name) {
|
||||
if (!name) {
|
||||
var content = <span>-</span>;
|
||||
} else if (!item.uri || props.nolinks) {
|
||||
var content = <span>{ item.name }</span>;
|
||||
} else if (!uri || nolinks) {
|
||||
var content = <span>{name}</span>;
|
||||
} else {
|
||||
var content = <URILink className="links-sentence__item links-sentence__item--link" uri={item.uri}>{ item.name }</URILink>;
|
||||
var content = (
|
||||
<URILink
|
||||
className="links-sentence__item links-sentence__item--link"
|
||||
uri={uri}
|
||||
>
|
||||
{name}
|
||||
</URILink>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<span key={`index_${item.uri}`}>
|
||||
{ content }
|
||||
{ separator }
|
||||
<span key={`index_${uri}`}>
|
||||
{content}
|
||||
{separator}
|
||||
</span>
|
||||
);
|
||||
})
|
||||
|
||||
@ -8,9 +8,7 @@ import Icon from '../../components/Icon';
|
||||
import ErrorBoundary from '../../components/ErrorBoundary';
|
||||
import * as uiActions from '../../services/ui/actions';
|
||||
import * as mopidyActions from '../../services/mopidy/actions';
|
||||
import {
|
||||
formatImages,
|
||||
} from '../../util/helpers';
|
||||
import { formatImages } from '../../util/format';
|
||||
|
||||
class LibraryBrowse extends React.Component {
|
||||
componentDidMount() {
|
||||
|
||||
Reference in New Issue
Block a user