Sending control_url to snapcast meta so users can jump to Mopidy instance

This commit is contained in:
James Barnsley
2021-10-17 13:08:22 +13:00
parent f1fddc5354
commit dff2b178c4
11 changed files with 115 additions and 57 deletions

View File

@ -27,6 +27,7 @@ class Extension(ext.Extension):
schema["enabled"] = config.Boolean()
schema["country"] = config.String()
schema["locale"] = config.String()
schema["control_url"] = config.String()
schema["snapcast_enabled"] = config.Boolean()
schema["snapcast_host"] = config.String()
schema["snapcast_port"] = config.String()

View File

@ -1191,20 +1191,29 @@ class IrisCore(pykka.ThreadingActor):
# Uses snapcast server and stream details as defined in configuration
##
async def update_snapcast_meta(self, *args, **kwargs):
current_track = self.core.playback.get_current_track().get()
track = self.core.playback.get_current_track().get()
# Append our server details, so Iris UI can switch to this Mopidy instance
# This isn't a great way of doing this, but it works for now.
meta = {
"control_url": self.config["iris"]["control_url"],
}
if current_track:
if track:
# We dump the JSON to convert the Track to JSON, but we need to then loads back to JSON
# for the response.
current_track = json.loads(json.dumps(current_track, cls=ModelJSONEncoder))
images = self.core.library.get_images([current_track["uri"]]).get()
track = json.loads(json.dumps(track, cls=ModelJSONEncoder))
images = self.core.library.get_images([track["uri"]]).get()
if images:
current_track["images"] = json.loads(
meta["images"] = json.loads(
json.dumps(
images[current_track["uri"]],
images[track["uri"]],
cls=ModelJSONEncoder
)
)
meta["name"] = track["name"]
meta["uri"] = track["uri"]
meta["artists"] = track["artists"]
meta["album"] = track["album"]
url = "http"
if self.config["iris"]["snapcast_ssl"]:
@ -1219,7 +1228,7 @@ class IrisCore(pykka.ThreadingActor):
"method": "Stream.SetMeta",
"params": {
"id": self.config["iris"]["snapcast_stream"],
"meta": current_track
"meta": meta
}
}

View File

@ -2,6 +2,7 @@
enabled = true
country = NZ
locale = en_NZ
control_url = http://localhost:6680
snapcast_enabled = true
snapcast_host = localhost
snapcast_port = 1780

View File

