String to binary to base64 for all URIs, will fix #708 and certainly #711

This commit is contained in:
James Barnsley
2021-03-26 20:53:04 +13:00
parent 0730e6cce0
commit 20ea63b7e9
13 changed files with 163 additions and 326 deletions

View File

@ -138033,9 +138033,8 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var _services_mopidy_actions__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../services/mopidy/actions */ "./src/js/services/mopidy/actions.js"); /* harmony import */ var _services_mopidy_actions__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../services/mopidy/actions */ "./src/js/services/mopidy/actions.js");
/* harmony import */ var _services_spotify_actions__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../services/spotify/actions */ "./src/js/services/spotify/actions.js"); /* harmony import */ var _services_spotify_actions__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../services/spotify/actions */ "./src/js/services/spotify/actions.js");
/* harmony import */ var _util_arrays__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../util/arrays */ "./src/js/util/arrays.js"); /* harmony import */ var _util_arrays__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../util/arrays */ "./src/js/util/arrays.js");
/* harmony import */ var _util_helpers__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../util/helpers */ "./src/js/util/helpers.js"); /* harmony import */ var _locale__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../locale */ "./src/js/locale/index.js");
/* harmony import */ var _locale__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../locale */ "./src/js/locale/index.js"); /* harmony import */ var _util_format__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../util/format */ "./src/js/util/format.js");
/* harmony import */ var _util_format__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../util/format */ "./src/js/util/format.js");
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
@ -138068,7 +138067,6 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
var Dropzones = /*#__PURE__*/function (_React$Component) { var Dropzones = /*#__PURE__*/function (_React$Component) {
_inherits(Dropzones, _React$Component); _inherits(Dropzones, _React$Component);
@ -138110,7 +138108,7 @@ var Dropzones = /*#__PURE__*/function (_React$Component) {
break; break;
case 'add_to_playlist': case 'add_to_playlist':
history.push("/add-to-playlist/".concat(Object(_util_format__WEBPACK_IMPORTED_MODULE_11__["encodeUri"])(uris.join(',')))); // uris history.push("/add-to-playlist/".concat(Object(_util_format__WEBPACK_IMPORTED_MODULE_10__["encodeUri"])(uris.join(',')))); // uris
break; break;
@ -138141,15 +138139,15 @@ var Dropzones = /*#__PURE__*/function (_React$Component) {
}); });
_this._zones = [{ _this._zones = [{
title: Object(_locale__WEBPACK_IMPORTED_MODULE_10__["i18n"])('actions.add_to_queue'), title: Object(_locale__WEBPACK_IMPORTED_MODULE_9__["i18n"])('actions.add_to_queue'),
icon: 'play_arrow', icon: 'play_arrow',
action: 'enqueue' action: 'enqueue'
}, { }, {
title: Object(_locale__WEBPACK_IMPORTED_MODULE_10__["i18n"])('actions.play_next'), title: Object(_locale__WEBPACK_IMPORTED_MODULE_9__["i18n"])('actions.play_next'),
icon: 'play_arrow', icon: 'play_arrow',
action: 'enqueue_next' action: 'enqueue_next'
}, { }, {
title: Object(_locale__WEBPACK_IMPORTED_MODULE_10__["i18n"])('actions.add_to_playlist'), title: Object(_locale__WEBPACK_IMPORTED_MODULE_9__["i18n"])('actions.add_to_playlist'),
icon: 'playlist_add', icon: 'playlist_add',
action: 'add_to_playlist', action: 'add_to_playlist',
accepts: ['tltrack', 'track', 'album', 'playlist', 'artist'] accepts: ['tltrack', 'track', 'album', 'playlist', 'artist']
@ -138160,7 +138158,7 @@ var Dropzones = /*#__PURE__*/function (_React$Component) {
return Dropzones; return Dropzones;
}(react__WEBPACK_IMPORTED_MODULE_0___default.a.Component); }(react__WEBPACK_IMPORTED_MODULE_0___default.a.Component);
var mapStateToProps = function mapStateToProps(state, ownProps) { var mapStateToProps = function mapStateToProps(state) {
return { return {
dragger: state.ui.dragger dragger: state.ui.dragger
}; };
@ -141842,6 +141840,8 @@ var updateScrollPosition = function updateScrollPosition(_ref) {
var Link = function Link(_ref2) { var Link = function Link(_ref2) {
var _history$location;
var retainScroll = _ref2.retainScroll, var retainScroll = _ref2.retainScroll,
scrollTarget = _ref2.scrollTo, scrollTarget = _ref2.scrollTo,
onContextMenu = _ref2.onContextMenu, onContextMenu = _ref2.onContextMenu,
@ -141870,9 +141870,8 @@ var Link = function Link(_ref2) {
// they're otherwise identical // they're otherwise identical
var link = Object(_util_format__WEBPACK_IMPORTED_MODULE_3__["decodeUri"])(to); var currentLink = (history === null || history === void 0 ? void 0 : (_history$location = history.location) === null || _history$location === void 0 ? void 0 : _history$location.pathname) || '';
var currentLink = Object(_util_format__WEBPACK_IMPORTED_MODULE_3__["decodeUri"])(history.location.pathname); var isLinkActive = exact ? currentLink === to : currentLink.startsWith(to); // We have an active detector method
var isLinkActive = exact ? currentLink === link : currentLink.startsWith(link); // We have an active detector method
// This is used almost solely by the Sidebar navigation // This is used almost solely by the Sidebar navigation
var active = history && isLinkActive ? activeClassName || 'active' : ''; var active = history && isLinkActive ? activeClassName || 'active' : '';
@ -153856,11 +153855,10 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var js_sha256__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(js_sha256__WEBPACK_IMPORTED_MODULE_2__); /* harmony import */ var js_sha256__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(js_sha256__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! lodash */ "./node_modules/lodash/lodash.js"); /* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! lodash */ "./node_modules/lodash/lodash.js");
/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_3__); /* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var _sentry_utils__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @sentry/utils */ "./node_modules/@sentry/utils/esm/index.js"); /* harmony import */ var _locale__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../locale */ "./src/js/locale/index.js");
/* harmony import */ var _locale__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../locale */ "./src/js/locale/index.js"); /* harmony import */ var _util_helpers__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../util/helpers */ "./src/js/util/helpers.js");
/* harmony import */ var _util_helpers__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../util/helpers */ "./src/js/util/helpers.js"); /* harmony import */ var _util_format__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../util/format */ "./src/js/util/format.js");
/* harmony import */ var _util_format__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../util/format */ "./src/js/util/format.js"); /* harmony import */ var _util_arrays__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../util/arrays */ "./src/js/util/arrays.js");
/* harmony import */ var _util_arrays__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../util/arrays */ "./src/js/util/arrays.js");
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@ -153888,7 +153886,6 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
var mopidyActions = __webpack_require__(/*! ./actions.js */ "./src/js/services/mopidy/actions.js"); var mopidyActions = __webpack_require__(/*! ./actions.js */ "./src/js/services/mopidy/actions.js");
var coreActions = __webpack_require__(/*! ../core/actions.js */ "./src/js/services/core/actions.js"); var coreActions = __webpack_require__(/*! ../core/actions.js */ "./src/js/services/core/actions.js");
@ -154073,7 +154070,7 @@ var MopidyMiddleware = function () {
var request = function request(store, call) { var request = function request(store, call) {
var value = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var value = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
var loaderId = Object(_util_helpers__WEBPACK_IMPORTED_MODULE_6__["generateGuid"])(); var loaderId = Object(_util_helpers__WEBPACK_IMPORTED_MODULE_5__["generateGuid"])();
var loaderKey = "mopidy_".concat(call); var loaderKey = "mopidy_".concat(call);
store.dispatch(uiActions.startLoading(loaderId, loaderKey)); store.dispatch(uiActions.startLoading(loaderId, loaderKey));
@ -154144,8 +154141,8 @@ var MopidyMiddleware = function () {
} }
store.dispatch(uiActions.updateProcess(processKey, { store.dispatch(uiActions.updateProcess(processKey, {
content: Object(_locale__WEBPACK_IMPORTED_MODULE_5__["i18n"])('services.mopidy.searching', { content: Object(_locale__WEBPACK_IMPORTED_MODULE_4__["i18n"])('services.mopidy.searching', {
provider: Object(_util_helpers__WEBPACK_IMPORTED_MODULE_6__["titleCase"])(uri_scheme.replace(':', '')), provider: Object(_util_helpers__WEBPACK_IMPORTED_MODULE_5__["titleCase"])(uri_scheme.replace(':', '')),
type: requestType type: requestType
}), }),
remaining: queue.length remaining: queue.length
@ -154159,7 +154156,7 @@ var MopidyMiddleware = function () {
if (result.albums) { if (result.albums) {
result.albums.forEach(function (album) { result.albums.forEach(function (album) {
if (album.uri) { if (album.uri) {
albums[album.uri] = _objectSpread(_objectSpread({}, albums[album.uri]), Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatAlbum"])(album)); albums[album.uri] = _objectSpread(_objectSpread({}, albums[album.uri]), Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatAlbum"])(album));
} }
}); });
} }
@ -154167,12 +154164,12 @@ var MopidyMiddleware = function () {
if (result.tracks) { if (result.tracks) {
result.tracks.forEach(function (track) { result.tracks.forEach(function (track) {
if (track.album && track.album.uri) { if (track.album && track.album.uri) {
albums[track.album.uri] = _objectSpread(_objectSpread({}, albums[track.album.uri]), Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatAlbum"])(track.album)); albums[track.album.uri] = _objectSpread(_objectSpread({}, albums[track.album.uri]), Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatAlbum"])(track.album));
} }
}); });
} }
return Object(_util_arrays__WEBPACK_IMPORTED_MODULE_8__["indexToArray"])(albums); return Object(_util_arrays__WEBPACK_IMPORTED_MODULE_7__["indexToArray"])(albums);
}, },
artists: function artists(response) { artists: function artists(response) {
var result = response[0]; var result = response[0];
@ -154181,7 +154178,7 @@ var MopidyMiddleware = function () {
if (result.artists) { if (result.artists) {
result.artists.forEach(function (artist) { result.artists.forEach(function (artist) {
if (artist.uri) { if (artist.uri) {
artists[artist.uri] = _objectSpread(_objectSpread({}, artists[artist.uri]), Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatArtist"])(artist)); artists[artist.uri] = _objectSpread(_objectSpread({}, artists[artist.uri]), Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatArtist"])(artist));
} }
}); });
} }
@ -154191,14 +154188,14 @@ var MopidyMiddleware = function () {
if (track.artists) { if (track.artists) {
track.artists.forEach(function (artist) { track.artists.forEach(function (artist) {
if (artist && artist.uri) { if (artist && artist.uri) {
artists[artist.uri] = _objectSpread(_objectSpread({}, artists[artist.uri]), Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatArtist"])(artist)); artists[artist.uri] = _objectSpread(_objectSpread({}, artists[artist.uri]), Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatArtist"])(artist));
} }
}); });
} }
}); });
} }
return Object(_util_arrays__WEBPACK_IMPORTED_MODULE_8__["indexToArray"])(artists); return Object(_util_arrays__WEBPACK_IMPORTED_MODULE_7__["indexToArray"])(artists);
}, },
playlists: function playlists(response) { playlists: function playlists(response) {
var playlists = response.filter(function (item) { var playlists = response.filter(function (item) {
@ -154206,15 +154203,15 @@ var MopidyMiddleware = function () {
return item.name.toLowerCase().includes(term.toLowerCase()); return item.name.toLowerCase().includes(term.toLowerCase());
}); });
return playlists.map(function (playlist) { return playlists.map(function (playlist) {
return _objectSpread(_objectSpread({}, Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatPlaylist"])(playlist)), {}, { return _objectSpread(_objectSpread({}, Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatPlaylist"])(playlist)), {}, {
uri: Object(_util_helpers__WEBPACK_IMPORTED_MODULE_6__["encodeMopidyUri"])(playlist.uri) uri: playlist.uri
}); });
}); });
}, },
tracks: function tracks(response) { tracks: function tracks(response) {
var _response$0$tracks = response[0].tracks, var _response$0$tracks = response[0].tracks,
tracks = _response$0$tracks === void 0 ? [] : _response$0$tracks; tracks = _response$0$tracks === void 0 ? [] : _response$0$tracks;
return Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatTracks"])(tracks); return Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatTracks"])(tracks);
} }
}; };
request(store, method, data).then(function (response) { request(store, method, data).then(function (response) {
@ -154284,7 +154281,7 @@ var MopidyMiddleware = function () {
break; break;
case 'MOPIDY_DISCONNECTED': case 'MOPIDY_DISCONNECTED':
Object(_util_helpers__WEBPACK_IMPORTED_MODULE_6__["setFavicon"])('favicon_error.png'); Object(_util_helpers__WEBPACK_IMPORTED_MODULE_5__["setFavicon"])('favicon_error.png');
break; break;
case 'MOPIDY_DEBUG': case 'MOPIDY_DEBUG':
@ -154374,9 +154371,9 @@ var MopidyMiddleware = function () {
store.dispatch(uiActions.setWindowTitle(null, action.play_state)); store.dispatch(uiActions.setWindowTitle(null, action.play_state));
if (action.play_state == 'playing') { if (action.play_state == 'playing') {
Object(_util_helpers__WEBPACK_IMPORTED_MODULE_6__["setFavicon"])('favicon.png'); Object(_util_helpers__WEBPACK_IMPORTED_MODULE_5__["setFavicon"])('favicon.png');
} else { } else {
Object(_util_helpers__WEBPACK_IMPORTED_MODULE_6__["setFavicon"])('favicon_paused.png'); Object(_util_helpers__WEBPACK_IMPORTED_MODULE_5__["setFavicon"])('favicon_paused.png');
} }
next(action); next(action);
@ -154401,7 +154398,7 @@ var MopidyMiddleware = function () {
store.dispatch(pusherActions.deliverBroadcast('notification', { store.dispatch(pusherActions.deliverBroadcast('notification', {
notification: { notification: {
content: "".concat(store.getState().pusher.username + (store.getState().mopidy.play_state == 'paused' ? ' resumed' : ' started'), " playback"), content: "".concat(store.getState().pusher.username + (store.getState().mopidy.play_state == 'paused' ? ' resumed' : ' started'), " playback"),
icon: store.getState().core.current_track ? Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["getTrackIcon"])(store.getState().core.current_track, store.getState().core) : false icon: store.getState().core.current_track ? Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["getTrackIcon"])(store.getState().core.current_track, store.getState().core) : false
} }
})); }));
break; break;
@ -154415,7 +154412,7 @@ var MopidyMiddleware = function () {
store.dispatch(pusherActions.deliverBroadcast('notification', { store.dispatch(pusherActions.deliverBroadcast('notification', {
notification: { notification: {
content: "".concat(store.getState().pusher.username, " paused playback"), content: "".concat(store.getState().pusher.username, " paused playback"),
icon: store.getState().core.current_track ? Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["getTrackIcon"])(store.getState().core.current_track, store.getState().core) : false icon: store.getState().core.current_track ? Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["getTrackIcon"])(store.getState().core.current_track, store.getState().core) : false
} }
})); }));
}); });
@ -154434,7 +154431,7 @@ var MopidyMiddleware = function () {
store.dispatch(pusherActions.deliverBroadcast('notification', { store.dispatch(pusherActions.deliverBroadcast('notification', {
notification: { notification: {
content: "".concat(store.getState().pusher.username, " skipped \"").concat(store.getState().core.current_track.name, "\""), content: "".concat(store.getState().pusher.username, " skipped \"").concat(store.getState().core.current_track.name, "\""),
icon: store.getState().core.current_track ? Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["getTrackIcon"])(store.getState().core.current_track, store.getState().core) : false icon: store.getState().core.current_track ? Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["getTrackIcon"])(store.getState().core.current_track, store.getState().core) : false
} }
})); }));
}); });
@ -154446,7 +154443,7 @@ var MopidyMiddleware = function () {
store.dispatch(pusherActions.deliverBroadcast('notification', { store.dispatch(pusherActions.deliverBroadcast('notification', {
notification: { notification: {
content: "".concat(store.getState().pusher.username, " stopped playback"), content: "".concat(store.getState().pusher.username, " stopped playback"),
icon: store.getState().core.current_track ? Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["getTrackIcon"])(store.getState().core.current_track, store.getState().core) : false icon: store.getState().core.current_track ? Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["getTrackIcon"])(store.getState().core.current_track, store.getState().core) : false
} }
})); }));
}); });
@ -154613,7 +154610,7 @@ var MopidyMiddleware = function () {
var playlist = store.getState().core.items[action.uri]; var playlist = store.getState().core.items[action.uri];
if (playlist && playlist.tracks) { if (playlist && playlist.tracks) {
store.dispatch(mopidyActions.playURIs(Object(_util_arrays__WEBPACK_IMPORTED_MODULE_8__["arrayOf"])('uri', playlist.tracks), action.uri, action.shuffle)); store.dispatch(mopidyActions.playURIs(Object(_util_arrays__WEBPACK_IMPORTED_MODULE_7__["arrayOf"])('uri', playlist.tracks), action.uri, action.shuffle));
break; break;
} }
@ -154632,7 +154629,7 @@ var MopidyMiddleware = function () {
var _playlist = store.getState().core.items[action.uri]; var _playlist = store.getState().core.items[action.uri];
if (_playlist && _playlist.tracks) { if (_playlist && _playlist.tracks) {
store.dispatch(mopidyActions.enqueueURIs(Object(_util_arrays__WEBPACK_IMPORTED_MODULE_8__["arrayOf"])('uri', _playlist.tracks), action.uri, action.shuffle)); store.dispatch(mopidyActions.enqueueURIs(Object(_util_arrays__WEBPACK_IMPORTED_MODULE_7__["arrayOf"])('uri', _playlist.tracks), action.uri, action.shuffle));
break; break;
} }
@ -154676,7 +154673,7 @@ var MopidyMiddleware = function () {
} }
store.dispatch(uiActions.startProcess(action.type, { store.dispatch(uiActions.startProcess(action.type, {
content: Object(_locale__WEBPACK_IMPORTED_MODULE_5__["i18n"])('services.mopidy.adding_uris', { content: Object(_locale__WEBPACK_IMPORTED_MODULE_4__["i18n"])('services.mopidy.adding_uris', {
count: remaining count: remaining
}), }),
remaining: remaining, remaining: remaining,
@ -154684,11 +154681,11 @@ var MopidyMiddleware = function () {
})); }));
store.dispatch(pusherActions.deliverBroadcast('notification', { store.dispatch(pusherActions.deliverBroadcast('notification', {
notification: { notification: {
content: Object(_locale__WEBPACK_IMPORTED_MODULE_5__["i18n"])('services.mopidy.adding_uris_broadcast', { content: Object(_locale__WEBPACK_IMPORTED_MODULE_4__["i18n"])('services.mopidy.adding_uris_broadcast', {
username: store.getState().pusher.username, username: store.getState().pusher.username,
count: remaining count: remaining
}), }),
icon: store.getState().core.current_track ? Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["getTrackIcon"])(store.getState().core.current_track, store.getState().core) : false icon: store.getState().core.current_track ? Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["getTrackIcon"])(store.getState().core.current_track, store.getState().core) : false
} }
})); // Prepare our URIS into batches. This allows performance gain of several URIs at once })); // Prepare our URIS into batches. This allows performance gain of several URIs at once
// (which is a blocking request), but not so many that it locks the Mopidy server. // (which is a blocking request), but not so many that it locks the Mopidy server.
@ -154726,7 +154723,7 @@ var MopidyMiddleware = function () {
if (at_position !== null) at_position += uris.length; if (at_position !== null) at_position += uris.length;
store.dispatch(uiActions.updateProcess(action.type, { store.dispatch(uiActions.updateProcess(action.type, {
remaining: remaining, remaining: remaining,
content: Object(_locale__WEBPACK_IMPORTED_MODULE_5__["i18n"])('services.mopidy.adding_uris', { content: Object(_locale__WEBPACK_IMPORTED_MODULE_4__["i18n"])('services.mopidy.adding_uris', {
count: remaining count: remaining
}) })
})); }));
@ -154758,7 +154755,7 @@ var MopidyMiddleware = function () {
} }
if (action.shuffle) { if (action.shuffle) {
urisToPlay = Object(_util_arrays__WEBPACK_IMPORTED_MODULE_8__["shuffle"])(urisToPlay); urisToPlay = Object(_util_arrays__WEBPACK_IMPORTED_MODULE_7__["shuffle"])(urisToPlay);
} // Stop the radio } // Stop the radio
@ -154908,7 +154905,7 @@ var MopidyMiddleware = function () {
if (_queue.length) { if (_queue.length) {
store.dispatch(uiActions.startProcess(action.type, { store.dispatch(uiActions.startProcess(action.type, {
content: Object(_locale__WEBPACK_IMPORTED_MODULE_5__["i18n"])('services.mopidy.searching'), content: Object(_locale__WEBPACK_IMPORTED_MODULE_4__["i18n"])('services.mopidy.searching'),
total: _queue.length, total: _queue.length,
remaining: _queue.length remaining: _queue.length
})); }));
@ -154925,7 +154922,7 @@ var MopidyMiddleware = function () {
uris: uris uris: uris
}).then(function (response) { }).then(function (response) {
if (!response) return; if (!response) return;
Object(_util_arrays__WEBPACK_IMPORTED_MODULE_8__["indexToArray"])(response).forEach(function (item) { Object(_util_arrays__WEBPACK_IMPORTED_MODULE_7__["indexToArray"])(response).forEach(function (item) {
store.dispatch(coreActions["load".concat(item.___model__)](item.uri)); store.dispatch(coreActions["load".concat(item.___model__)](item.uri));
}); });
}); });
@ -154937,7 +154934,7 @@ var MopidyMiddleware = function () {
uri: action.uri uri: action.uri
}).then(function (response) { }).then(function (response) {
if (!response) return; if (!response) return;
var playlist = Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatPlaylist"])(_objectSpread(_objectSpread({ var playlist = Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatPlaylist"])(_objectSpread(_objectSpread({
images: {} images: {}
}, response), {}, { }, response), {}, {
type: 'playlist', type: 'playlist',
@ -154947,13 +154944,13 @@ var MopidyMiddleware = function () {
if (response.tracks) { if (response.tracks) {
request(store, 'library.lookup', { request(store, 'library.lookup', {
uris: Object(_util_arrays__WEBPACK_IMPORTED_MODULE_8__["arrayOf"])('uri', response.tracks) uris: Object(_util_arrays__WEBPACK_IMPORTED_MODULE_7__["arrayOf"])('uri', response.tracks)
}).then(function (tracksResponse) { }).then(function (tracksResponse) {
var tracks = response.tracks.map(function (simpleTrack) { var tracks = response.tracks.map(function (simpleTrack) {
var fullTracks = tracksResponse[simpleTrack.uri]; var fullTracks = tracksResponse[simpleTrack.uri];
return _objectSpread(_objectSpread({}, simpleTrack), fullTracks.length ? fullTracks[0] : {}); return _objectSpread(_objectSpread({}, simpleTrack), fullTracks.length ? fullTracks[0] : {});
}); });
playlist.tracks = Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["injectSortId"])(Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatTracks"])(tracks)); playlist.tracks = Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["injectSortId"])(Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatTracks"])(tracks));
store.dispatch(coreActions.itemLoaded(playlist)); store.dispatch(coreActions.itemLoaded(playlist));
}); });
} else { } else {
@ -154967,7 +154964,7 @@ var MopidyMiddleware = function () {
uri: action.key uri: action.key
}).then(function (response) { }).then(function (response) {
if (!response) { if (!response) {
store.dispatch(coreActions.handleException(Object(_locale__WEBPACK_IMPORTED_MODULE_5__["i18n"])('errors.uri_not_found', { store.dispatch(coreActions.handleException(Object(_locale__WEBPACK_IMPORTED_MODULE_4__["i18n"])('errors.uri_not_found', {
uri: action.key uri: action.key
}))); })));
return; return;
@ -155117,14 +155114,14 @@ var MopidyMiddleware = function () {
name: action.name, name: action.name,
uri_scheme: action.scheme uri_scheme: action.scheme
}).then(function (response) { }).then(function (response) {
var playlist = Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatPlaylist"])(_objectSpread(_objectSpread(_objectSpread({}, response), action), {}, { var playlist = Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatPlaylist"])(_objectSpread(_objectSpread(_objectSpread({}, response), action), {}, {
can_edit: true, can_edit: true,
type: 'playlist', type: 'playlist',
provider: 'mopidy' provider: 'mopidy'
})); }));
store.dispatch(uiActions.createNotification({ store.dispatch(uiActions.createNotification({
content: Object(_locale__WEBPACK_IMPORTED_MODULE_5__["i18n"])('actions.created', { content: Object(_locale__WEBPACK_IMPORTED_MODULE_4__["i18n"])('actions.created', {
name: Object(_locale__WEBPACK_IMPORTED_MODULE_5__["i18n"])('playlist.title') name: Object(_locale__WEBPACK_IMPORTED_MODULE_4__["i18n"])('playlist.title')
}) })
})); }));
store.dispatch(coreActions.addToLibrary('mopidy:library:playlists', playlist)); store.dispatch(coreActions.addToLibrary('mopidy:library:playlists', playlist));
@ -155136,8 +155133,8 @@ var MopidyMiddleware = function () {
uri: action.uri uri: action.uri
}).then(function () { }).then(function () {
store.dispatch(uiActions.createNotification({ store.dispatch(uiActions.createNotification({
content: Object(_locale__WEBPACK_IMPORTED_MODULE_5__["i18n"])('actions.deleted', { content: Object(_locale__WEBPACK_IMPORTED_MODULE_4__["i18n"])('actions.deleted', {
name: Object(_locale__WEBPACK_IMPORTED_MODULE_5__["i18n"])('playlist.title') name: Object(_locale__WEBPACK_IMPORTED_MODULE_4__["i18n"])('playlist.title')
}) })
})); }));
store.dispatch(coreActions.removeFromLibrary('mopidy:library:playlists', action.uri)); store.dispatch(coreActions.removeFromLibrary('mopidy:library:playlists', action.uri));
@ -155152,12 +155149,12 @@ var MopidyMiddleware = function () {
if (!_response) return; if (!_response) return;
var response = _response[uri]; var response = _response[uri];
if (!response || !response.length) return; if (!response || !response.length) return;
response = Object(_util_arrays__WEBPACK_IMPORTED_MODULE_8__["sortItems"])(response, 'track_number'); response = Object(_util_arrays__WEBPACK_IMPORTED_MODULE_7__["sortItems"])(response, 'track_number');
var album = _objectSpread(_objectSpread({}, response[0].album), {}, { var album = _objectSpread(_objectSpread({}, response[0].album), {}, {
source: 'local', source: 'local',
artists: Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatArtists"])(response[0].artists), artists: Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatArtists"])(response[0].artists),
tracks: Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatTracks"])(response) tracks: Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatTracks"])(response)
}); });
store.dispatch(coreActions.itemLoaded(album)); store.dispatch(coreActions.itemLoaded(album));
@ -155181,7 +155178,7 @@ var MopidyMiddleware = function () {
for (var _i5 = 0; _i5 < response.length; _i5++) { for (var _i5 = 0; _i5 < response.length; _i5++) {
if (response[_i5].album) { if (response[_i5].album) {
(function () { (function () {
var album = _objectSpread(_objectSpread({}, Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatAlbum"])(response[_i5].album)), {}, { var album = _objectSpread(_objectSpread({}, Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatAlbum"])(response[_i5].album)), {}, {
uri: response[_i5].album.uri uri: response[_i5].album.uri
}); });
@ -155218,9 +155215,9 @@ var MopidyMiddleware = function () {
var artist = _objectSpread({ var artist = _objectSpread({
uri: action.uri, uri: action.uri,
provider: 'mopidy', provider: 'mopidy',
albums_uris: Object(_util_arrays__WEBPACK_IMPORTED_MODULE_8__["arrayOf"])('uri', albums), albums_uris: Object(_util_arrays__WEBPACK_IMPORTED_MODULE_7__["arrayOf"])('uri', albums),
tracks: Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatTracks"])(response) tracks: Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatTracks"])(response)
}, raw_artist ? Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatArtist"])(raw_artist) : {}); }, raw_artist ? Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatArtist"])(raw_artist) : {});
store.dispatch(coreActions.itemLoaded(artist)); // We may not have a raw_artist if the tracks' artist is not found (ie the requested store.dispatch(coreActions.itemLoaded(artist)); // We may not have a raw_artist if the tracks' artist is not found (ie the requested
// artist may be the albumartist). // artist may be the albumartist).
@ -155267,7 +155264,7 @@ var MopidyMiddleware = function () {
case 'MOPIDY_CURRENT_TRACK_LOADED': case 'MOPIDY_CURRENT_TRACK_LOADED':
{ {
store.dispatch(uiActions.setCurrentTrackTransition(false)); store.dispatch(uiActions.setCurrentTrackTransition(false));
var track = Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatTrack"])(action.tl_track); var track = Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatTrack"])(action.tl_track);
if (track.uri) { if (track.uri) {
store.dispatch({ store.dispatch({
@ -155288,7 +155285,7 @@ var MopidyMiddleware = function () {
if (response && response >= 0) { if (response && response >= 0) {
// Get the full track object from our tracklist // Get the full track object from our tracklist
// We know it will be here, as the tlid refers to an item in this list // We know it will be here, as the tlid refers to an item in this list
var _track = Object(_util_arrays__WEBPACK_IMPORTED_MODULE_8__["applyFilter"])('tlid', response, store.getState().core.queue, true); var _track = Object(_util_arrays__WEBPACK_IMPORTED_MODULE_7__["applyFilter"])('tlid', response, store.getState().core.queue, true);
if (_track && _track.uri) { if (_track && _track.uri) {
store.dispatch({ store.dispatch({
@ -155313,11 +155310,11 @@ var MopidyMiddleware = function () {
uris: _uris uris: _uris
}).then(function (_response) { }).then(function (_response) {
if (!_response) return; if (!_response) return;
var tracks = Object(lodash__WEBPACK_IMPORTED_MODULE_3__["compact"])(Object(_util_arrays__WEBPACK_IMPORTED_MODULE_8__["indexToArray"])(_response).map(function (results) { var tracks = Object(lodash__WEBPACK_IMPORTED_MODULE_3__["compact"])(Object(_util_arrays__WEBPACK_IMPORTED_MODULE_7__["indexToArray"])(_response).map(function (results) {
return results.length ? Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatTrack"])(results[0]) : null; return results.length ? Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatTrack"])(results[0]) : null;
})); }));
store.dispatch(coreActions.itemsLoaded(tracks)); store.dispatch(coreActions.itemsLoaded(tracks));
store.dispatch(mopidyActions.getImages(Object(_util_arrays__WEBPACK_IMPORTED_MODULE_8__["arrayOf"])('uri', tracks))); store.dispatch(mopidyActions.getImages(Object(_util_arrays__WEBPACK_IMPORTED_MODULE_7__["arrayOf"])('uri', tracks)));
tracks.forEach(function (track) { tracks.forEach(function (track) {
if (full) { if (full) {
if (store.getState().lastfm.authorization) { if (store.getState().lastfm.authorization) {
@ -155347,12 +155344,12 @@ var MopidyMiddleware = function () {
uri: 'local:directory?type=track' uri: 'local:directory?type=track'
}).then(function (_response) { }).then(function (_response) {
if (!_response || !_response.length) return; if (!_response || !_response.length) return;
var uris = Object(lodash__WEBPACK_IMPORTED_MODULE_3__["sampleSize"])(Object(_util_arrays__WEBPACK_IMPORTED_MODULE_8__["arrayOf"])('uri', _response), action.limit); var uris = Object(lodash__WEBPACK_IMPORTED_MODULE_3__["sampleSize"])(Object(_util_arrays__WEBPACK_IMPORTED_MODULE_7__["arrayOf"])('uri', _response), action.limit);
request(store, 'library.lookup', { request(store, 'library.lookup', {
uris: uris uris: uris
}).then(function (_response) { }).then(function (_response) {
if (!_response) return; if (!_response) return;
var random_tracks = Object(_util_arrays__WEBPACK_IMPORTED_MODULE_8__["indexToArray"])(_response).map(function (results) { var random_tracks = Object(_util_arrays__WEBPACK_IMPORTED_MODULE_7__["indexToArray"])(_response).map(function (results) {
return results[0]; return results[0];
}); });
var view = store.getState().core.view || {}; var view = store.getState().core.view || {};
@ -155378,7 +155375,7 @@ var MopidyMiddleware = function () {
if (images) { if (images) {
itemsWithImages.push({ itemsWithImages.push({
uri: uri, uri: uri,
images: Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatImages"])(Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["digestMopidyImages"])(store.getState().mopidy, images)) images: Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatImages"])(Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["digestMopidyImages"])(store.getState().mopidy, images))
}); });
} else { } else {
store.dispatch(lastfmActions.getImages(uri)); store.dispatch(lastfmActions.getImages(uri));
@ -155407,14 +155404,14 @@ var MopidyMiddleware = function () {
var subdirectoryImagesToLoad = []; var subdirectoryImagesToLoad = [];
results.forEach(function (item) { results.forEach(function (item) {
if (item.__model__ === 'Track') { if (item.__model__ === 'Track') {
tracks.push(Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatTrack"])(item)); tracks.push(Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatTrack"])(item));
} else if (item.__model__ === 'Ref' && item.type === 'track') { } else if (item.__model__ === 'Ref' && item.type === 'track') {
tracks.push(Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatTrack"])(_objectSpread(_objectSpread({}, item), {}, { tracks.push(Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatTrack"])(_objectSpread(_objectSpread({}, item), {}, {
loading: true loading: true
}))); })));
trackUrisToLoad.push(item.uri); trackUrisToLoad.push(item.uri);
} else if (item.__model__ === 'Ref' && item.type === 'album') { } else if (item.__model__ === 'Ref' && item.type === 'album') {
subdirectories.push(Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatAlbum"])(_objectSpread(_objectSpread({}, item), {}, { subdirectories.push(Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatAlbum"])(_objectSpread(_objectSpread({}, item), {}, {
loading: true loading: true
}))); })));
subdirectoryImagesToLoad.push(item.uri); subdirectoryImagesToLoad.push(item.uri);
@ -155437,7 +155434,7 @@ var MopidyMiddleware = function () {
uris: trackUrisToLoad uris: trackUrisToLoad
}).then(function (response) { }).then(function (response) {
var fullTrackObjects = Object.values(response).map(function (t) { var fullTrackObjects = Object.values(response).map(function (t) {
return t.length > 0 ? Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatTrack"])(t[0]) : undefined; return t.length > 0 ? Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatTrack"])(t[0]) : undefined;
}); });
store.dispatch({ store.dispatch({
type: 'MOPIDY_DIRECTORY_LOADED', type: 'MOPIDY_DIRECTORY_LOADED',
@ -155459,7 +155456,7 @@ var MopidyMiddleware = function () {
var images = response[subdir.uri] || undefined; var images = response[subdir.uri] || undefined;
if (images) { if (images) {
images = Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatImages"])(Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["digestMopidyImages"])(store.getState().mopidy, images)); images = Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatImages"])(Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["digestMopidyImages"])(store.getState().mopidy, images));
} }
return _objectSpread(_objectSpread({}, subdir), {}, { return _objectSpread(_objectSpread({}, subdir), {}, {
@ -155540,14 +155537,14 @@ var MopidyMiddleware = function () {
var response = raw_response.map(function (artist) { var response = raw_response.map(function (artist) {
return _objectSpread(_objectSpread({}, Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatArtist"])(artist)), {}, { return _objectSpread(_objectSpread({}, Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatArtist"])(artist)), {}, {
uri: artist.uri.replace('local:directory?albumartist=', '').replace('local:directory?artist=', '') uri: artist.uri.replace('local:directory?albumartist=', '').replace('local:directory?artist=', '')
}); });
}); });
store.dispatch(coreActions.itemsLoaded(response)); store.dispatch(coreActions.itemsLoaded(response));
store.dispatch(coreActions.libraryLoaded({ store.dispatch(coreActions.libraryLoaded({
uri: 'mopidy:library:artists', uri: 'mopidy:library:artists',
items_uris: Object(_util_arrays__WEBPACK_IMPORTED_MODULE_8__["arrayOf"])('uri', response) items_uris: Object(_util_arrays__WEBPACK_IMPORTED_MODULE_7__["arrayOf"])('uri', response)
})); }));
store.dispatch(uiActions.processFinished(action.type)); store.dispatch(uiActions.processFinished(action.type));
}); });
@ -155560,8 +155557,8 @@ var MopidyMiddleware = function () {
})); }));
request(store, 'playlists.asList').then(function (listResponse) { request(store, 'playlists.asList').then(function (listResponse) {
// Remove any Spotify playlists. These will be handled by our Spotify API // Remove any Spotify playlists. These will be handled by our Spotify API
var playlist_uris = Object(_util_arrays__WEBPACK_IMPORTED_MODULE_8__["arrayOf"])('uri', listResponse).filter(function (playlistUri) { var playlist_uris = Object(_util_arrays__WEBPACK_IMPORTED_MODULE_7__["arrayOf"])('uri', listResponse).filter(function (playlistUri) {
return Object(_util_helpers__WEBPACK_IMPORTED_MODULE_6__["uriSource"])(playlistUri) !== 'spotify'; return Object(_util_helpers__WEBPACK_IMPORTED_MODULE_5__["uriSource"])(playlistUri) !== 'spotify';
}); });
var libraryPlaylists = []; var libraryPlaylists = [];
store.dispatch(uiActions.updateProcess(action.type, { store.dispatch(uiActions.updateProcess(action.type, {
@ -155574,10 +155571,10 @@ var MopidyMiddleware = function () {
request(store, 'playlists.lookup', { request(store, 'playlists.lookup', {
uri: uri uri: uri
}).then(function (response) { }).then(function (response) {
libraryPlaylists.push(Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatPlaylist"])({ libraryPlaylists.push(Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatPlaylist"])({
name: response.name, name: response.name,
uri: response.uri, uri: response.uri,
can_edit: Object(_util_helpers__WEBPACK_IMPORTED_MODULE_6__["uriSource"])(response.uri) === 'm3u', can_edit: Object(_util_helpers__WEBPACK_IMPORTED_MODULE_5__["uriSource"])(response.uri) === 'm3u',
last_modified: response.last_modified, last_modified: response.last_modified,
// By not including actual tracks they will be fetched when needed. We don't // By not including actual tracks they will be fetched when needed. We don't
// want these simple tracks because they don't contain duration, artist, etc. // want these simple tracks because they don't contain duration, artist, etc.
@ -155591,7 +155588,7 @@ var MopidyMiddleware = function () {
store.dispatch(coreActions.itemsLoaded(libraryPlaylists)); store.dispatch(coreActions.itemsLoaded(libraryPlaylists));
store.dispatch(coreActions.libraryLoaded({ store.dispatch(coreActions.libraryLoaded({
uri: 'mopidy:library:playlists', uri: 'mopidy:library:playlists',
items_uris: Object(_util_arrays__WEBPACK_IMPORTED_MODULE_8__["arrayOf"])('uri', libraryPlaylists) items_uris: Object(_util_arrays__WEBPACK_IMPORTED_MODULE_7__["arrayOf"])('uri', libraryPlaylists)
})); }));
store.dispatch(uiActions.processFinished(action.type)); store.dispatch(uiActions.processFinished(action.type));
} }
@ -155616,7 +155613,7 @@ var MopidyMiddleware = function () {
request(store, 'library.browse', { request(store, 'library.browse', {
uri: store.getState().mopidy.library_albums_uri uri: store.getState().mopidy.library_albums_uri
}).then(function (browseResponse) { }).then(function (browseResponse) {
var allUris = Object(_util_arrays__WEBPACK_IMPORTED_MODULE_8__["arrayOf"])('uri', browseResponse); var allUris = Object(_util_arrays__WEBPACK_IMPORTED_MODULE_7__["arrayOf"])('uri', browseResponse);
store.dispatch(uiActions.updateProcess(action.type, { store.dispatch(uiActions.updateProcess(action.type, {
remaining: allUris.length, remaining: allUris.length,
total: allUris.length total: allUris.length
@ -155640,12 +155637,12 @@ var MopidyMiddleware = function () {
request(store, 'library.lookup', { request(store, 'library.lookup', {
uris: _uris3 uris: _uris3
}).then(function (lookupResponse) { }).then(function (lookupResponse) {
var libraryItems = Object(_util_arrays__WEBPACK_IMPORTED_MODULE_8__["indexToArray"])(lookupResponse).map(function (tracks) { var libraryItems = Object(_util_arrays__WEBPACK_IMPORTED_MODULE_7__["indexToArray"])(lookupResponse).map(function (tracks) {
return _objectSpread({ return _objectSpread({
artists: tracks[0].artists ? Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatArtists"])(tracks[0].artists) : null, artists: tracks[0].artists ? Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatArtists"])(tracks[0].artists) : null,
tracks: Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatTracks"])(tracks), tracks: Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatTracks"])(tracks),
last_modified: tracks[0].last_modified last_modified: tracks[0].last_modified
}, Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatAlbum"])(tracks[0].album)); }, Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatAlbum"])(tracks[0].album));
}); });
if (libraryItems.length) { if (libraryItems.length) {
@ -155658,7 +155655,7 @@ var MopidyMiddleware = function () {
store.dispatch(uiActions.processFinished(action.type)); store.dispatch(uiActions.processFinished(action.type));
store.dispatch(coreActions.libraryLoaded({ store.dispatch(coreActions.libraryLoaded({
uri: 'mopidy:library:albums', uri: 'mopidy:library:albums',
items_uris: Object(_util_arrays__WEBPACK_IMPORTED_MODULE_8__["arrayOf"])('uri', browseResponse) items_uris: Object(_util_arrays__WEBPACK_IMPORTED_MODULE_7__["arrayOf"])('uri', browseResponse)
})); }));
} }
}; };
@ -155674,7 +155671,7 @@ var MopidyMiddleware = function () {
request(store, 'library.browse', { request(store, 'library.browse', {
uri: store.getState().mopidy.library_tracks_uri uri: store.getState().mopidy.library_tracks_uri
}).then(function (browseResponse) { }).then(function (browseResponse) {
var allUris = Object(_util_arrays__WEBPACK_IMPORTED_MODULE_8__["arrayOf"])('uri', browseResponse); var allUris = Object(_util_arrays__WEBPACK_IMPORTED_MODULE_7__["arrayOf"])('uri', browseResponse);
store.dispatch(uiActions.updateProcess(action.type, { store.dispatch(uiActions.updateProcess(action.type, {
remaining: allUris.length, remaining: allUris.length,
total: allUris.length total: allUris.length
@ -155698,8 +155695,8 @@ var MopidyMiddleware = function () {
request(store, 'library.lookup', { request(store, 'library.lookup', {
uris: _uris4 uris: _uris4
}).then(function (lookupResponse) { }).then(function (lookupResponse) {
var libraryItems = Object(lodash__WEBPACK_IMPORTED_MODULE_3__["compact"])(Object(_util_arrays__WEBPACK_IMPORTED_MODULE_8__["indexToArray"])(lookupResponse).map(function (results) { var libraryItems = Object(lodash__WEBPACK_IMPORTED_MODULE_3__["compact"])(Object(_util_arrays__WEBPACK_IMPORTED_MODULE_7__["indexToArray"])(lookupResponse).map(function (results) {
return results.length ? Object(_util_format__WEBPACK_IMPORTED_MODULE_7__["formatTrack"])(results[0]) : null; return results.length ? Object(_util_format__WEBPACK_IMPORTED_MODULE_6__["formatTrack"])(results[0]) : null;
})); }));
if (libraryItems.length) { if (libraryItems.length) {
@ -155712,7 +155709,7 @@ var MopidyMiddleware = function () {
store.dispatch(uiActions.processFinished(action.type)); store.dispatch(uiActions.processFinished(action.type));
store.dispatch(coreActions.libraryLoaded({ store.dispatch(coreActions.libraryLoaded({
uri: 'mopidy:library:tracks', uri: 'mopidy:library:tracks',
items_uris: Object(_util_arrays__WEBPACK_IMPORTED_MODULE_8__["arrayOf"])('uri', browseResponse) items_uris: Object(_util_arrays__WEBPACK_IMPORTED_MODULE_7__["arrayOf"])('uri', browseResponse)
})); }));
} }
}; };
@ -161884,7 +161881,7 @@ var shuffle = function shuffle(array) {
/*!*******************************!*\ /*!*******************************!*\
!*** ./src/js/util/format.js ***! !*** ./src/js/util/format.js ***!
\*******************************/ \*******************************/
/*! exports provided: toJSON, getTrackIcon, digestMopidyImages, formatImages, formatSimpleObject, formatSimpleObjects, formatAlbum, formatAlbums, formatArtist, formatArtists, formatPlaylist, formatPlaylists, formatUser, formatUsers, formatTrack, formatTracks, formatClient, formatGroup, formatCategory, formatCategories, collate, collateLibrary, injectSortId, encodeUri, decodeUri, encodeMopidyUri, default */ /*! exports provided: toJSON, getTrackIcon, digestMopidyImages, formatImages, formatSimpleObject, formatSimpleObjects, formatAlbum, formatAlbums, formatArtist, formatArtists, formatPlaylist, formatPlaylists, formatUser, formatUsers, formatTrack, formatTracks, formatClient, formatGroup, formatCategory, formatCategories, collate, collateLibrary, injectSortId, encodeUri, decodeUri, default */
/***/ (function(module, __webpack_exports__, __webpack_require__) { /***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict"; "use strict";
@ -161914,7 +161911,6 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "injectSortId", function() { return injectSortId; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "injectSortId", function() { return injectSortId; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "encodeUri", function() { return encodeUri; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "encodeUri", function() { return encodeUri; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "decodeUri", function() { return decodeUri; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "decodeUri", function() { return decodeUri; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "encodeMopidyUri", function() { return encodeMopidyUri; });
/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lodash */ "./node_modules/lodash/lodash.js"); /* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lodash */ "./node_modules/lodash/lodash.js");
/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./helpers */ "./src/js/util/helpers.js"); /* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./helpers */ "./src/js/util/helpers.js");
@ -162295,77 +162291,41 @@ var formatSimpleObjects = function formatSimpleObjects() {
}; };
/** /**
* Prepare a URI for use in a URL * Prepare a URI for use in a URL
*
* Simple alias to encodeURIComponent so this can be extended as needed
* @param {String} uri * @param {String} uri
*/ */
var encodeUri = function encodeUri() { var encodeUri = function encodeUri() {
var rawUri = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; var rawUri = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var uri = rawUri; // Manually encode %
// Needed because React Router History incorrectly handles '%' during encoding/decoding
// See https://github.com/jaedb/Iris/issues/674
uri = uri.replace(/%25/g, '_PRCNT_'); try {
uri = encodeURIComponent(uri); return btoa(unescape(encodeURIComponent(rawUri)));
return uri; } catch (_unused) {
console.error('Failed to encode', rawUri);
return null;
}
}; };
/** /**
* Rebuild a URI with some ugly-ass handling of encoding. * Reconstruct a URI from a URL-friendly base64 string, back into its original form
* *
* We can't just run encodeURIComponent because it will encode ':' and '/' elements which are * Why base64? Some Mopidy backends have varying encoding styles, and handling all of these became
* required to properly map to Mopidy's internal structure. Some things need encoding, and others * unweildy. Instead we take whatever Mopidy gives us, convert to binary, and then base64 it.
* need decoding *sigh*.
*
* Instead, we pluck the individual encodings as needed.
*
* For example somebackend:track:https://youtube.com/1234 would cause issues with the
* https:// section. Our explode-by-':' approach would break this type of URI.
* *
* Even when a URI is not URIEncoded, the browser will do some of it's own encoding/decoding which
* we can avoid by giving a base64 string.
* @param {String} rawUri * @param {String} rawUri
*/ */
var decodeUri = function decodeUri() { var decodeUri = function decodeUri() {
var rawUri = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; var rawUri = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var uri = rawUri;
try { try {
uri = decodeURIComponent(uri); return decodeURIComponent(escape(atob(rawUri)));
} catch (_unused) { } catch (_unused2) {
console.error('Could not decode URI', uri); console.error('Failed to decode', rawUri);
} // Some characters must be encoded for Mopidy URI compatibility return null;
}
uri = uri.replace(/%2F/g, '/'); // We need slashes
uri = uri.replace(/_PRCNT_/g, '%25'); // Decode '%'
uri = uri.replace(/!/g, '%21');
uri = uri.replace(/\*/g, '%2A');
uri = uri.replace(/\(/g, '%28');
uri = uri.replace(/\)/g, '%29');
uri = uri.replace(/\[/g, '%5B');
uri = uri.replace(/\]/g, '%5D');
uri = uri.replace(/@/g, '%40');
uri = uri.replace(/#/g, '%23');
uri = uri.replace(/\$/g, '%24');
uri = uri.replace(/&/g, '%26');
uri = uri.replace(/'/g, '%27');
uri = uri.replace(/,/g, '%2C');
uri = uri.replace(/ /g, '%20'); // Re-encode any accented characters. Most Mopidy backends expect encoding of these.
uri = uri.replace(/[À-ÖØ-öø-ÿ]/g, function (_char) {
return encodeURIComponent(_char);
});
return uri;
};
var encodeMopidyUri = function encodeMopidyUri() {
var rawUri = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var uri = rawUri;
return uri;
}; };
/** /**
* Format our album objects into a universal format * Format our album objects into a universal format
@ -162710,7 +162670,7 @@ var formatTrack = function formatTrack(data) {
track.disc_track += "".concat(track.track_number || 0).padStart(3, '0'); // Remove lower-case encoding of ':' track.disc_track += "".concat(track.track_number || 0).padStart(3, '0'); // Remove lower-case encoding of ':'
// See https://github.com/tkem/mopidy-dleyna/issues/72 // See https://github.com/tkem/mopidy-dleyna/issues/72
track.uri = decodeUri(track.uri); track.uri = track.uri.replace('%3a', '%3A');
return track; return track;
}; };
/** /**
@ -163110,8 +163070,7 @@ var injectSortId = function injectSortId(array) {
collateLibrary: collateLibrary, collateLibrary: collateLibrary,
injectSortId: injectSortId, injectSortId: injectSortId,
encodeUri: encodeUri, encodeUri: encodeUri,
decodeUri: decodeUri, decodeUri: decodeUri
encodeMopidyUri: encodeMopidyUri
}); });
/***/ }), /***/ }),
@ -163120,7 +163079,7 @@ var injectSortId = function injectSortId(array) {
/*!********************************!*\ /*!********************************!*\
!*** ./src/js/util/helpers.js ***! !*** ./src/js/util/helpers.js ***!
\********************************/ \********************************/
/*! exports provided: debounce, throttle, setFavicon, queryString, generateGuid, getCurrentPusherConnection, uriSource, uriType, sourceIcon, getFromUri, buildLink, isTouchDevice, isNumeric, isObject, isLoading, isHosted, getIndexedRecords, titleCase, scrollTo, upgradeSpotifyPlaylistUris, upgradeSpotifyPlaylistUri, iconFromKeyword, decodeMopidyUri, encodeMopidyUri, default */ /*! exports provided: debounce, throttle, setFavicon, queryString, generateGuid, getCurrentPusherConnection, uriSource, uriType, sourceIcon, getFromUri, buildLink, isTouchDevice, isNumeric, isObject, isLoading, isHosted, getIndexedRecords, titleCase, scrollTo, upgradeSpotifyPlaylistUris, upgradeSpotifyPlaylistUri, iconFromKeyword, default */
/***/ (function(module, __webpack_exports__, __webpack_require__) { /***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict"; "use strict";
@ -163147,8 +163106,6 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "upgradeSpotifyPlaylistUris", function() { return upgradeSpotifyPlaylistUris; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "upgradeSpotifyPlaylistUris", function() { return upgradeSpotifyPlaylistUris; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "upgradeSpotifyPlaylistUri", function() { return upgradeSpotifyPlaylistUri; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "upgradeSpotifyPlaylistUri", function() { return upgradeSpotifyPlaylistUri; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "iconFromKeyword", function() { return iconFromKeyword; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "iconFromKeyword", function() { return iconFromKeyword; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "decodeMopidyUri", function() { return decodeMopidyUri; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "encodeMopidyUri", function() { return encodeMopidyUri; });
/* harmony import */ var _arrays__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./arrays */ "./src/js/util/arrays.js"); /* harmony import */ var _arrays__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./arrays */ "./src/js/util/arrays.js");
/* harmony import */ var _format__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./format */ "./src/js/util/format.js"); /* harmony import */ var _format__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./format */ "./src/js/util/format.js");
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
@ -163835,48 +163792,6 @@ var upgradeSpotifyPlaylistUris = function upgradeSpotifyPlaylistUris(uris) {
var upgradeSpotifyPlaylistUri = function upgradeSpotifyPlaylistUri(uri) { var upgradeSpotifyPlaylistUri = function upgradeSpotifyPlaylistUri(uri) {
return upgradeSpotifyPlaylistUris([uri])[0]; return upgradeSpotifyPlaylistUris([uri])[0];
}; };
/**
* Decode and encode Mopidy playlist URIs
* This is needed as Mopidy encodes *some* characters in playlist URIs (but not other characters)
* We need to retain ":" because this a reserved URI separator
*/
var decodeMopidyUri = function decodeMopidyUri(uri) {
var decodeComponent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var decoded = decodeComponent ? decodeURIComponent(uri) : uri;
decoded = decoded.replace(/\s/g, '%20'); // space
decoded = decoded.replace(/\[/g, '%5B'); // [
decoded = decoded.replace(/\]/g, '%5D'); // ]
decoded = decoded.replace(/\(/g, '%28'); // (
decoded = decoded.replace(/\)/g, '%29'); // )
decoded = decoded.replace(/\#/g, '%23'); // #
return decoded;
};
var encodeMopidyUri = function encodeMopidyUri(uri) {
var encodeComponent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var encoded = encodeComponent ? encodeURIComponent(uri) : uri;
encoded = encoded.replace(/\%20/g, ' '); // space
encoded = encoded.replace(/\%5B/g, '['); // [
encoded = encoded.replace(/\%5D/g, ']'); // ]
encoded = encoded.replace(/\%28/g, '('); // (
encoded = encoded.replace(/\%29/g, ')'); // )
encoded = encoded.replace(/\%23/g, '#'); // #
return encoded;
};
/* harmony default export */ __webpack_exports__["default"] = ({ /* harmony default export */ __webpack_exports__["default"] = ({
@ -163901,9 +163816,7 @@ var encodeMopidyUri = function encodeMopidyUri(uri) {
scrollTo: scrollTo, scrollTo: scrollTo,
upgradeSpotifyPlaylistUris: upgradeSpotifyPlaylistUris, upgradeSpotifyPlaylistUris: upgradeSpotifyPlaylistUris,
upgradeSpotifyPlaylistUri: upgradeSpotifyPlaylistUri, upgradeSpotifyPlaylistUri: upgradeSpotifyPlaylistUri,
iconFromKeyword: iconFromKeyword, iconFromKeyword: iconFromKeyword
decodeMopidyUri: decodeMopidyUri,
encodeMopidyUri: encodeMopidyUri
}); });
/***/ }), /***/ }),
@ -164887,7 +164800,7 @@ var Album = /*#__PURE__*/function (_React$Component) {
}(react__WEBPACK_IMPORTED_MODULE_0___default.a.Component); }(react__WEBPACK_IMPORTED_MODULE_0___default.a.Component);
var mapStateToProps = function mapStateToProps(state, ownProps) { var mapStateToProps = function mapStateToProps(state, ownProps) {
var uri = decodeURIComponent(ownProps.match.params.uri); var uri = Object(_util_format__WEBPACK_IMPORTED_MODULE_26__["decodeUri"])(ownProps.match.params.uri);
var itemSelector = Object(_util_selectors__WEBPACK_IMPORTED_MODULE_23__["makeItemSelector"])(uri); var itemSelector = Object(_util_selectors__WEBPACK_IMPORTED_MODULE_23__["makeItemSelector"])(uri);
var loadingSelector = Object(_util_selectors__WEBPACK_IMPORTED_MODULE_23__["makeLoadingSelector"])(["(.*)".concat(uri, "(.*)"), '^((?!contains).)*$', '^((?!me\/albums).)*$']); var loadingSelector = Object(_util_selectors__WEBPACK_IMPORTED_MODULE_23__["makeLoadingSelector"])(["(.*)".concat(uri, "(.*)"), '^((?!contains).)*$', '^((?!me\/albums).)*$']);
return { return {
@ -165781,7 +165694,7 @@ var Artist = /*#__PURE__*/function (_React$Component) {
}(react__WEBPACK_IMPORTED_MODULE_0___default.a.Component); }(react__WEBPACK_IMPORTED_MODULE_0___default.a.Component);
var mapStateToProps = function mapStateToProps(state, props) { var mapStateToProps = function mapStateToProps(state, props) {
var uri = decodeURIComponent(props.match.params.uri); var uri = Object(_util_format__WEBPACK_IMPORTED_MODULE_21__["decodeUri"])(props.match.params.uri);
var loadingSelector = Object(_util_selectors__WEBPACK_IMPORTED_MODULE_26__["makeLoadingSelector"])(["(.*)".concat(uri, "(.*)"), '^((?!contains).)*$', '^((?!albums).)*$', '^((?!related-artists).)*$', '^((?!top-tracks).)*$']); var loadingSelector = Object(_util_selectors__WEBPACK_IMPORTED_MODULE_26__["makeLoadingSelector"])(["(.*)".concat(uri, "(.*)"), '^((?!contains).)*$', '^((?!albums).)*$', '^((?!related-artists).)*$', '^((?!top-tracks).)*$']);
var artistSelector = Object(_util_selectors__WEBPACK_IMPORTED_MODULE_26__["makeItemSelector"])(uri); var artistSelector = Object(_util_selectors__WEBPACK_IMPORTED_MODULE_26__["makeItemSelector"])(uri);
var artist = artistSelector(state); var artist = artistSelector(state);
@ -169825,7 +169738,7 @@ var Track = /*#__PURE__*/function (_React$Component) {
loadTrack = _this$props.coreActions.loadTrack; loadTrack = _this$props.coreActions.loadTrack;
if (prevUri !== uri) { if (prevUri !== uri) {
loadTrack(Object(_util_format__WEBPACK_IMPORTED_MODULE_24__["decodeUri"])(uri), { loadTrack(uri, {
full: true, full: true,
lyrics: true lyrics: true
}); });
@ -170075,7 +169988,7 @@ var Track = /*#__PURE__*/function (_React$Component) {
uri = _this$props5.uri, uri = _this$props5.uri,
track = _this$props5.track, track = _this$props5.track,
loadTrack = _this$props5.coreActions.loadTrack; loadTrack = _this$props5.coreActions.loadTrack;
loadTrack(Object(_util_format__WEBPACK_IMPORTED_MODULE_24__["decodeUri"])(uri), { loadTrack(uri, {
full: true, full: true,
lyrics: true lyrics: true
}); });

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -106,7 +106,7 @@
// Release details // Release details
// These are automatically injected to built HTML // These are automatically injected to built HTML
var build = "1616572568"; var build = "1616744984";
var version = "3.57.2"; var version = "3.57.2";
// Construct the script tag // Construct the script tag

View File

@ -9,7 +9,6 @@ import * as uiActions from '../../services/ui/actions';
import * as mopidyActions from '../../services/mopidy/actions'; import * as mopidyActions from '../../services/mopidy/actions';
import * as spotifyActions from '../../services/spotify/actions'; import * as spotifyActions from '../../services/spotify/actions';
import { arrayOf } from '../../util/arrays'; import { arrayOf } from '../../util/arrays';
import { decodeMopidyUri } from '../../util/helpers';
import { i18n } from '../../locale'; import { i18n } from '../../locale';
import { encodeUri } from '../../util/format'; import { encodeUri } from '../../util/format';
@ -94,7 +93,7 @@ class Dropzones extends React.Component {
} }
} }
const mapStateToProps = (state, ownProps) => ({ const mapStateToProps = (state) => ({
dragger: state.ui.dragger, dragger: state.ui.dragger,
}); });

View File

@ -11,7 +11,7 @@ const updateScrollPosition = ({
state, state,
pathname, pathname,
}, },
}) => { }) => {
// Fetch the current scroll position of our #main element and save to our history's state, so // 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. // clicking 'back' etc will restore the previous scroll position.
// This doesn't trigger lazy-load elements (unless scrolling exposes the LazyLoader component). // This doesn't trigger lazy-load elements (unless scrolling exposes the LazyLoader component).
@ -50,15 +50,14 @@ const Link = ({
if (!to) return <span className={className}>{children}</span>; if (!to) return <span className={className}>{children}</span>;
const history = useHistory(); const history = useHistory();
const location = useLocation(); const location = useLocation();
const onClick = () => updateScrollPosition({ const onClick = () => updateScrollPosition({
history, location, retainScroll, scrollTarget, history, location, retainScroll, scrollTarget,
}); });
// Decode both links. This handles issues where one link is encoded and the other isn't, but // Decode both links. This handles issues where one link is encoded and the other isn't, but
// they're otherwise identical // they're otherwise identical
const link = decodeUri(to); const currentLink = history?.location?.pathname || '';
const currentLink = decodeUri(history.location.pathname); const isLinkActive = exact ? currentLink === to : currentLink.startsWith(to);
const isLinkActive = exact ? currentLink === link : currentLink.startsWith(link);
// We have an active detector method // We have an active detector method
// This is used almost solely by the Sidebar navigation // This is used almost solely by the Sidebar navigation

View File

@ -2,14 +2,12 @@ import ReactGA from 'react-ga';
import Mopidy from 'mopidy'; import Mopidy from 'mopidy';
import { sha256 } from 'js-sha256'; import { sha256 } from 'js-sha256';
import { sampleSize, compact, chunk } from 'lodash'; import { sampleSize, compact, chunk } from 'lodash';
import { consoleSandbox } from '@sentry/utils'; import { i18n } from '../../locale';
import { i18n, I18n } from '../../locale';
import { import {
generateGuid, generateGuid,
uriSource, uriSource,
setFavicon, setFavicon,
titleCase, titleCase,
encodeMopidyUri,
} from '../../util/helpers'; } from '../../util/helpers';
import { import {
digestMopidyImages, digestMopidyImages,
@ -240,8 +238,8 @@ const MopidyMiddleware = (function () {
store.dispatch(uiActions.stopLoading(loaderId)); store.dispatch(uiActions.stopLoading(loaderId));
console.warn( console.warn(
'Mopidy request aborted. Either Mopidy is not connected or the request method is invalid. Check the request and your server settings.', 'Mopidy request aborted. Either Mopidy is not connected or the request method is invalid. Check the request and your server settings.',
{ {
call, value, socket, controller, call, value, socket, controller,
}, },
); );
} }
@ -362,7 +360,7 @@ const MopidyMiddleware = (function () {
); );
return playlists.map((playlist) => ({ return playlists.map((playlist) => ({
...formatPlaylist(playlist), ...formatPlaylist(playlist),
uri: encodeMopidyUri(playlist.uri), uri: playlist.uri,
})); }));
}, },
tracks: (response) => { tracks: (response) => {
@ -1209,7 +1207,7 @@ const MopidyMiddleware = (function () {
}); });
} else { } else {
store.dispatch(coreActions.itemLoaded(playlist)); store.dispatch(coreActions.itemLoaded(playlist));
} }
}); });
break; break;
@ -1786,7 +1784,7 @@ const MopidyMiddleware = (function () {
store.dispatch(uiActions.startProcess(action.type, { notification: false })); store.dispatch(uiActions.startProcess(action.type, { notification: false }));
request(store, 'playlists.asList') request(store, 'playlists.asList')
.then((listResponse) => { .then((listResponse) => {
// Remove any Spotify playlists. These will be handled by our Spotify API // Remove any Spotify playlists. These will be handled by our Spotify API
const playlist_uris = arrayOf('uri', listResponse).filter( const playlist_uris = arrayOf('uri', listResponse).filter(
(playlistUri) => uriSource(playlistUri) !== 'spotify', (playlistUri) => uriSource(playlistUri) !== 'spotify',

View File

@ -275,71 +275,34 @@ const formatSimpleObjects = function (records = []) {
/** /**
* Prepare a URI for use in a URL * Prepare a URI for use in a URL
*
* Simple alias to encodeURIComponent so this can be extended as needed
* @param {String} uri * @param {String} uri
*/ */
const encodeUri = (rawUri = '') => { const encodeUri = (rawUri = '') => {
let uri = rawUri; try {
return btoa(unescape(encodeURIComponent(rawUri)));
// Manually encode % } catch {
// Needed because React Router History incorrectly handles '%' during encoding/decoding console.error('Failed to encode', rawUri);
// See https://github.com/jaedb/Iris/issues/674 return null;
uri = uri.replace(/%25/g, '_PRCNT_'); }
uri = encodeURIComponent(uri);
return uri;
}; };
/** /**
* Rebuild a URI with some ugly-ass handling of encoding. * Reconstruct a URI from a URL-friendly base64 string, back into its original form
* *
* We can't just run encodeURIComponent because it will encode ':' and '/' elements which are * Why base64? Some Mopidy backends have varying encoding styles, and handling all of these became
* required to properly map to Mopidy's internal structure. Some things need encoding, and others * unweildy. Instead we take whatever Mopidy gives us, convert to binary, and then base64 it.
* need decoding *sigh*.
*
* Instead, we pluck the individual encodings as needed.
*
* For example somebackend:track:https://youtube.com/1234 would cause issues with the
* https:// section. Our explode-by-':' approach would break this type of URI.
* *
* Even when a URI is not URIEncoded, the browser will do some of it's own encoding/decoding which
* we can avoid by giving a base64 string.
* @param {String} rawUri * @param {String} rawUri
*/ */
const decodeUri = (rawUri = '') => { const decodeUri = (rawUri = '') => {
let uri = rawUri;
try { try {
uri = decodeURIComponent(uri); return decodeURIComponent(escape(atob(rawUri)));
} catch { } catch {
console.error('Could not decode URI', uri); console.error('Failed to decode', rawUri);
return null;
} }
// Some characters must be encoded for Mopidy URI compatibility
uri = uri.replace(/%2F/g, '/'); // We need slashes
uri = uri.replace(/_PRCNT_/g, '%25'); // Decode '%'
uri = uri.replace(/!/g, '%21');
uri = uri.replace(/\*/g, '%2A');
uri = uri.replace(/\(/g, '%28');
uri = uri.replace(/\)/g, '%29');
uri = uri.replace(/\[/g, '%5B');
uri = uri.replace(/\]/g, '%5D');
uri = uri.replace(/@/g, '%40');
uri = uri.replace(/#/g, '%23');
uri = uri.replace(/\$/g, '%24');
uri = uri.replace(/&/g, '%26');
uri = uri.replace(/'/g, '%27');
uri = uri.replace(/,/g, '%2C');
uri = uri.replace(/ /g, '%20');
// Re-encode any accented characters. Most Mopidy backends expect encoding of these.
uri = uri.replace(/[À-ÖØ-öø-ÿ]/g, (char) => encodeURIComponent(char));
return uri;
};
const encodeMopidyUri = (rawUri = '') => {
const uri = rawUri;
return uri;
}; };
/** /**
@ -735,7 +698,7 @@ const formatTrack = function (data) {
// Remove lower-case encoding of ':' // Remove lower-case encoding of ':'
// See https://github.com/tkem/mopidy-dleyna/issues/72 // See https://github.com/tkem/mopidy-dleyna/issues/72
track.uri = decodeUri(track.uri); track.uri = track.uri.replace('%3a', '%3A');
return track; return track;
}; };
@ -1033,7 +996,6 @@ export {
injectSortId, injectSortId,
encodeUri, encodeUri,
decodeUri, decodeUri,
encodeMopidyUri,
}; };
export default { export default {
@ -1062,5 +1024,4 @@ export default {
injectSortId, injectSortId,
encodeUri, encodeUri,
decodeUri, decodeUri,
encodeMopidyUri,
}; };

View File

@ -598,33 +598,6 @@ const upgradeSpotifyPlaylistUri = function (uri) {
return upgradeSpotifyPlaylistUris([uri])[0]; return upgradeSpotifyPlaylistUris([uri])[0];
}; };
/**
* Decode and encode Mopidy playlist URIs
* This is needed as Mopidy encodes *some* characters in playlist URIs (but not other characters)
* We need to retain ":" because this a reserved URI separator
*/
const decodeMopidyUri = (uri, decodeComponent = true) => {
let decoded = decodeComponent ? decodeURIComponent(uri) : uri;
decoded = decoded.replace(/\s/g, '%20'); // space
decoded = decoded.replace(/\[/g, '%5B'); // [
decoded = decoded.replace(/\]/g, '%5D'); // ]
decoded = decoded.replace(/\(/g, '%28'); // (
decoded = decoded.replace(/\)/g, '%29'); // )
decoded = decoded.replace(/\#/g, '%23'); // #
return decoded;
};
const encodeMopidyUri = (uri, encodeComponent = true) => {
let encoded = encodeComponent ? encodeURIComponent(uri) : uri;
encoded = encoded.replace(/\%20/g, ' '); // space
encoded = encoded.replace(/\%5B/g, '['); // [
encoded = encoded.replace(/\%5D/g, ']'); // ]
encoded = encoded.replace(/\%28/g, '('); // (
encoded = encoded.replace(/\%29/g, ')'); // )
encoded = encoded.replace(/\%23/g, '#'); // #
return encoded;
};
export { export {
debounce, debounce,
throttle, throttle,
@ -648,8 +621,6 @@ export {
upgradeSpotifyPlaylistUris, upgradeSpotifyPlaylistUris,
upgradeSpotifyPlaylistUri, upgradeSpotifyPlaylistUri,
iconFromKeyword, iconFromKeyword,
decodeMopidyUri,
encodeMopidyUri,
}; };
export default { export default {
@ -675,6 +646,4 @@ export default {
upgradeSpotifyPlaylistUris, upgradeSpotifyPlaylistUris,
upgradeSpotifyPlaylistUri, upgradeSpotifyPlaylistUri,
iconFromKeyword, iconFromKeyword,
decodeMopidyUri, };
encodeMopidyUri,
};

View File

@ -28,7 +28,7 @@ import Button from '../components/Button';
import { makeLoadingSelector, makeItemSelector } from '../util/selectors'; import { makeLoadingSelector, makeItemSelector } from '../util/selectors';
import { applyFilter, sortItems } from '../util/arrays'; import { applyFilter, sortItems } from '../util/arrays';
import { trackEvent } from '../components/Trackable'; import { trackEvent } from '../components/Trackable';
import { encodeUri } from '../util/format'; import { encodeUri, decodeUri } from '../util/format';
class Album extends React.Component { class Album extends React.Component {
constructor(props) { constructor(props) {
@ -346,7 +346,7 @@ class Album extends React.Component {
} }
const mapStateToProps = (state, ownProps) => { const mapStateToProps = (state, ownProps) => {
const uri = decodeURIComponent(ownProps.match.params.uri); const uri = decodeUri(ownProps.match.params.uri);
const itemSelector = makeItemSelector(uri); const itemSelector = makeItemSelector(uri);
const loadingSelector = makeLoadingSelector([`(.*)${uri}(.*)`, '^((?!contains).)*$', '^((?!me\/albums).)*$']); const loadingSelector = makeLoadingSelector([`(.*)${uri}(.*)`, '^((?!contains).)*$', '^((?!me\/albums).)*$']);
return { return {

View File

@ -23,7 +23,7 @@ import {
sourceIcon, sourceIcon,
titleCase, titleCase,
} from '../util/helpers'; } from '../util/helpers';
import { collate, encodeUri } from '../util/format'; import { collate, encodeUri, decodeUri } from '../util/format';
import { sortItems, applyFilter, arrayOf } from '../util/arrays'; import { sortItems, applyFilter, arrayOf } from '../util/arrays';
import { i18n, I18n } from '../locale'; import { i18n, I18n } from '../locale';
import Button from '../components/Button'; import Button from '../components/Button';
@ -601,7 +601,7 @@ class Artist extends React.Component {
} }
const mapStateToProps = (state, props) => { const mapStateToProps = (state, props) => {
const uri = decodeURIComponent(props.match.params.uri); const uri = decodeUri(props.match.params.uri);
const loadingSelector = makeLoadingSelector([`(.*)${uri}(.*)`, '^((?!contains).)*$', '^((?!albums).)*$', '^((?!related-artists).)*$', '^((?!top-tracks).)*$']); const loadingSelector = makeLoadingSelector([`(.*)${uri}(.*)`, '^((?!contains).)*$', '^((?!albums).)*$', '^((?!related-artists).)*$', '^((?!top-tracks).)*$']);
const artistSelector = makeItemSelector(uri); const artistSelector = makeItemSelector(uri);
const artist = artistSelector(state); const artist = artistSelector(state);

View File

@ -21,9 +21,7 @@ import * as mopidyActions from '../services/mopidy/actions';
import * as spotifyActions from '../services/spotify/actions'; import * as spotifyActions from '../services/spotify/actions';
import { import {
uriSource, uriSource,
getFromUri,
sourceIcon, sourceIcon,
decodeMopidyUri,
} from '../util/helpers'; } from '../util/helpers';
import { trackEvent } from '../components/Trackable'; import { trackEvent } from '../components/Trackable';
import { i18n, I18n } from '../locale'; import { i18n, I18n } from '../locale';

View File

@ -31,7 +31,7 @@ const LyricsSelector = ({
lyrics_path, lyrics_path,
} = {}, } = {},
getTrackLyrics, getTrackLyrics,
}) => { }) => {
if (lyrics_results === undefined || lyrics_results === null) return null; if (lyrics_results === undefined || lyrics_results === null) return null;
if (lyrics_results.length <= 0) { if (lyrics_results.length <= 0) {
return ( return (
@ -121,11 +121,11 @@ const Lyrics = ({
<LyricsSelector <LyricsSelector
getTrackLyrics={getTrackLyrics} getTrackLyrics={getTrackLyrics}
authorized={authorized} authorized={authorized}
track={track} track={track}
/> />
<LyricsContent <LyricsContent
track={track} track={track}
authorized={authorized} authorized={authorized}
/> />
</> </>
); );
@ -140,7 +140,7 @@ class Track extends React.Component {
}, },
} = this.props; } = this.props;
loadTrack(decodeUri(uri), { full: true, lyrics: true }); loadTrack(uri, { full: true, lyrics: true });
if (track) { if (track) {
this.setWindowTitle(track); this.setWindowTitle(track);
@ -160,7 +160,7 @@ class Track extends React.Component {
} = this.props; } = this.props;
if (prevUri !== uri) { if (prevUri !== uri) {
loadTrack(decodeUri(uri), { full: true, lyrics: true }); loadTrack(uri, { full: true, lyrics: true });
} }
if (!prevTrack && track) this.setWindowTitle(track); if (!prevTrack && track) this.setWindowTitle(track);