From 2e8205bd26347877dbb4d7cc672f58b759b603a5 Mon Sep 17 00:00:00 2001 From: James Barnsley Date: Sun, 3 Oct 2021 21:18:21 +1300 Subject: [PATCH] Experimenting with mulitple server selector --- src/js/components/Servers.js | 291 ++++++++++++++++++++++------------- src/js/components/Sidebar.js | 34 +++- src/js/locale/en.yaml | 1 + 3 files changed, 219 insertions(+), 107 deletions(-) diff --git a/src/js/components/Servers.js b/src/js/components/Servers.js index 7919eea3..98f090ed 100755 --- a/src/js/components/Servers.js +++ b/src/js/components/Servers.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState, useEffect } from 'react'; import { useStore, useDispatch } from 'react-redux'; import Link from './Link'; import Icon from './Icon'; @@ -8,6 +8,185 @@ import { Button } from './Button'; import * as mopidyActions from '../services/mopidy/actions'; import { iconFromKeyword } from '../util/helpers'; import { I18n } from '../locale'; +import LinksSentence from './LinksSentence'; +import { + digestMopidyImages, + formatImages, +} from '../util/format'; +import Thumbnail from './Thumbnail'; + +const callServer = ({ endpoint, method, params }) => new Promise((resolve, reject) => { + const body = { + jsonrpc: '2.0', + id: 1, + method, + params, + }; + fetch(endpoint, { + method: 'POST', + mode: 'no-cors', + credentials: 'same-origin', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(body), + }) + .then((response) => response.json()) + .then(({ result }) => resolve(result)) + .catch((error) => { console.debug({ error }); reject() }); +}); + +const Server = ({ + server, + current_server, +}) => { + if (!server) return null; + const { id } = server; + const dispatch = useDispatch(); + const [currentTrack, setCurrentTrack] = useState(); + const [playState, setPlayState] = useState(); + + useEffect(() => { + const endpoint = `http://${server.host}:${server.port}/mopidy/rpc`; + callServer({ + endpoint, + method: 'core.playback.get_current_track', + }).then( + (track) => { + callServer({ + endpoint, + method: 'core.library.get_images', + params: { + uris: [track.uri], + }, + }).then(({ [track.uri]: images }) => { + console.debug({ track }) + setCurrentTrack({ + ...track, + images: images ? formatImages(digestMopidyImages(server, images)) : null, + }); + }); + }, + () => setCurrentTrack(null), + ); + + callServer({ + endpoint, + method: 'core.playback.get_state', + }).then(setPlayState, setPlayState); + }, [id]); + + const remove = () => { + dispatch(mopidyActions.removeServer(server.id)); + }; + + const setAsCurrent = () => { + dispatch(mopidyActions.setCurrentServer(server)); + }; + + return ( +
+ + + + + +
+
+ +
+
+ +
+
+ + + +
+ ); +}; const Servers = ({ match: { params: { id: serverId } }, @@ -19,7 +198,6 @@ const Servers = ({ mopidy: { servers, current_server, - ssl, connected: mopidyConnected, connecting: mopidyConnecting, }, @@ -35,7 +213,7 @@ const Servers = ({ history.push(`/settings/servers/${action.server.id}`); }; - const renderMenu = () => ( + const Menu = () => (
{indexToArray(servers).map((server) => { @@ -102,110 +280,13 @@ const Servers = ({
); - const renderServer = () => { - if (!serverId) return null; - const server = servers[serverId]; - if (!server) return null; - - const remove = () => { - dispatch(mopidyActions.removeServer(server.id)); - }; - - const setAsCurrent = () => { - dispatch(mopidyActions.setCurrentServer(server)); - }; - - return ( -
- - - - -
-
- -
-
- -
-
- - - -
- ); - }; - return (
- {renderMenu()} - {renderServer()} + +
); }; diff --git a/src/js/components/Sidebar.js b/src/js/components/Sidebar.js index 4f21e336..adb8d098 100755 --- a/src/js/components/Sidebar.js +++ b/src/js/components/Sidebar.js @@ -1,16 +1,45 @@ import React from 'react'; -import { connect } from 'react-redux'; +import { connect, useSelector, useDispatch } from 'react-redux'; import { bindActionCreators } from 'redux'; import { withRouter } from 'react-router'; import Link from './Link'; import Icon from './Icon'; import Dropzones from './Fields/Dropzones'; import PinList from './Fields/PinList'; +import DropdownField from './Fields/DropdownField'; import * as uiActions from '../services/ui/actions'; import * as mopidyActions from '../services/mopidy/actions'; import { I18n, i18n } from '../locale'; +import { indexToArray } from '../util/arrays'; -class Sidebar extends React.Component { +const ServerSwitcher = () => { + const servers = useSelector((state) => state.mopidy.servers); + const serversArray = indexToArray(servers); + const current_server = useSelector((state) => state.mopidy.current_server); + const dispatch = useDispatch(); + if (!serversArray || serversArray.length <= 1) return null; + + const onChange = (id) => dispatch(mopidyActions.setCurrentServer(servers[id])); + + return ( +
+ ({ value: server.id, label: server.name }))} + handleChange={onChange} + /> +
+ ); +} + +class Sidebar extends React.Component { closeSidebar = () => { const { uiActions: { @@ -89,6 +118,7 @@ class Sidebar extends React.Component {