Merging PR #853
This commit is contained in:
@ -1,25 +1,7 @@
|
||||
import React, { useEffect, useState, useRef } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { withRouter } from 'react-router';
|
||||
import { compact } from 'lodash';
|
||||
import {
|
||||
uriSource,
|
||||
uriType,
|
||||
getFromUri,
|
||||
buildLink,
|
||||
isLoading,
|
||||
throttle,
|
||||
titleCase,
|
||||
} from '../../util/helpers';
|
||||
import {
|
||||
arrayOf,
|
||||
sortItems,
|
||||
} from '../../util/arrays';
|
||||
import Link from '../Link';
|
||||
import Icon from '../Icon';
|
||||
import Loader from '../Loader';
|
||||
import URILink from '../URILink';
|
||||
|
||||
import * as coreActions from '../../services/core/actions';
|
||||
import * as uiActions from '../../services/ui/actions';
|
||||
@ -27,8 +9,6 @@ import * as pusherActions from '../../services/pusher/actions';
|
||||
import * as mopidyActions from '../../services/mopidy/actions';
|
||||
import * as lastfmActions from '../../services/lastfm/actions';
|
||||
import * as spotifyActions from '../../services/spotify/actions';
|
||||
import { I18n } from '../../locale';
|
||||
import { encodeUri } from '../../util/format';
|
||||
import {
|
||||
makeProcessProgressSelector,
|
||||
makeProvidersSelector,
|
||||
@ -207,4 +187,4 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
mopidyActions: bindActionCreators(mopidyActions, dispatch),
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(withRouter(ContextMenu));
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ContextMenu);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { uniq } from 'lodash';
|
||||
import { I18n } from '../../locale';
|
||||
import Link from '../Link';
|
||||
@ -266,12 +266,12 @@ const Discover = ({
|
||||
uris,
|
||||
disabled,
|
||||
}) => {
|
||||
const history = useHistory();
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
const onClick = () => {
|
||||
dispatch(hideContextMenu());
|
||||
const discoverUri = encodeUri(`iris:discover:${uris.map((uri) => encodeUri(uri)).join(',')}`);
|
||||
history.push(`/discover/recommendations/${discoverUri}`);
|
||||
navigate(`/discover/recommendations/${discoverUri}`);
|
||||
};
|
||||
return (
|
||||
<div className={`context-menu__item ${disabled && 'context-menu__item--disabled'}`}>
|
||||
@ -380,11 +380,11 @@ const GoTo = ({
|
||||
type,
|
||||
uri,
|
||||
}) => {
|
||||
const history = useHistory();
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
const onClick = () => {
|
||||
dispatch(hideContextMenu());
|
||||
history.push(`/${type}/${encodeUri(uri)}`);
|
||||
navigate(`/${type}/${encodeUri(uri)}`);
|
||||
};
|
||||
return (
|
||||
<div className="context-menu__item">
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useDragLayer, useDrop } from 'react-dnd';
|
||||
import * as mopidyActions from '../../services/mopidy/actions';
|
||||
import Icon from '../Icon';
|
||||
@ -53,7 +53,7 @@ const Dropzone = ({
|
||||
accept,
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
const history = useHistory();
|
||||
const navigate = useNavigate();
|
||||
const [{ handlerId, isOver, canDrop }, drop] = useDrop({
|
||||
accept,
|
||||
collect: (monitor) => {
|
||||
@ -73,10 +73,10 @@ const Dropzone = ({
|
||||
dispatch(mopidyActions.enqueueURIs({ uris, from: context, play_next: true }));
|
||||
break;
|
||||
case 'add_to_playlist':
|
||||
history.push(`/modal/add-to-playlist/${encodeUri(uris.join(','))}`);
|
||||
navigate(`/modal/add-to-playlist/${encodeUri(uris.join(','))}`);
|
||||
break;
|
||||
case 'create_playlist_and_add':
|
||||
history.push(`/modal/create-playlist/${encodeUri(uris.join(','))}`);
|
||||
navigate(`/modal/create-playlist/${encodeUri(uris.join(','))}`);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { uriType } from '../../util/helpers';
|
||||
import Icon from '../Icon';
|
||||
import { i18n } from '../../locale';
|
||||
@ -12,7 +11,7 @@ const SearchForm = ({
|
||||
onReset: doReset,
|
||||
onSubmit: doSubmit,
|
||||
}) => {
|
||||
const history = useHistory();
|
||||
const navigate = useNavigate();
|
||||
const [term, setTerm] = useState(termProp);
|
||||
const [dirty, setDirty] = useState();
|
||||
|
||||
@ -43,19 +42,19 @@ const SearchForm = ({
|
||||
// check for uri type matching
|
||||
switch (uriType(term)) {
|
||||
case 'album':
|
||||
history.push(`/album/${encodeUri(term)}`);
|
||||
navigate(`/album/${encodeUri(term)}`);
|
||||
break;
|
||||
|
||||
case 'artist':
|
||||
history.push(`/artist/${encodeUri(term)}`);
|
||||
navigate(`/artist/${encodeUri(term)}`);
|
||||
break;
|
||||
|
||||
case 'playlist':
|
||||
history.push(`/playlist/${encodeUri(term)}`);
|
||||
navigate(`/playlist/${encodeUri(term)}`);
|
||||
break;
|
||||
|
||||
case 'track':
|
||||
history.push(`/track/${encodeUri(term)}`);
|
||||
navigate(`/track/${encodeUri(term)}`);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@ -32,6 +32,7 @@ const SecondaryLine = ({
|
||||
const items = () => {
|
||||
switch (type) {
|
||||
case 'mood':
|
||||
case 'directory':
|
||||
case 'playlist_group':
|
||||
return null;
|
||||
case 'playlist':
|
||||
@ -78,7 +79,7 @@ const GridItem = ({
|
||||
type: item?.type?.toUpperCase() || 'UNKNOWN',
|
||||
item: { item, context: item },
|
||||
});
|
||||
const tile = ['playlist_group', 'mood', 'directory', 'category'].indexOf(item?.type) > -1
|
||||
const tile = ['playlist_group', 'mood', 'category'].indexOf(item?.type) > -1
|
||||
|
||||
const onContextMenu = (e) => {
|
||||
e.preventDefault();
|
||||
@ -142,7 +143,10 @@ const GridItem = ({
|
||||
type={item.type}
|
||||
/>
|
||||
<div className="grid__item__name">
|
||||
{item.name ? item.name : <span className="opaque-text">{item.uri}</span>}
|
||||
{item.name
|
||||
? <span title={item.name}>{item.name}</span>
|
||||
: <span className="opaque-text">{item.uri}</span>
|
||||
}
|
||||
</div>
|
||||
<div className="grid__item__secondary">
|
||||
<SecondaryLine item={item} sourceIcon={sourceIcon} />
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import ReactGA from 'react-ga';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { indexToArray, sortItems } from '../util/arrays';
|
||||
import { collate } from '../util/format';
|
||||
@ -10,7 +10,7 @@ import * as mopidyActions from '../services/mopidy/actions';
|
||||
import * as snapcastActions from '../services/snapcast/actions';
|
||||
|
||||
const Hotkeys = () => {
|
||||
const history = useHistory();
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
const volume = useSelector((state) => state.mopidy.volume);
|
||||
const mute = useSelector((state) => state.mopidy.mute);
|
||||
@ -94,7 +94,7 @@ const Hotkeys = () => {
|
||||
e,
|
||||
label: 'Hotkey info',
|
||||
callback: () => {
|
||||
history.push('/modal/hotkeys');
|
||||
navigate('/modal/hotkeys');
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import React from 'react';
|
||||
import { Link as RouterLink, useHistory, useLocation } from 'react-router-dom';
|
||||
import { Link as RouterLink, useNavigate, useLocation } from 'react-router-dom';
|
||||
import { scrollTo } from '../util/helpers';
|
||||
|
||||
const updateScrollPosition = ({
|
||||
retainScroll = false,
|
||||
scrollTarget = 0,
|
||||
history,
|
||||
navigate,
|
||||
location: {
|
||||
state,
|
||||
pathname,
|
||||
@ -16,14 +16,17 @@ const updateScrollPosition = ({
|
||||
// This doesn't trigger lazy-load elements (unless scrolling exposes the LazyLoader component).
|
||||
const main = document.getElementById('main');
|
||||
|
||||
history.replace(
|
||||
navigate(
|
||||
pathname,
|
||||
{
|
||||
...state,
|
||||
scroll_position: main.scrollTop,
|
||||
previous: {
|
||||
pathname,
|
||||
state: {
|
||||
...state,
|
||||
scroll_position: main.scrollTop,
|
||||
previous: {
|
||||
pathname,
|
||||
},
|
||||
},
|
||||
replace: true,
|
||||
},
|
||||
);
|
||||
|
||||
@ -48,23 +51,23 @@ const Link = ({
|
||||
children,
|
||||
}) => {
|
||||
if (!to) return <span className={className}>{children}</span>;
|
||||
const history = useHistory();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const handleClick = (e) => {
|
||||
updateScrollPosition({
|
||||
history, location, retainScroll, scrollTarget,
|
||||
navigate, location, retainScroll, scrollTarget,
|
||||
});
|
||||
if (onClick) onClick(e);
|
||||
}
|
||||
|
||||
// Decode both links. This handles issues where one link is encoded and the other isn't, but
|
||||
// they're otherwise identical
|
||||
const currentLink = history?.location?.pathname || '';
|
||||
const currentLink = location?.pathname || '';
|
||||
const isLinkActive = exact ? currentLink === to : currentLink.startsWith(to);
|
||||
|
||||
// We have an active detector method
|
||||
// This is used almost solely by the Sidebar navigation
|
||||
const active = history && isLinkActive ? (activeClassName || 'active') : '';
|
||||
const active = navigate && isLinkActive ? (activeClassName || 'active') : '';
|
||||
return (
|
||||
<RouterLink
|
||||
onClick={handleClick}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
import { useDrag } from 'react-dnd';
|
||||
import LinksSentence from './LinksSentence';
|
||||
import { dater } from './Dater';
|
||||
@ -98,7 +98,7 @@ const ListItem = ({
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const spotify_available = useSelector((state) => state.spotify.access_token);
|
||||
const history = useHistory();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const [_, drag] = useDrag({
|
||||
type: item?.type?.toUpperCase() || 'UNKNOWN',
|
||||
@ -154,9 +154,9 @@ const ListItem = ({
|
||||
}
|
||||
|
||||
if (e.target.tagName.toLowerCase() !== 'a') {
|
||||
updateScrollPosition({ location, history });
|
||||
updateScrollPosition({ location, navigate });
|
||||
e.preventDefault();
|
||||
history.push(to);
|
||||
navigate(to);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
|
||||
const ModalStateListener = () => {
|
||||
const { name } = useSelector((state) => state.ui.modal || {});
|
||||
const history = useHistory();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
if (name && location.pathname.indexOf(`modal/${name}`) < 0) {
|
||||
history.push(`modal/${name}`);
|
||||
navigate(`modal/${name}`);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Route, Switch, useParams, useHistory } from 'react-router-dom';
|
||||
import { Route, Routes, useParams, useNavigate } from 'react-router-dom';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import Link from './Link';
|
||||
import Icon from './Icon';
|
||||
@ -116,7 +116,7 @@ const Server = () => {
|
||||
};
|
||||
|
||||
const Menu = () => {
|
||||
const history = useHistory();
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
const servers = indexToArray(useSelector((state) => state.mopidy.servers));
|
||||
|
||||
@ -133,7 +133,7 @@ const Menu = () => {
|
||||
const addServer = () => {
|
||||
const action = mopidyActions.addServer();
|
||||
dispatch(action);
|
||||
history.push(`/settings/servers/${action.server.id}`);
|
||||
navigate(`/settings/servers/${action.server.id}`);
|
||||
};
|
||||
|
||||
return (
|
||||
@ -168,7 +168,6 @@ const Menu = () => {
|
||||
}
|
||||
return (
|
||||
<Link
|
||||
history={history}
|
||||
className="menu-item"
|
||||
activeClassName="menu-item--active"
|
||||
to={`/settings/servers/${server.id}`}
|
||||
@ -207,13 +206,12 @@ const Menu = () => {
|
||||
const Servers = () => (
|
||||
<div className="sub-tabs sub-tabs--servers">
|
||||
<Menu />
|
||||
<Switch>
|
||||
<Routes>
|
||||
<Route
|
||||
exact
|
||||
path="/settings/servers/:id"
|
||||
component={Server}
|
||||
path=":id"
|
||||
component={<Server />}
|
||||
/>
|
||||
</Switch>
|
||||
</Routes>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@ import * as mopidyActions from '../services/mopidy/actions';
|
||||
import * as pusherActions from '../services/pusher/actions';
|
||||
import * as spotifyActions from '../services/spotify/actions';
|
||||
import * as lastfmActions from '../services/lastfm/actions';
|
||||
import { withRouter } from '../util';
|
||||
import * as geniusActions from '../services/genius/actions';
|
||||
import { I18n, i18n } from '../locale';
|
||||
import Button from './Button';
|
||||
@ -291,7 +292,6 @@ class Services extends React.Component {
|
||||
me: geniusUser,
|
||||
authorization: geniusAuthorization,
|
||||
},
|
||||
history,
|
||||
snapcast: {
|
||||
enabled: snapcastEnabled,
|
||||
connected: snapcastConnected,
|
||||
@ -335,7 +335,6 @@ class Services extends React.Component {
|
||||
<div className="sub-tabs__menu menu" id="services-menu">
|
||||
<div className="menu__inner">
|
||||
<Link
|
||||
history={history}
|
||||
className="menu-item menu-item--snapcast"
|
||||
activeClassName="menu-item--active"
|
||||
to="/settings/services/snapcast"
|
||||
@ -364,7 +363,6 @@ class Services extends React.Component {
|
||||
</div>
|
||||
</Link>
|
||||
<Link
|
||||
history={history}
|
||||
className="menu-item menu-item--spotify"
|
||||
activeClassName="menu-item--active"
|
||||
to="/settings/services/spotify"
|
||||
@ -387,7 +385,6 @@ class Services extends React.Component {
|
||||
</div>
|
||||
</Link>
|
||||
<Link
|
||||
history={history}
|
||||
className="menu-item menu-item--lastfm"
|
||||
activeClassName="menu-item--active"
|
||||
to="/settings/services/lastfm"
|
||||
@ -410,7 +407,6 @@ class Services extends React.Component {
|
||||
</div>
|
||||
</Link>
|
||||
<Link
|
||||
history={history}
|
||||
className="menu-item menu-item--genius"
|
||||
activeClassName="menu-item--active"
|
||||
to="/settings/services/genius"
|
||||
@ -438,8 +434,8 @@ class Services extends React.Component {
|
||||
}
|
||||
|
||||
renderService() {
|
||||
const { match } = this.props;
|
||||
switch (match.params.service) {
|
||||
const { params } = this.props;
|
||||
switch (params.service) {
|
||||
case 'spotify':
|
||||
return <div className="sub-tabs__content">{this.renderSpotify()}</div>;
|
||||
case 'lastfm':
|
||||
@ -447,7 +443,7 @@ class Services extends React.Component {
|
||||
case 'genius':
|
||||
return <div className="sub-tabs__content">{this.renderGenius()}</div>;
|
||||
case 'snapcast':
|
||||
return <div className="sub-tabs__content"><Snapcast match={this.props.match} /></div>;
|
||||
return <div className="sub-tabs__content"><Snapcast params={params} /></div>;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@ -475,4 +471,4 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
geniusActions: bindActionCreators(geniusActions, dispatch),
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Services);
|
||||
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Services));
|
||||
|
||||
@ -6,15 +6,12 @@ import SnapcastGroups from './SnapcastGroups';
|
||||
import * as uiActions from '../services/ui/actions';
|
||||
import * as actions from '../services/snapcast/actions';
|
||||
import { I18n } from '../locale';
|
||||
import Button from './Button';
|
||||
|
||||
const Snapcast = (props) => {
|
||||
const {
|
||||
actions,
|
||||
show_disconnected_clients,
|
||||
uiActions,
|
||||
match,
|
||||
history,
|
||||
snapcast: {
|
||||
host,
|
||||
port,
|
||||
@ -125,7 +122,7 @@ const Snapcast = (props) => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{connected && enabled && <SnapcastGroups match={match} history={history} />}
|
||||
{connected && enabled && <SnapcastGroups />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { collate } from '../util/format';
|
||||
@ -21,10 +22,9 @@ const SnapcastGroups = (props) => {
|
||||
streams,
|
||||
groups,
|
||||
clients,
|
||||
history,
|
||||
match: { params: { id: groupId } },
|
||||
} = props;
|
||||
|
||||
const { id: groupId } = useParams();
|
||||
const streamsArray = Object.keys(streams).map((id) => streams[id]);
|
||||
const groupsArray = Object.keys(groups).map((id) => groups[id]);
|
||||
|
||||
@ -128,7 +128,6 @@ const SnapcastGroups = (props) => {
|
||||
className={`snapcast__groups__menu-item menu-item${noClients ? ' menu-item--no-clients' : ''}`}
|
||||
activeClassName="menu-item--active"
|
||||
key={group.id}
|
||||
history={history}
|
||||
to={`/settings/services/snapcast/${group.id}`}
|
||||
scrollTo="#services-snapcast-groups"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user