mirror of
https://github.com/Dangoware/dango-music-player.git
synced 2025-06-22 22:52:59 -05:00
Moved context menu from QueueSongs
s to Queue
and updated context menu popup position
This commit is contained in:
parent
672d472742
commit
14c677e814
1 changed files with 88 additions and 64 deletions
110
src/App.tsx
110
src/App.tsx
|
@ -1,4 +1,4 @@
|
||||||
import React, { createRef, MutableRefObject, ReactEventHandler, useEffect, useRef, useState } from "react";
|
import React, { MutableRefObject, useEffect, useRef, useState } from "react";
|
||||||
import { convertFileSrc, invoke } from "@tauri-apps/api/core";
|
import { convertFileSrc, invoke } from "@tauri-apps/api/core";
|
||||||
import "./App.css";
|
import "./App.css";
|
||||||
import { Config, playbackInfo } from "./types";
|
import { Config, playbackInfo } from "./types";
|
||||||
|
@ -6,12 +6,21 @@ import { Config, playbackInfo } from "./types";
|
||||||
// import { listen } from "@tauri-apps/api/event";
|
// import { listen } from "@tauri-apps/api/event";
|
||||||
// import { fetch } from "@tauri-apps/plugin-http";
|
// import { fetch } from "@tauri-apps/plugin-http";
|
||||||
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow";
|
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow";
|
||||||
import { getCurrentWindow, LogicalPosition } from "@tauri-apps/api/window";
|
import { cursorPosition, LogicalPosition, PhysicalPosition } from "@tauri-apps/api/window";
|
||||||
import { Menu, Submenu, SubmenuOptions } from "@tauri-apps/api/menu";
|
import { Menu, Submenu, SubmenuOptions } from "@tauri-apps/api/menu";
|
||||||
import { listen } from "@tauri-apps/api/event";
|
import { TauriEvent } from "@tauri-apps/api/event";
|
||||||
|
|
||||||
|
|
||||||
const appWindow = getCurrentWebviewWindow();
|
const appWindow = getCurrentWebviewWindow();
|
||||||
|
|
||||||
|
type Location = "Library" | { "Playlist": string };
|
||||||
|
|
||||||
|
// This needs to be changed to properly reflect cursor position
|
||||||
|
// this will do for now.
|
||||||
|
async function contextMenuPosition(event: React.MouseEvent) {
|
||||||
|
return new PhysicalPosition(event.clientX, event.clientY);
|
||||||
|
}
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const library = useState<JSX.Element[]>([]);
|
const library = useState<JSX.Element[]>([]);
|
||||||
const [queue, setQueue] = useState<JSX.Element[]>([]);
|
const [queue, setQueue] = useState<JSX.Element[]>([]);
|
||||||
|
@ -19,8 +28,10 @@ function App() {
|
||||||
const [playlists, setPlaylists] = useState<JSX.Element[]>([]);
|
const [playlists, setPlaylists] = useState<JSX.Element[]>([]);
|
||||||
const [viewName, setViewName] = useState("Library");
|
const [viewName, setViewName] = useState("Library");
|
||||||
const playlistsInfo= useRef<PlaylistInfo[]>([]);
|
const playlistsInfo= useRef<PlaylistInfo[]>([]);
|
||||||
const selectedSong = useRef<SongProps>();
|
const selectedSongMain = useRef<SongProps>();
|
||||||
const setSelected = (props: SongProps) => {selectedSong.current = props;}
|
const selectedSongQueue = useRef<selectedQueueSong>({uuid: "0", index: 0, location: "Library"});
|
||||||
|
const setSelectedSongMain = (props: SongProps) => {selectedSongMain.current = props;}
|
||||||
|
const setSelectedSongQueue = (song: selectedQueueSong) => {selectedSongQueue.current = song; console.log(selectedSongQueue)}
|
||||||
|
|
||||||
const [nowPlaying, setNowPlaying] = useState<JSX.Element>(
|
const [nowPlaying, setNowPlaying] = useState<JSX.Element>(
|
||||||
<NowPlaying
|
<NowPlaying
|
||||||
|
@ -63,6 +74,7 @@ function App() {
|
||||||
location={ song[1] as "Library" | {"Playlist" : string}}
|
location={ song[1] as "Library" | {"Playlist" : string}}
|
||||||
index={i+1}
|
index={i+1}
|
||||||
key={ Math.floor((Math.random() * 100_000_000_000) + 1) + '_' + Date.now() }
|
key={ Math.floor((Math.random() * 100_000_000_000) + 1) + '_' + Date.now() }
|
||||||
|
setSelectedSong={ setSelectedSongQueue }
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -79,19 +91,20 @@ function App() {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const invoke_: any = invoke("start_controller").then(() => {});
|
invoke("start_controller").then(() => {});
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main>
|
<main>
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="leftSide">
|
<div className="leftSide">
|
||||||
<PlaylistHead playlists={ playlists } setPlaylists={ setPlaylists } setViewName={ setViewName } setLibrary={ library[1] } playlistsInfo={ playlistsInfo } setSelected={ setSelected } />
|
<PlaylistHead playlists={ playlists } setPlaylists={ setPlaylists } setViewName={ setViewName } setLibrary={ library[1] } playlistsInfo={ playlistsInfo } setSelected={ setSelectedSongMain } />
|
||||||
<MainView lib_ref={ library } viewName={ viewName } playlistsInfo={ playlistsInfo } setSelected={ setSelected } selectedSong={ selectedSong} />
|
<MainView lib_ref={ library } viewName={ viewName } playlistsInfo={ playlistsInfo } setSelected={ setSelectedSongMain } selectedSong={ selectedSongMain} />
|
||||||
</div>
|
</div>
|
||||||
<div className="rightSide">
|
<div className="rightSide">
|
||||||
{ nowPlaying }
|
{ nowPlaying }
|
||||||
<Queue songs={ queue } />
|
<Queue songs={ queue } selectedSong={ selectedSongQueue } />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="bottom">
|
<div className="bottom">
|
||||||
|
@ -121,11 +134,9 @@ interface PlaylistHeadProps {
|
||||||
function PlaylistHead({ playlists, setPlaylists, setViewName, setLibrary, playlistsInfo, setSelected }: PlaylistHeadProps) {
|
function PlaylistHead({ playlists, setPlaylists, setViewName, setLibrary, playlistsInfo, setSelected }: PlaylistHeadProps) {
|
||||||
function getPlaylist(playlist: PlaylistInfo) {
|
function getPlaylist(playlist: PlaylistInfo) {
|
||||||
invoke('get_playlist', { uuid: playlist.uuid }).then((list) => {
|
invoke('get_playlist', { uuid: playlist.uuid }).then((list) => {
|
||||||
let i = 0;
|
setLibrary([...(list as any[]).map((song, i) => {
|
||||||
setLibrary([...(list as any[]).map((song) => {
|
|
||||||
// console.log(song);
|
// console.log(song);
|
||||||
const reload = () => getPlaylist(playlist)
|
const reload = () => getPlaylist(playlist)
|
||||||
i++;
|
|
||||||
return (
|
return (
|
||||||
<Song
|
<Song
|
||||||
key={ song.uuid + Math.floor(Math.random() * 100_000_000_000) }
|
key={ song.uuid + Math.floor(Math.random() * 100_000_000_000) }
|
||||||
|
@ -137,7 +148,7 @@ function PlaylistHead({ playlists, setPlaylists, setViewName, setLibrary, playli
|
||||||
tags={ song.tags }
|
tags={ song.tags }
|
||||||
playlists={ playlistsInfo }
|
playlists={ playlistsInfo }
|
||||||
reload = { reload }
|
reload = { reload }
|
||||||
index = { i - 1 }
|
index = { i }
|
||||||
setSelected={ setSelected }
|
setSelected={ setSelected }
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
@ -167,7 +178,7 @@ function PlaylistHead({ playlists, setPlaylists, setViewName, setLibrary, playli
|
||||||
{ id: "delete_playlist" + list.uuid, text: "Delete Playlist", action: deletePlaylist }
|
{ id: "delete_playlist" + list.uuid, text: "Delete Playlist", action: deletePlaylist }
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
menu.popup();
|
menu.popup(await contextMenuPosition(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -251,7 +262,7 @@ function MainView({ lib_ref, viewName, playlistsInfo, setSelected, selectedSong
|
||||||
async function clickHandler(event: React.MouseEvent) {
|
async function clickHandler(event: React.MouseEvent) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
const _ = await invoke('get_playlists');
|
await invoke('get_playlists');
|
||||||
let removeText = "Remove from Library";
|
let removeText = "Remove from Library";
|
||||||
if (selectedSong.current!.playerLocation != "Library") {
|
if (selectedSong.current!.playerLocation != "Library") {
|
||||||
removeText = "Remove from Playlist";
|
removeText = "Remove from Playlist";
|
||||||
|
@ -273,11 +284,8 @@ function MainView({ lib_ref, viewName, playlistsInfo, setSelected, selectedSong
|
||||||
} as SubmenuOptions
|
} as SubmenuOptions
|
||||||
),
|
),
|
||||||
{ id: "remove_from_lib_playlist" + selectedSong.current!.location + selectedSong.current!.uuid, text: removeText, action: removeLibPlaylist },
|
{ id: "remove_from_lib_playlist" + selectedSong.current!.location + selectedSong.current!.uuid, text: removeText, action: removeLibPlaylist },
|
||||||
]
|
]});
|
||||||
})
|
menu.popup(await contextMenuPosition(event));
|
||||||
;
|
|
||||||
const pos = new LogicalPosition(event.clientX, event.clientY);
|
|
||||||
menu.popup(pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -466,32 +474,24 @@ function NowPlaying({ title, artist, album, artwork }: NowPlayingProps) {
|
||||||
|
|
||||||
interface QueueProps {
|
interface QueueProps {
|
||||||
songs: JSX.Element[],
|
songs: JSX.Element[],
|
||||||
|
// song element. put the proper type here :]???
|
||||||
|
selectedSong: MutableRefObject<selectedQueueSong>,
|
||||||
}
|
}
|
||||||
|
|
||||||
function Queue({ songs }: QueueProps) {
|
interface selectedQueueSong {
|
||||||
return (
|
uuid: string,
|
||||||
<section className="Queue">
|
index: number
|
||||||
{ songs }
|
location: Location,
|
||||||
</section>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface QueueSongProps {
|
function Queue({ songs, selectedSong, }: QueueProps) {
|
||||||
song: any,
|
|
||||||
location: "Library" | {"Playlist": string},
|
|
||||||
index: number,
|
|
||||||
}
|
|
||||||
|
|
||||||
function QueueSong({ song, location, index }: QueueSongProps) {
|
|
||||||
// console.log(song.tags);
|
|
||||||
|
|
||||||
const removeFromQueue = () => {
|
const removeFromQueue = () => {
|
||||||
invoke('remove_from_queue', { index: index }).then(() => {})
|
invoke('remove_from_queue', { index: selectedSong.current.index }).then(() => {})
|
||||||
}
|
}
|
||||||
const playNow = () => {
|
const playNow = () => {
|
||||||
invoke('play_now', { uuid: song.uuid, location: location }).then(() => {})
|
invoke('play_now', { uuid: selectedSong.current.uuid, location: selectedSong.current.location }).then(() => {})
|
||||||
}
|
}
|
||||||
const playNext = () => invoke('play_next_queue', { uuid: song.uuid, location }).then(() => {});
|
const playNext = () => invoke('play_next_queue', { uuid: selectedSong.current.uuid, location: selectedSong.current.location }).then(() => {});
|
||||||
const clearQueue = () => invoke('clear_queue').then();
|
const clearQueue = () => invoke('clear_queue').then();
|
||||||
|
|
||||||
async function menuHandler(event: React.MouseEvent) {
|
async function menuHandler(event: React.MouseEvent) {
|
||||||
|
@ -499,17 +499,40 @@ function QueueSong({ song, location, index }: QueueSongProps) {
|
||||||
|
|
||||||
const menu = await Menu.new({
|
const menu = await Menu.new({
|
||||||
items: [
|
items: [
|
||||||
{ id: "play_now" + index, text: "Play Now", action: playNow },
|
{ id: "play_now" + selectedSong.current.index, text: "Play Now", action: playNow },
|
||||||
{ id: "play_next_" + song.uuid + index, text: "Play Next in Queue", action: playNext },
|
{ id: "play_next_" + selectedSong.current.uuid + selectedSong.current.index, text: "Play Next in Queue", action: playNext },
|
||||||
{ id: "remove_queue" + song.uuid + index, text: "Remove from Queue", action: removeFromQueue },
|
{ id: "remove_queue" + selectedSong.current.uuid + selectedSong.current.index, text: "Remove from Queue", action: removeFromQueue },
|
||||||
{ id: "clear_queue", text: "Clear Queue", action: clearQueue },
|
{ id: "clear_queue", text: "Clear Queue", action: clearQueue },
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
menu.popup();
|
menu.popup(await contextMenuPosition(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="queueSong unselectable" onAuxClickCapture={ removeFromQueue } onDoubleClickCapture={ playNow } onContextMenu={ menuHandler }>
|
<section className="Queue"
|
||||||
|
onAuxClickCapture={ removeFromQueue }
|
||||||
|
onDoubleClick={ playNow }
|
||||||
|
onContextMenu={ menuHandler }
|
||||||
|
>
|
||||||
|
{ songs }
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface QueueSongProps {
|
||||||
|
song: any,
|
||||||
|
location: Location,
|
||||||
|
index: number,
|
||||||
|
setSelectedSong: (song: selectedQueueSong) => void,
|
||||||
|
}
|
||||||
|
|
||||||
|
function QueueSong({ song, location, index, setSelectedSong }: QueueSongProps) {
|
||||||
|
// console.log(song.tags);
|
||||||
|
|
||||||
|
let setSelected = () => setSelectedSong({uuid: song.uuid, index: index, location: location })
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="queueSong unselectable" onAuxClickCapture={ setSelected } onClick={ setSelected } onContextMenu={ setSelected }>
|
||||||
<img className="queueSongCoverArt" src={ convertFileSrc('abc') + '?' + song.uuid } key={ 'coverArt_' + song.uuid }/>
|
<img className="queueSongCoverArt" src={ convertFileSrc('abc') + '?' + song.uuid } key={ 'coverArt_' + song.uuid }/>
|
||||||
<div className="queueSongTags">
|
<div className="queueSongTags">
|
||||||
<p className="queueSongTitle">{ song.tags.TrackTitle }</p>
|
<p className="queueSongTitle">{ song.tags.TrackTitle }</p>
|
||||||
|
@ -530,3 +553,4 @@ function getConfig(): any {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue