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

@ -56,9 +56,8 @@ const Link = ({
// 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,
@ -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) => {

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

@ -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);