Browse Source

update contextmenu

- move to root app
- styling changes
master
jeffvli 3 years ago
parent
commit
87bb21820e
  1. 2
      src/App.tsx
  2. 156
      src/components/shared/ContextMenu.tsx
  3. 4
      src/components/shared/styled.ts
  4. 6
      src/components/viewtypes/ListViewTable.tsx

2
src/App.tsx

@ -23,6 +23,7 @@ import { defaultDark, defaultLight } from './styles/styledTheme';
import { useAppSelector } from './redux/hooks';
import PageModal from './components/modal/PageModal';
import NowPlayingMiniView from './components/player/NowPlayingMiniView';
import { GlobalContextMenu } from './components/shared/ContextMenu';
const keyMap = {
FOCUS_SEARCH: 'ctrl+f',
@ -96,6 +97,7 @@ const App = () => {
</Layout>
<PageModal />
<NowPlayingMiniView />
<GlobalContextMenu />
</Router>
</GlobalHotKeys>
</ThemeProvider>

156
src/components/shared/ContextMenu.tsx

@ -1,5 +1,23 @@
import React from 'react';
import { ContextMenuWindow, StyledContextMenuButton } from './styled';
import React, { useRef, useState } from 'react';
import { useQuery } from 'react-query';
import { useHistory } from 'react-router';
import { Popover, Whisper } from 'rsuite';
import { getPlaylists, populatePlaylist } from '../../api/api';
import { useAppDispatch, useAppSelector } from '../../redux/hooks';
import {
addProcessingPlaylist,
removeProcessingPlaylist,
setContextMenu,
} from '../../redux/miscSlice';
import {
ContextMenuTitle,
ContextMenuDivider,
ContextMenuWindow,
StyledContextMenuButton,
StyledInputPicker,
StyledButton,
} from './styled';
import { notifyToast } from './toast';
export const ContextMenuButton = ({ children, ...rest }: any) => {
return (
@ -9,7 +27,7 @@ export const ContextMenuButton = ({ children, ...rest }: any) => {
);
};
export const NowPlayingContextMenu = ({
export const ContextMenu = ({
yPos,
xPos,
width,
@ -31,3 +49,135 @@ export const NowPlayingContextMenu = ({
</ContextMenuWindow>
);
};
export const GlobalContextMenu = () => {
const history = useHistory();
const dispatch = useAppDispatch();
const misc = useAppSelector((state) => state.misc);
const multiSelect = useAppSelector((state) => state.multiSelect);
const playlistTriggerRef = useRef<any>();
const [selectedPlaylistId, setSelectedPlaylistId] = useState('');
const { data: playlists }: any = useQuery(['playlists', 'name'], () =>
getPlaylists('name')
);
const handleAddToPlaylist = async () => {
// If the window is closed, the selectedPlaylistId will be deleted
const localSelectedPlaylistId = selectedPlaylistId;
dispatch(addProcessingPlaylist(selectedPlaylistId));
const sortedEntries = [...multiSelect.selected].sort(
(a: any, b: any) => a.rowIndex - b.rowIndex
);
try {
const res = await populatePlaylist(
localSelectedPlaylistId,
sortedEntries
);
if (res.status === 'failed') {
notifyToast('error', res.error.message);
} else {
notifyToast(
'success',
<>
<p>
Added {sortedEntries.length} song(s) to playlist &quot;
{
playlists.find(
(playlist: any) => playlist.id === localSelectedPlaylistId
)?.name
}
&quot;
</p>
<StyledButton
appearance="link"
onClick={() => {
history.push(`/playlist/${localSelectedPlaylistId}`);
dispatch(setContextMenu({ show: false }));
}}
>
Go to playlist
</StyledButton>
</>
);
}
} catch (err) {
console.log(err);
}
dispatch(removeProcessingPlaylist(localSelectedPlaylistId));
};
return (
<>
{misc.contextMenu.show && misc.contextMenu.type === 'nowPlaying' && (
<>
<ContextMenu
xPos={misc.contextMenu.xPos}
yPos={misc.contextMenu.yPos}
width={140}
numOfButtons={5}
numOfDividers={3}
hasTitle
>
<ContextMenuTitle>
Selected: {multiSelect.selected.length}
</ContextMenuTitle>
<ContextMenuDivider />
<ContextMenuButton>Add to queue</ContextMenuButton>
<ContextMenuButton>Remove from current</ContextMenuButton>
<ContextMenuDivider />
<Whisper
ref={playlistTriggerRef}
enterable
placement="autoHorizontal"
trigger="none"
speaker={
<Popover>
<StyledInputPicker
data={playlists}
virtualized
style={{ width: '150px' }}
labelKey="name"
valueKey="id"
onChange={(e: any) => setSelectedPlaylistId(e)}
/>
<StyledButton
disabled={
!selectedPlaylistId ||
misc.isProcessingPlaylist.includes(selectedPlaylistId)
}
loading={misc.isProcessingPlaylist.includes(
selectedPlaylistId
)}
onClick={handleAddToPlaylist}
>
Add
</StyledButton>
</Popover>
}
>
<ContextMenuButton
onClick={() =>
playlistTriggerRef.current.state.isOverlayShown
? playlistTriggerRef.current.close()
: playlistTriggerRef.current.open()
}
>
Add to playlist
</ContextMenuButton>
</Whisper>
<ContextMenuDivider />
<ContextMenuButton>Add to favorites</ContextMenuButton>
<ContextMenuButton>Remove from favorites</ContextMenuButton>
</ContextMenu>
</>
)}
</>
);
};

4
src/components/shared/styled.ts

@ -170,7 +170,7 @@ export const ContextMenuWindow = styled.div<{
left: ${(props) => `${props.xPos}px`};
height: ${(props) =>
`${
props.numOfButtons * 30 +
props.numOfButtons * 30.5 +
props.numOfDividers * 7 +
(props.hasTitle ? 16 : 0)
}px`};
@ -180,7 +180,7 @@ export const ContextMenuWindow = styled.div<{
overflow: hidden;
overflow-x: hidden;
font-size: smaller;
background: ${(props) => props.theme.primary.background};
background: ${(props) => props.theme.primary.sideBar};
border: 1px #3c4043 solid;
`;

6
src/components/viewtypes/ListViewTable.tsx

@ -213,13 +213,11 @@ const ListViewTable = ({
(entry: any) => entry.uniqueId === rowData.uniqueId
).length > 0
) {
const xFix = misc.expandSidebar ? 185 : 50;
const yFix = nowPlaying ? 150 : 215;
dispatch(
setContextMenu({
show: true,
xPos: e.pageX - xFix,
yPos: e.pageY - yFix,
xPos: e.pageX,
yPos: e.pageY,
rowId: rowData.uniqueId,
type: nowPlaying ? 'nowPlaying' : 'other',
})

Loading…
Cancel
Save