diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 6c3b475e0..5c1cfd0bb 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -2,13 +2,13 @@ if [ -z "$PULSE_COOKIE_DATA" ] then - printf '%s' "$(echo "$PULSE_COOKIE_DATA" | sed -e 's/../\\x&/g')" >"$HOME"/pulse.cookie - export PULSE_COOKIE="$HOME"/pulse.cookie + printf '%s' "$(echo $PULSE_COOKIE_DATA | sed -e 's/../\\x&/g')" >$HOME/pulse.cookie + export PULSE_COOKIE=$HOME/pulse.cookie fi if [ ${PIP_PACKAGES:+x} ]; then echo "-- INSTALLING PIP PACKAGES $PIP_PACKAGES --" - python3 -m pip install --no-cache --upgrade "$PIP_PACKAGES" + python3 -m pip install --no-cache --upgrade $PIP_PACKAGES fi exec "$@" diff --git a/docker/snapserver/snapserver-example.conf b/docker/snapserver/snapserver-example.conf index 763399e97..cf45eb51a 100644 --- a/docker/snapserver/snapserver-example.conf +++ b/docker/snapserver/snapserver-example.conf @@ -73,7 +73,8 @@ doc_root = /usr/share/snapserver/snapweb/ # stream URI of the PCM input stream, can be configured multiple times # Format: TYPE://host/path?name=NAME[&codec=CODEC][&sampleformat=SAMPLEFORMAT] #stream = pipe:///tmp/snapfifo?name=default -stream = pipe:///tmp/snapfifo?name=Default&sampleformat=48000:16:2&controlscript=meta_mopidy.py +stream = pipe:///tmp/snapfifo?name=Mopidy&sampleformat=48000:16:2&controlscript=meta_mopidy.py +stream = librespot:///librespot?name=Spotify # Default sample format #sampleformat = 48000:16:2 diff --git a/package-lock.json b/package-lock.json index a974475b2..44abe921f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "mopidy-iris", - "version": "3.65.0", + "version": "3.66.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -4855,9 +4855,9 @@ "dev": true }, "enhanced-resolve": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", - "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", + "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", "dev": true, "requires": { "graceful-fs": "^4.2.4", @@ -11010,9 +11010,9 @@ } }, "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", "dev": true, "requires": { "randombytes": "^2.1.0" @@ -11441,18 +11441,24 @@ } }, "terser-webpack-plugin": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz", - "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==", + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.7.tgz", + "integrity": "sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw==", "dev": true, "requires": { - "@jridgewell/trace-mapping": "^0.3.14", + "@jridgewell/trace-mapping": "^0.3.17", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "terser": "^5.14.1" + "serialize-javascript": "^6.0.1", + "terser": "^5.16.5" }, "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -11489,6 +11495,18 @@ "requires": { "has-flag": "^4.0.0" } + }, + "terser": { + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.6.tgz", + "integrity": "sha512-IBZ+ZQIA9sMaXmRZCUMDjNH0D5AQQfdn4WUjHL0+1lF4TP1IHRJbrhb6fNaXWikrYQTSkb7SLxkeXAiy1p7mbg==", + "dev": true, + "requires": { + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + } } } }, @@ -11871,9 +11889,9 @@ "dev": true }, "webpack": { - "version": "5.73.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.73.0.tgz", - "integrity": "sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA==", + "version": "5.76.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.0.tgz", + "integrity": "sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA==", "dev": true, "requires": { "@types/eslint-scope": "^3.7.3", @@ -11881,11 +11899,11 @@ "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/wasm-edit": "1.11.1", "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", + "acorn": "^8.7.1", "acorn-import-assertions": "^1.7.6", "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.9.3", + "enhanced-resolve": "^5.10.0", "es-module-lexer": "^0.9.0", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -11898,7 +11916,7 @@ "schema-utils": "^3.1.0", "tapable": "^2.1.1", "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.3.1", + "watchpack": "^2.4.0", "webpack-sources": "^3.2.3" }, "dependencies": { diff --git a/package.json b/package.json index 48da1fe14..a6fa51ad9 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ "sortablejs": "1.15.0", "style-loader": "3.3.1", "url-loader": "4.1.1", - "webpack": "5.73.0", + "webpack": "5.76.0", "webpack-cli": "4.10.0", "webpack-dev-server": "4.11.1", "webpack-strip": "0.1.0", diff --git a/src/js/components/Fields/OutputControl.js b/src/js/components/Fields/OutputControl.js index 1bee0bb26..0c4d334d9 100755 --- a/src/js/components/Fields/OutputControl.js +++ b/src/js/components/Fields/OutputControl.js @@ -8,7 +8,13 @@ import Thumbnail from '../Thumbnail'; import LinksSentence from '../LinksSentence'; import DropdownField from './DropdownField'; import * as pusherActions from '../../services/pusher/actions'; -import * as snapcastActions from '../../services/snapcast/actions'; +import { + setGroupStream, + setClientMute, + setClientVolume, + setStreamingEnabled, + controlStream, +} from '../../services/snapcast/actions'; import { sortItems, indexToArray } from '../../util/arrays'; import { titleCase } from '../../util/helpers'; import { I18n, i18n } from '../../locale'; @@ -38,10 +44,10 @@ const Header = ({ let onClick = null; switch (playbackStatus) { case 'playing': - if (canPause) onClick = () => dispatch(snapcastActions.controlStream(id, 'pause')); + if (canPause) onClick = () => dispatch(controlStream(id, 'pause')); break; default: - if (canPlay) onClick = () => dispatch(snapcastActions.controlStream(id, 'play')); + if (canPlay) onClick = () => dispatch(controlStream(id, 'play')); break; } @@ -88,6 +94,7 @@ const Header = ({ }; const Group = ({ + setExpanded, group: { id: groupId, name: groupName, @@ -111,6 +118,7 @@ const Group = ({ className="text" to={`/settings/services/snapcast/${groupId}`} scrollTo="#services-snapcast-groups" + onClick={() => setExpanded(false)} > {titleCase(groupName)} @@ -121,7 +129,7 @@ const Group = ({ options={allStreams.map((s) => ({ value: s.id, label: titleCase(s.id) }))} noLabel handleChange={ - (value) => dispatch(snapcastActions.setGroupStream(groupId, value)) + (value) => dispatch(setGroupStream(groupId, value)) } /> @@ -143,14 +151,14 @@ const Group = ({ noTooltip mute={mute} onMuteChange={ - (value) => dispatch(snapcastActions.setClientMute(clientId, value)) + (value) => dispatch(setClientMute(clientId, value)) } /> dispatch(snapcastActions.setClientVolume(clientId, value)) + (value) => dispatch(setClientVolume(clientId, value)) } /> @@ -162,11 +170,13 @@ const Group = ({ ); }; -const Outputs = () => { +const Outputs = ({ setExpanded }) => { + const dispatch = useDispatch(); const allGroups = indexToArray(useSelector((state) => state.snapcast.groups || {})); const allStreams = useSelector((state) => state.snapcast.streams || {}); const allServers = indexToArray(useSelector((state) => state.mopidy.servers || {})); const groupsByStream = groupBy(allGroups, 'stream_id'); + const { streaming_enabled } = useSelector((state) => state?.snapcast || {}); return ( @@ -180,10 +190,29 @@ const Outputs = () => { return (
- {groups.map((group) => )} + { + groups.map( + (group) => ( + + ) + ) + }
); })} +
+ +
); } @@ -241,7 +270,7 @@ const OutputControl = ({ force_expanded }) => {
{!isEmpty(commands) && } - {snapcastEnabled && } + {snapcastEnabled && }
); diff --git a/src/js/components/Snapcast.js b/src/js/components/Snapcast.js index ff74ee504..4f342e894 100755 --- a/src/js/components/Snapcast.js +++ b/src/js/components/Snapcast.js @@ -41,18 +41,6 @@ const Snapcast = (props) => { -