@ -153184,24 +153184,30 @@ var Header = function Header(_ref) {
var stream = _ref.stream,
server = _ref.server;
var dispatch = Object(react_redux__WEBPACK_IMPORTED_MODULE_1__["useDispatch"])();
var current_server = Object(react_redux__WEBPACK_IMPORTED_MODULE_1__["useSelector"])(function (state) {
return state.mopidy.current_server;
});
var _ref2 = stream || {},
id = _ref2.id,
meta = _ref2.meta,
status = _ref2.status;
var canBeSelected = (server === null || server === void 0 ? void 0 : server.id) && server.id !== current_server;
var controlURL = meta !== null && meta !== void 0 && meta.control_url ? new URL(meta.control_url) : null;
var controlServer = controlURL ? {
id: meta === null || meta === void 0 ? void 0 : meta.control_url,
ssl: controlURL.protocol === 'https:',
host: controlURL.hostname,
port: controlURL.port || (controlURL.protocol === 'https:' ? '443' : '80')
} : null;
console.debug({
controlURL: controlURL,
controlServer: controlServer
});
var images = meta !== null && meta !== void 0 && meta.images ? Object(_util_format__WEBPACK_IMPORTED_MODULE_14__["formatImages"])(Object(_util_format__WEBPACK_IMPORTED_MODULE_14__["digestMopidyImages"])(controlServer, meta.images)) : null;
var onClick = function onClick() {
if (!canBeSelected) return;
dispatch(_services_mopidy_actions__WEBPACK_IMPORTED_MODULE_10__["setCurrentServer"](server));
if (!controlServer) return;
dispatch(_services_mopidy_actions__WEBPACK_IMPORTED_MODULE_10__["setCurrentServer"](controlServer));
};
var images = meta !== null && meta !== void 0 && meta.images ? Object(_util_format__WEBPACK_IMPORTED_MODULE_14__["formatImages"])(Object(_util_format__WEBPACK_IMPORTED_MODULE_14__["digestMopidyImages"])(server, meta.images)) : null;
console.debug(images, meta.images);
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
className: "output-control__output__header",
"data-qa-node": "div",
@ -153217,10 +153223,10 @@ var Header = function Header(_ref) {
"data-qa-node": "div",
"data-qa-file": "OutputControl"
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("h5", {
className: "output-control__output__header__title",
className: "output-control__output__header__title tooltip",
onClick: onClick,
style: {
cursor: canBeSelected ? 'pointer' : 'default'
cursor: controlServer ? 'pointer' : 'default'
},
"data-qa-node": "h5",
"data-qa-file": "OutputControl"
@ -153228,7 +153234,11 @@ var Header = function Header(_ref) {
name: "play_arrow",
"data-qa-node": "Icon",
"data-qa-file": "OutputControl"
})), meta && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("ul", {
}), controlURL && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
className: "tooltip__content",
"data-qa-node": "div",
"data-qa-file": "OutputControl"
}, meta.control_url)), meta && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("ul", {
className: "details",
"data-qa-node": "ul",
"data-qa-file": "OutputControl"
@ -158481,6 +158491,8 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var _services_mopidy_actions__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../services/mopidy/actions */ "./src/js/services/mopidy/actions.js");
/* harmony import */ var _util_helpers__WEBPACK_IMPORTED_MODULE_8__ = __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 _util_format__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../util/format */ "./src/js/util/format.js");
@ -158674,8 +158686,9 @@ var Server = function Server(_ref) {
};
var Servers = function Servers(_ref2) {
var serverId = _ref2.match.params.id,
var id = _ref2.match.params.id,
history = _ref2.history;
var serverId = Object(_util_format__WEBPACK_IMPORTED_MODULE_10__["decodeUri"])(id);
var store = Object(react_redux__WEBPACK_IMPORTED_MODULE_1__["useStore"])();
var dispatch = Object(react_redux__WEBPACK_IMPORTED_MODULE_1__["useDispatch"])();
@ -158692,7 +158705,7 @@ var Servers = function Servers(_ref2) {
var addServer = function addServer() {
var action = _services_mopidy_actions__WEBPACK_IMPORTED_MODULE_7__["addServer"]();
dispatch(action);
history.push("/settings/servers/".concat(action.server.id));
history.push("/settings/servers/".concat(Object(_util_format__WEBPACK_IMPORTED_MODULE_10__["encodeUri"])(action.server.id)));
};
var Menu = function Menu() {
@ -158754,7 +158767,7 @@ var Servers = function Servers(_ref2) {
history: history,
className: "menu-item",
activeClassName: "menu-item--active",
to: "/settings/servers/".concat(server.id),
to: "/settings/servers/".concat(Object(_util_format__WEBPACK_IMPORTED_MODULE_10__["encodeUri"])(server.id)),
scrollTo: "#servers-menu",
key: server.id,
"data-qa-node": "Link",
@ -167098,6 +167111,12 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getQueueHistory", function() { return getQueueHistory; });
/* harmony import */ var _util_arrays__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../util/arrays */ "./src/js/util/arrays.js");
/* harmony import */ var _util_helpers__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../util/helpers */ "./src/js/util/helpers.js");
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function set(data) {
@ -167118,16 +167137,19 @@ function updateServers(servers) {
servers: servers
};
}
function addServer() {
function addServer(data) {
var server = _objectSpread({
host: window.location.hostname,
port: window.location.port ? window.location.port : window.location.protocol === 'https:' ? '443' : '80',
ssl: window.location.protocol === 'https:'
}, data);
return {
type: 'MOPIDY_UPDATE_SERVER',
server: {
id: Object(_util_helpers__WEBPACK_IMPORTED_MODULE_1__["generateGuid"])(),
name: 'New server',
host: window.location.hostname,
port: window.location.port ? window.location.port : window.location.protocol === 'https:' ? '443' : '80',
ssl: window.location.protocol === 'https:'
}
server: _objectSpread(_objectSpread({}, server), {}, {
id: "http".concat(server.ssl ? 's' : '', "://").concat(server.host, ":").concat(server.port),
name: "".concat(server.host).concat(server.ssl ? ' 🔒' : '')
})
};
}
function setCurrentServer(server) {
@ -168066,6 +168088,8 @@ var MopidyMiddleware = function () {
break;
case 'MOPIDY_SET_CURRENT_SERVER':
var existingServer = action.server.id ? store.getState().mopidy.servers[action.server.id] : null;
if (!existingServer) store.dispatch(mopidyActions.addServer(action.server));
store.dispatch(mopidyActions.set({
current_server: action.server.id,
host: action.server.host,
@ -168079,6 +168103,7 @@ var MopidyMiddleware = function () {
store.dispatch(mopidyActions.connect());
store.dispatch(pusherActions.connect());
}, 250);
next(action);
break;
case 'MOPIDY_GET_SERVER_STATE':

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -115,7 +115,7 @@
// Release details
// These are automatically injected to built HTML
var build = "1634411463";
var build = "1634428893";
var version = "3.59.1";
// Construct the script tag

View File

@ -18,19 +18,26 @@ import { I18n } from '../../locale';
const Header = ({ stream, server }) => {
const dispatch = useDispatch();
const current_server = useSelector((state) => state.mopidy.current_server);
const {
id,
meta,
status,
} = stream || {};
const canBeSelected = server?.id && server.id !== current_server;
const controlURL = meta?.control_url ? new URL(meta.control_url) : null;
const controlServer = controlURL ? {
id: meta?.control_url,
ssl: controlURL.protocol === 'https:',
host: controlURL.hostname,
port: controlURL.port || (controlURL.protocol === 'https:' ? '443' : '80'),
} : null;
console.debug({ controlURL, controlServer });
const images = meta?.images ? formatImages(digestMopidyImages(controlServer, meta.images)) : null;
const onClick = () => {
if (!canBeSelected) return;
dispatch(mopidyActions.setCurrentServer(server));
}
const images = meta?.images ? formatImages(digestMopidyImages(server, meta.images)) : null;
console.debug(images, meta.images)
if (!controlServer) return;
dispatch(mopidyActions.setCurrentServer(controlServer));
};
return (
<div className="output-control__output__header">
<Thumbnail
@ -40,12 +47,13 @@ const Header = ({ stream, server }) => {
/>
<div className="output-control__output__header__content">
<h5
className="output-control__output__header__title"
className="output-control__output__header__title tooltip"
onClick={onClick}
style={{ cursor: canBeSelected ? 'pointer' : 'default' }}
style={{ cursor: controlServer ? 'pointer' : 'default' }}
>
{server?.name || id}
{status === 'playing' && <Icon name="play_arrow" />}
{controlURL && <div className="tooltip__content">{meta.control_url}</div>}
</h5>
{meta && (
<ul className="details">

View File

@ -8,6 +8,7 @@ import { Button } from './Button';
import * as mopidyActions from '../services/mopidy/actions';
import { iconFromKeyword } from '../util/helpers';
import { I18n } from '../locale';
import { decodeUri, encodeUri } from '../util/format';
const Server = ({
server,
@ -107,9 +108,10 @@ const Server = ({
};
const Servers = ({
match: { params: { id: serverId } },
match: { params: { id } },
history,
}) => {
const serverId = decodeUri(id);
const store = useStore();
const dispatch = useDispatch();
const {
@ -128,7 +130,7 @@ const Servers = ({
const addServer = () => {
const action = mopidyActions.addServer();
dispatch(action);
history.push(`/settings/servers/${action.server.id}`);
history.push(`/settings/servers/${encodeUri(action.server.id)}`);
};
const Menu = () => (
@ -166,7 +168,7 @@ const Servers = ({
history={history}
className="menu-item"
activeClassName="menu-item--active"
to={`/settings/servers/${server.id}`}
to={`/settings/servers/${encodeUri(server.id)}`}
scrollTo="#servers-menu"
key={server.id}
>

View File

@ -22,15 +22,21 @@ export function updateServers(servers) {
};
}
export function addServer() {
export function addServer(data) {
const server = {
host: window.location.hostname,
port: window.location.port
? window.location.port
: (window.location.protocol === 'https:' ? '443' : '80'),
ssl: window.location.protocol === 'https:',
...data,
};
return {
type: 'MOPIDY_UPDATE_SERVER',
server: {
id: generateGuid(),
name: 'New server',
host: window.location.hostname,
port: (window.location.port ? window.location.port : (window.location.protocol === 'https:' ? '443' : '80')),
ssl: window.location.protocol === 'https:',
...server,
id: `http${server.ssl ? 's' : ''}://${server.host}:${server.port}`,
name: `${server.host}${server.ssl ? ' 🔒' : ''}`,
},
};
}

View File

@ -459,6 +459,11 @@ const MopidyMiddleware = (function () {
break;
case 'MOPIDY_SET_CURRENT_SERVER':
const existingServer = action.server.id
? store.getState().mopidy.servers[action.server.id]
: null;
if (!existingServer) store.dispatch(mopidyActions.addServer(action.server));
store.dispatch(mopidyActions.set({
current_server: action.server.id,
host: action.server.host,
@ -476,6 +481,7 @@ const MopidyMiddleware = (function () {
},
250,
);
next(action);
break;
case 'MOPIDY_GET_SERVER_STATE': {