mirror of
https://github.com/Dangoware/dango-music-player.git
synced 2025-06-22 22:52:59 -05:00
Added function to remove a song from the library/ playlist
This commit is contained in:
parent
5666581c7f
commit
624e6f2db6
9 changed files with 185 additions and 88 deletions
|
@ -108,6 +108,7 @@ pub enum LibraryCommand {
|
||||||
Song(Uuid),
|
Song(Uuid),
|
||||||
AllSongs,
|
AllSongs,
|
||||||
GetLibrary,
|
GetLibrary,
|
||||||
|
LibraryRemoveSong(Uuid),
|
||||||
ExternalPlaylist(Uuid),
|
ExternalPlaylist(Uuid),
|
||||||
PlaylistSong { list_uuid: Uuid, item_uuid: Uuid },
|
PlaylistSong { list_uuid: Uuid, item_uuid: Uuid },
|
||||||
Playlist(Uuid),
|
Playlist(Uuid),
|
||||||
|
@ -115,6 +116,7 @@ pub enum LibraryCommand {
|
||||||
Save,
|
Save,
|
||||||
Playlists,
|
Playlists,
|
||||||
PlaylistAddSong { playlist: Uuid, song: Uuid },
|
PlaylistAddSong { playlist: Uuid, song: Uuid },
|
||||||
|
PlaylistRemoveSong { playlist: Uuid, song: Uuid },
|
||||||
DeletePlaylist(Uuid),
|
DeletePlaylist(Uuid),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,14 @@ impl ControllerHandle {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn lib_remove_song(&self, song: Uuid) {
|
||||||
|
let (command, tx) = LibraryCommandInput::command(LibraryCommand::LibraryRemoveSong(song));
|
||||||
|
self.lib_mail_rx.send(command).await.unwrap();
|
||||||
|
let LibraryResponse::Ok = tx.recv().await.unwrap() else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// The Playlist Section
|
// The Playlist Section
|
||||||
pub async fn playlist_get(&self, uuid: Uuid) -> Result<ExternalPlaylist, ()> {
|
pub async fn playlist_get(&self, uuid: Uuid) -> Result<ExternalPlaylist, ()> {
|
||||||
let (command, tx) = LibraryCommandInput::command(LibraryCommand::ExternalPlaylist(uuid));
|
let (command, tx) = LibraryCommandInput::command(LibraryCommand::ExternalPlaylist(uuid));
|
||||||
|
@ -92,6 +100,15 @@ impl ControllerHandle {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn playlist_remove_song(&self, song: Uuid, playlist: Uuid) {
|
||||||
|
let (command, tx) =
|
||||||
|
LibraryCommandInput::command(LibraryCommand::PlaylistRemoveSong { song, playlist });
|
||||||
|
self.lib_mail_rx.send(command).await.unwrap();
|
||||||
|
let LibraryResponse::Ok = tx.recv().await.unwrap() else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// The Queue Section
|
// The Queue Section
|
||||||
pub async fn queue_append(
|
pub async fn queue_append(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -108,7 +108,18 @@ impl Controller {
|
||||||
LibraryCommand::PlaylistAddSong { playlist, song } => {
|
LibraryCommand::PlaylistAddSong { playlist, song } => {
|
||||||
let playlist = library.query_playlist_uuid_mut(&playlist).unwrap();
|
let playlist = library.query_playlist_uuid_mut(&playlist).unwrap();
|
||||||
playlist.add_track(song);
|
playlist.add_track(song);
|
||||||
library.save(config.read().path.clone()).unwrap();
|
let lib_uuid = library.uuid;
|
||||||
|
library
|
||||||
|
.save(
|
||||||
|
config
|
||||||
|
.read()
|
||||||
|
.libraries
|
||||||
|
.get_library(&lib_uuid)
|
||||||
|
.unwrap()
|
||||||
|
.path
|
||||||
|
.clone(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
res_rx.send(LibraryResponse::Ok).await.unwrap();
|
res_rx.send(LibraryResponse::Ok).await.unwrap();
|
||||||
}
|
}
|
||||||
LibraryCommand::DeletePlaylist(uuid) => {
|
LibraryCommand::DeletePlaylist(uuid) => {
|
||||||
|
@ -127,6 +138,39 @@ impl Controller {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
res_rx.send(LibraryResponse::Ok).await.unwrap();
|
res_rx.send(LibraryResponse::Ok).await.unwrap();
|
||||||
}
|
}
|
||||||
|
LibraryCommand::LibraryRemoveSong(uuid) => {
|
||||||
|
library.remove_uuid(&uuid).unwrap();
|
||||||
|
let lib_uuid = library.uuid;
|
||||||
|
library
|
||||||
|
.save_path(
|
||||||
|
&config
|
||||||
|
.read()
|
||||||
|
.libraries
|
||||||
|
.get_library(&lib_uuid)
|
||||||
|
.unwrap()
|
||||||
|
.path
|
||||||
|
.clone(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
res_rx.send(LibraryResponse::Ok).await.unwrap();
|
||||||
|
}
|
||||||
|
LibraryCommand::PlaylistRemoveSong { playlist, song } => {
|
||||||
|
library.playlists.delete_song(song, &playlist).unwrap();
|
||||||
|
|
||||||
|
let lib_uuid = library.uuid;
|
||||||
|
library
|
||||||
|
.save(
|
||||||
|
config
|
||||||
|
.read()
|
||||||
|
.libraries
|
||||||
|
.get_library(&lib_uuid)
|
||||||
|
.unwrap()
|
||||||
|
.path
|
||||||
|
.clone(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
res_rx.send(LibraryResponse::Ok).await.unwrap();
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ use file_format::{FileFormat, Kind};
|
||||||
use lofty::file::{AudioFile as _, TaggedFileExt as _};
|
use lofty::file::{AudioFile as _, TaggedFileExt as _};
|
||||||
use lofty::probe::Probe;
|
use lofty::probe::Probe;
|
||||||
use lofty::tag::{ItemKey, ItemValue, TagType};
|
use lofty::tag::{ItemKey, ItemValue, TagType};
|
||||||
use rayon::iter::plumbing::Folder;
|
|
||||||
use rcue::parser::parse_from_file;
|
use rcue::parser::parse_from_file;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
@ -985,6 +984,17 @@ impl MusicLibrary {
|
||||||
Ok(location)
|
Ok(location)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn remove_uuid(&mut self, target_uuid: &Uuid) -> Result<usize, Box<dyn Error>> {
|
||||||
|
let location = match self.query_uuid(target_uuid) {
|
||||||
|
Some(value) => value.1,
|
||||||
|
None => return Err("Uuid not in database".into()),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.library.remove(location);
|
||||||
|
|
||||||
|
Ok(location)
|
||||||
|
}
|
||||||
|
|
||||||
/// Scan the song by a location and update its tags
|
/// Scan the song by a location and update its tags
|
||||||
// TODO: change this to work with multiple uris
|
// TODO: change this to work with multiple uris
|
||||||
pub fn update_uri(
|
pub fn update_uri(
|
||||||
|
|
|
@ -14,6 +14,7 @@ use super::library::{AlbumArt, MusicLibrary, Song, Tag, URI};
|
||||||
use chrono::format::Item;
|
use chrono::format::Item;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use thiserror::Error;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use m3u8_rs::{MediaPlaylist, MediaPlaylistType, MediaSegment, Playlist as List2};
|
use m3u8_rs::{MediaPlaylist, MediaPlaylistType, MediaSegment, Playlist as List2};
|
||||||
|
@ -99,6 +100,20 @@ impl PlaylistFolder {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn delete_song(&mut self, song: Uuid, playlist: &Uuid) -> Result<(), PlaylistError> {
|
||||||
|
match self.query_uuid_mut(playlist) {
|
||||||
|
Some(list) => {
|
||||||
|
if let Some((_, index)) = list.query_uuid(&song) {
|
||||||
|
list.remove_track(index);
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(PlaylistError::NoUuid(song, *playlist))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => Err(PlaylistError::NoPlaylist(*playlist)),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
|
@ -146,9 +161,9 @@ impl Playlist {
|
||||||
self.tracks.push(track);
|
self.tracks.push(track);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_track(&mut self, index: i32) {
|
pub fn remove_track(&mut self, index: usize) {
|
||||||
let index = index as usize;
|
let len = self.tracks.len();
|
||||||
if (self.tracks.len() - 1) >= index {
|
if len > 0 && (len - 1) >= index {
|
||||||
self.tracks.remove(index);
|
self.tracks.remove(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -453,6 +468,14 @@ impl ExternalPlaylist {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum PlaylistError {
|
||||||
|
#[error("No uuid {0} found in playlist {1}")]
|
||||||
|
NoUuid(Uuid, Uuid),
|
||||||
|
#[error("No Playlist found with uuid {0}")]
|
||||||
|
NoPlaylist(Uuid),
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test_super {
|
mod test_super {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -11,7 +11,7 @@ use tauri::{AppHandle, Emitter, State, Wry};
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{wrappers::_Song, LAST_FM_API_KEY, LAST_FM_API_SECRET};
|
use crate::{LAST_FM_API_KEY, LAST_FM_API_SECRET, wrappers::_Song};
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn add_song_to_queue(
|
pub async fn add_song_to_queue(
|
||||||
|
@ -93,19 +93,23 @@ pub async fn last_fm_init_auth(ctrl_handle: State<'_, ControllerHandle>) -> Resu
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[tauri::command]
|
#[tauri::command]
|
||||||
// pub async fn test_menu(
|
pub async fn remove_from_lib_playlist(
|
||||||
// ctrl_handle: State<'_, ControllerHandle>,
|
app: AppHandle<Wry>,
|
||||||
// app: AppHandle<Wry>,
|
ctrl_handle: State<'_, ControllerHandle>,
|
||||||
// window: Window,
|
song: Uuid,
|
||||||
// uuid: Uuid,
|
location: PlayerLocation,
|
||||||
// ) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
// let handle = app.app_handle();
|
match location {
|
||||||
// let menu = MenuBuilder::new(handle)
|
PlayerLocation::Library => {
|
||||||
// .item(&MenuItem::new(handle, "Add to Queue", true, None::<&str>).unwrap())
|
ctrl_handle.lib_remove_song(song).await;
|
||||||
// .build()
|
app.emit("library_loaded", ()).unwrap();
|
||||||
// .unwrap();
|
}
|
||||||
// window.set_menu(menu).unwrap();
|
PlayerLocation::Playlist(uuid) => {
|
||||||
// println!("Menu popup!");
|
ctrl_handle.playlist_remove_song(song, uuid).await;
|
||||||
// Ok(())
|
}
|
||||||
// }
|
_ => unimplemented!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
@ -28,7 +28,9 @@ use crate::wrappers::{
|
||||||
get_queue, get_song, import_playlist, next, pause, play, play_next_queue, prev,
|
get_queue, get_song, import_playlist, next, pause, play, play_next_queue, prev,
|
||||||
remove_from_queue, seek, set_volume,
|
remove_from_queue, seek, set_volume,
|
||||||
};
|
};
|
||||||
use commands::{add_song_to_queue, display_album_art, last_fm_init_auth, play_now};
|
use commands::{
|
||||||
|
add_song_to_queue, display_album_art, last_fm_init_auth, play_now, remove_from_lib_playlist,
|
||||||
|
};
|
||||||
|
|
||||||
pub mod commands;
|
pub mod commands;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
@ -74,6 +76,7 @@ pub fn run() {
|
||||||
delete_playlist,
|
delete_playlist,
|
||||||
play_next_queue,
|
play_next_queue,
|
||||||
clear_queue,
|
clear_queue,
|
||||||
|
remove_from_lib_playlist,
|
||||||
// test_menu,
|
// test_menu,
|
||||||
])
|
])
|
||||||
.manage(tempfile::TempDir::new().unwrap())
|
.manage(tempfile::TempDir::new().unwrap())
|
||||||
|
|
|
@ -316,6 +316,6 @@ pub async fn clear_queue(
|
||||||
ctrl_handle: State<'_, ControllerHandle>,
|
ctrl_handle: State<'_, ControllerHandle>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let res = ctrl_handle.queue_clear().await.map_err(|e| e.to_string());
|
let res = ctrl_handle.queue_clear().await.map_err(|e| e.to_string());
|
||||||
app.emit("queue_updated", ());
|
_ = app.emit("queue_updated", ());
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
112
src/App.tsx
112
src/App.tsx
|
@ -116,17 +116,39 @@ interface PlaylistHeadProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
function PlaylistHead({ playlists, setPlaylists, setViewName, setLibrary, playlistsInfo }: PlaylistHeadProps) {
|
function PlaylistHead({ playlists, setPlaylists, setViewName, setLibrary, playlistsInfo }: PlaylistHeadProps) {
|
||||||
|
function getPlaylist(playlist: PlaylistInfo) {
|
||||||
|
invoke('get_playlist', { uuid: playlist.uuid }).then((list) => {
|
||||||
|
setLibrary([...(list as any[]).map((song) => {
|
||||||
|
// console.log(song);
|
||||||
|
const reload = () => getPlaylist(playlist)
|
||||||
|
return (
|
||||||
|
<Song
|
||||||
|
key={ song.uuid + Math.floor(Math.random() * 100_000_000_000) }
|
||||||
|
location={ song.location }
|
||||||
|
playerLocation={ {"Playlist" : playlist.uuid } }
|
||||||
|
uuid={ song.uuid }
|
||||||
|
plays={ song.plays }
|
||||||
|
duration={ song.duration }
|
||||||
|
tags={ song.tags }
|
||||||
|
playlists={ playlistsInfo }
|
||||||
|
reload = { reload }
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
})])
|
||||||
|
})
|
||||||
|
setViewName( playlist.name )
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const unlisten = appWindow.listen<any[]>("playlists_gotten", (_res) => {
|
const unlisten = appWindow.listen<any[]>("playlists_gotten", (_res) => {
|
||||||
// console.log(event);
|
// console.log(event);
|
||||||
let res = _res.payload as PlaylistInfo[];
|
let res = _res.payload as PlaylistInfo[];
|
||||||
playlistsInfo.current = [...res];
|
playlistsInfo.current = [...res];
|
||||||
console.log(playlistsInfo, res);
|
// console.log(playlistsInfo, res);
|
||||||
|
|
||||||
setPlaylists([
|
setPlaylists([
|
||||||
...res.map( (list) => {
|
...res.map( (list) => {
|
||||||
|
const _getPlaylist = () => getPlaylist(list)
|
||||||
const deletePlaylist = () => {
|
const deletePlaylist = () => {
|
||||||
invoke('delete_playlist', { uuid: list.uuid }).then(() => {});
|
invoke('delete_playlist', { uuid: list.uuid }).then(() => {});
|
||||||
invoke('get_playlists').then(() => {});
|
invoke('get_playlists').then(() => {});
|
||||||
|
@ -142,27 +164,7 @@ function PlaylistHead({ playlists, setPlaylists, setViewName, setLibrary, playli
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button onClick={ () => {
|
<button onClick={ _getPlaylist }
|
||||||
invoke('get_playlist', { uuid: list.uuid }).then((list_songs) => {
|
|
||||||
setLibrary([...(list_songs as any[]).map((song) => {
|
|
||||||
// console.log(song);
|
|
||||||
return (
|
|
||||||
<Song
|
|
||||||
key={ song.uuid + Math.floor(Math.random() * 100_000_000_000) }
|
|
||||||
location={ song.location }
|
|
||||||
playerLocation={ {"Playlist" : list.uuid } }
|
|
||||||
uuid={ song.uuid }
|
|
||||||
plays={ song.plays }
|
|
||||||
duration={ song.duration }
|
|
||||||
tags={ song.tags }
|
|
||||||
playlists={ playlistsInfo }
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
})])
|
|
||||||
})
|
|
||||||
setViewName( list.name )
|
|
||||||
|
|
||||||
} }
|
|
||||||
onContextMenu={ menuHandler }
|
onContextMenu={ menuHandler }
|
||||||
key={ 'playlist_' + list.uuid }>{ list.name }</button>
|
key={ 'playlist_' + list.uuid }>{ list.name }</button>
|
||||||
)
|
)
|
||||||
|
@ -177,31 +179,9 @@ function PlaylistHead({ playlists, setPlaylists, setViewName, setLibrary, playli
|
||||||
|
|
||||||
setPlaylists([
|
setPlaylists([
|
||||||
...playlists,
|
...playlists,
|
||||||
<button onClick={ () => {
|
<button onClick={ () => getPlaylist(res) } key={ 'playlist_' + res.uuid }>{ res.name }</button>
|
||||||
invoke('get_playlist', { uuid: res.uuid }).then((list) => {
|
|
||||||
console.log((list as any[]).length);
|
|
||||||
|
|
||||||
|
|
||||||
setLibrary([...(list as any[]).map((song) => {
|
|
||||||
// console.log(song);
|
|
||||||
return (
|
|
||||||
<Song
|
|
||||||
key={ song.uuid }
|
|
||||||
location={ song.location }
|
|
||||||
playerLocation={ {"Playlist" : res.uuid } }
|
|
||||||
uuid={ song.uuid }
|
|
||||||
plays={ song.plays }
|
|
||||||
duration={ song.duration }
|
|
||||||
tags={ song.tags }
|
|
||||||
playlists={ playlistsInfo }
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
})])
|
|
||||||
})
|
|
||||||
setViewName( res.name )
|
|
||||||
} } key={ 'playlist_' + res.uuid }>{ res.name }</button>
|
|
||||||
])
|
])
|
||||||
console.log(res.name);
|
// console.log(res.name);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
|
@ -210,11 +190,11 @@ function PlaylistHead({ playlists, setPlaylists, setViewName, setLibrary, playli
|
||||||
setViewName("Library");
|
setViewName("Library");
|
||||||
invoke('get_library').then((lib) => {
|
invoke('get_library').then((lib) => {
|
||||||
setLibrary([...(lib as any[]).map((song) => {
|
setLibrary([...(lib as any[]).map((song) => {
|
||||||
console.log(song);
|
// console.log(song);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Song
|
<Song
|
||||||
key={ song.uuid }
|
key={ song.uuid + Math.floor(Math.random() * 100_000_000_000) }
|
||||||
location={ song.location }
|
location={ song.location }
|
||||||
playerLocation="Library"
|
playerLocation="Library"
|
||||||
uuid={ song.uuid }
|
uuid={ song.uuid }
|
||||||
|
@ -290,22 +270,37 @@ interface SongProps {
|
||||||
date_added?: string,
|
date_added?: string,
|
||||||
date_modified?: string,
|
date_modified?: string,
|
||||||
tags: any,
|
tags: any,
|
||||||
playlists: MutableRefObject<PlaylistInfo[]>
|
playlists: MutableRefObject<PlaylistInfo[]>,
|
||||||
|
reload?: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
function Song(props: SongProps) {
|
function Song(props: SongProps) {
|
||||||
// console.log(props.tags);
|
// console.log(props.tags);
|
||||||
const add_to_queue_test = (_: string) => {
|
const addToQueue = (_: string) => {
|
||||||
invoke('add_song_to_queue', { uuid: props.uuid, location: props.playerLocation }).then(() => {});
|
invoke('add_song_to_queue', { uuid: props.uuid, location: props.playerLocation }).then(() => {});
|
||||||
}
|
}
|
||||||
|
const playNow = () => invoke("play_now", { uuid: props.uuid, location: props.playerLocation }).then(() => {})
|
||||||
|
const playNext = () => invoke("play_next_queue", { uuid: props.uuid, location: props.playerLocation }).then(() => {})
|
||||||
|
const removeLibPlaylist = () => {
|
||||||
|
invoke("remove_from_lib_playlist", { song: props.uuid, location: props.playerLocation }).then(() => {
|
||||||
|
if (props.reload !== undefined) {
|
||||||
|
props.reload()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
async function clickHandler(event: React.MouseEvent) {
|
async function clickHandler(event: React.MouseEvent) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
console.log(props.playlists);
|
|
||||||
const _ = await invoke('get_playlists');
|
const _ = await invoke('get_playlists');
|
||||||
|
let removeText = "Remove from Library";
|
||||||
|
if (props.playerLocation != "Library") {
|
||||||
|
removeText = "Remove from Playlist";
|
||||||
|
}
|
||||||
const menu = await Menu.new({
|
const menu = await Menu.new({
|
||||||
items: [
|
items: [
|
||||||
{ id: "add_song_to_queue" + props.uuid, text: "Add to Queue", action: add_to_queue_test },
|
{ id: "play_now_" + props.uuid, text: "Play Now", action: playNow },
|
||||||
|
{ id: "play_next_" + props.uuid, text: "Play Next", action: playNext },
|
||||||
|
{ id: "add_song_to_queue" + props.uuid, text: "Add to Queue", action: addToQueue },
|
||||||
await Submenu.new(
|
await Submenu.new(
|
||||||
{
|
{
|
||||||
text: "Add to Playlist...",
|
text: "Add to Playlist...",
|
||||||
|
@ -316,7 +311,8 @@ function Song(props: SongProps) {
|
||||||
return { id: "add_song_to_playlists" + props.uuid + list.uuid, text: list.name, action: addToPlaylist }
|
return { id: "add_song_to_playlists" + props.uuid + list.uuid, text: list.name, action: addToPlaylist }
|
||||||
})]
|
})]
|
||||||
} as SubmenuOptions
|
} as SubmenuOptions
|
||||||
)
|
),
|
||||||
|
{ id: "remove_from_lib_playlist" + props.location + props.uuid, text: removeText, action: removeLibPlaylist },
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
;
|
;
|
||||||
|
@ -339,10 +335,8 @@ function Song(props: SongProps) {
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<div
|
<div
|
||||||
onDoubleClick={() => {
|
onDoubleClick = { playNow }
|
||||||
invoke("play_now", { uuid: props.uuid, location: props.playerLocation }).then(() => {})
|
onContextMenu={ clickHandler }
|
||||||
}}
|
|
||||||
onContextMenu={clickHandler}
|
|
||||||
className="song">
|
className="song">
|
||||||
<p className="artist unselectable">{ props.tags.TrackArtist }</p>
|
<p className="artist unselectable">{ props.tags.TrackArtist }</p>
|
||||||
<p className="title unselectable">{ props.tags.TrackTitle }</p>
|
<p className="title unselectable">{ props.tags.TrackTitle }</p>
|
||||||
|
|
Loading…
Reference in a new issue