mirror of
https://github.com/Dangoware/dango-music-player.git
synced 2025-06-22 22:52:59 -05:00
Added "Add to Queue" test button
This commit is contained in:
parent
db595c13f0
commit
99bf0b6855
4 changed files with 74 additions and 28 deletions
|
@ -1,15 +1,15 @@
|
||||||
use std::{
|
use std::{
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{AtomicBool, Ordering},
|
|
||||||
Arc,
|
Arc,
|
||||||
|
atomic::{AtomicBool, Ordering},
|
||||||
},
|
},
|
||||||
thread::sleep,
|
thread::sleep,
|
||||||
time::{Duration, Instant, SystemTime, UNIX_EPOCH},
|
time::{Duration, SystemTime, UNIX_EPOCH},
|
||||||
};
|
};
|
||||||
|
|
||||||
use chrono::TimeDelta;
|
use chrono::TimeDelta;
|
||||||
use crossbeam::select;
|
use crossbeam::select;
|
||||||
use crossbeam_channel::{bounded, unbounded, Receiver, Sender};
|
use crossbeam_channel::{Receiver, Sender, bounded, unbounded};
|
||||||
use discord_presence::Client;
|
use discord_presence::Client;
|
||||||
use listenbrainz::ListenBrainz;
|
use listenbrainz::ListenBrainz;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use std::{fs::OpenOptions, io::Write};
|
|
||||||
use dmp_core::{
|
use dmp_core::{
|
||||||
music_controller::{
|
music_controller::{
|
||||||
connections::LastFMAuth,
|
connections::LastFMAuth,
|
||||||
|
@ -7,6 +6,7 @@ use dmp_core::{
|
||||||
},
|
},
|
||||||
music_storage::queue::{QueueItem, QueueItemType},
|
music_storage::queue::{QueueItem, QueueItemType},
|
||||||
};
|
};
|
||||||
|
use std::{fs::OpenOptions, io::Write};
|
||||||
use tauri::{AppHandle, Emitter, State, Wry};
|
use tauri::{AppHandle, Emitter, State, Wry};
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
@ -58,9 +58,9 @@ pub async fn display_album_art(
|
||||||
temp_dir: State<'_, TempDir>,
|
temp_dir: State<'_, TempDir>,
|
||||||
uuid: Uuid,
|
uuid: Uuid,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
match ctrl_handle.lib_get_song(uuid.clone()).await.0.album_art(0) {
|
match ctrl_handle.lib_get_song(uuid).await.0.album_art(0) {
|
||||||
Ok(art) => {
|
Ok(art) => {
|
||||||
let mut art = art.unwrap();
|
let art = art.unwrap();
|
||||||
let path = temp_dir.path().join(format!(
|
let path = temp_dir.path().join(format!(
|
||||||
"CoverArt_{uuid}.{}",
|
"CoverArt_{uuid}.{}",
|
||||||
file_format::FileFormat::from_bytes(&art).extension()
|
file_format::FileFormat::from_bytes(&art).extension()
|
||||||
|
@ -74,7 +74,7 @@ pub async fn display_album_art(
|
||||||
.read(true)
|
.read(true)
|
||||||
.open(path.clone())
|
.open(path.clone())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
file.write_all(&mut art).unwrap();
|
file.write_all(&art).unwrap();
|
||||||
}
|
}
|
||||||
opener::open(path).unwrap();
|
opener::open(path).unwrap();
|
||||||
}
|
}
|
||||||
|
@ -92,3 +92,20 @@ pub async fn last_fm_init_auth(ctrl_handle: State<'_, ControllerHandle>) -> Resu
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #[tauri::command]
|
||||||
|
// pub async fn test_menu(
|
||||||
|
// ctrl_handle: State<'_, ControllerHandle>,
|
||||||
|
// app: AppHandle<Wry>,
|
||||||
|
// window: Window,
|
||||||
|
// uuid: Uuid,
|
||||||
|
// ) -> Result<(), String> {
|
||||||
|
// let handle = app.app_handle();
|
||||||
|
// let menu = MenuBuilder::new(handle)
|
||||||
|
// .item(&MenuItem::new(handle, "Add to Queue", true, None::<&str>).unwrap())
|
||||||
|
// .build()
|
||||||
|
// .unwrap();
|
||||||
|
// window.set_menu(menu).unwrap();
|
||||||
|
// println!("Menu popup!");
|
||||||
|
// Ok(())
|
||||||
|
// }
|
||||||
|
|
|
@ -4,12 +4,12 @@ use std::{
|
||||||
fs,
|
fs,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
thread::{scope, spawn, JoinHandle},
|
thread::{scope, spawn},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
use config::{close_window, get_config, open_config_window, save_config};
|
use config::{close_window, get_config, open_config_window, save_config};
|
||||||
use crossbeam::channel::{bounded, Receiver};
|
use crossbeam::channel::bounded;
|
||||||
use dmp_core::{
|
use dmp_core::{
|
||||||
config::{Config, ConfigLibrary},
|
config::{Config, ConfigLibrary},
|
||||||
music_controller::{
|
music_controller::{
|
||||||
|
@ -19,7 +19,7 @@ use dmp_core::{
|
||||||
music_storage::library::{MusicLibrary, Song},
|
music_storage::library::{MusicLibrary, Song},
|
||||||
};
|
};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use tauri::{http::Response, AppHandle, Emitter, Listener, Manager};
|
use tauri::{http::Response, AppHandle, Emitter, Manager};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use wrappers::{_Song, stop};
|
use wrappers::{_Song, stop};
|
||||||
|
|
||||||
|
@ -69,6 +69,7 @@ pub fn run() {
|
||||||
save_config,
|
save_config,
|
||||||
close_window,
|
close_window,
|
||||||
start_controller,
|
start_controller,
|
||||||
|
// test_menu,
|
||||||
])
|
])
|
||||||
.manage(tempfile::TempDir::new().unwrap())
|
.manage(tempfile::TempDir::new().unwrap())
|
||||||
.manage(sync_rx)
|
.manage(sync_rx)
|
||||||
|
@ -128,19 +129,12 @@ fn start_controller(app: AppHandle) -> Result<(), String> {
|
||||||
let mut config = init_get_config().unwrap();
|
let mut config = init_get_config().unwrap();
|
||||||
|
|
||||||
let (lib_path, lib_uuid) = match config.libraries.get_default() {
|
let (lib_path, lib_uuid) = match config.libraries.get_default() {
|
||||||
Ok(library) => {
|
Ok(library) => (library.path.clone(), library.uuid),
|
||||||
(library.path.clone(), library.uuid)
|
Err(_) => (create_new_library().unwrap(), Uuid::new_v4()),
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
(create_new_library().unwrap(), Uuid::new_v4())
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
let scan_path = lib_path.parent().unwrap();
|
let scan_path = lib_path.parent().unwrap();
|
||||||
|
|
||||||
println!(
|
println!("lib_path: {}\nscan_path:{scan_path:?}", lib_path.display());
|
||||||
"lib_path: {}\nscan_path:{scan_path:?}",
|
|
||||||
lib_path.display()
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut library = MusicLibrary::init(lib_path.clone(), lib_uuid).unwrap();
|
let mut library = MusicLibrary::init(lib_path.clone(), lib_uuid).unwrap();
|
||||||
|
|
||||||
|
@ -161,7 +155,6 @@ fn start_controller(app: AppHandle) -> Result<(), String> {
|
||||||
library.save(lib_path.to_path_buf()).unwrap();
|
library.save(lib_path.to_path_buf()).unwrap();
|
||||||
app.emit("library_loaded", ()).unwrap();
|
app.emit("library_loaded", ()).unwrap();
|
||||||
|
|
||||||
|
|
||||||
let last_fm_session = config.connections.last_fm_session.clone();
|
let last_fm_session = config.connections.last_fm_session.clone();
|
||||||
let listenbrainz_token = config.connections.listenbrainz_token.clone();
|
let listenbrainz_token = config.connections.listenbrainz_token.clone();
|
||||||
|
|
||||||
|
@ -260,7 +253,6 @@ fn init_get_config() -> Result<Config, String> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn create_new_library() -> Result<PathBuf, String> {
|
fn create_new_library() -> Result<PathBuf, String> {
|
||||||
let dir = rfd::FileDialog::new()
|
let dir = rfd::FileDialog::new()
|
||||||
.set_title("Pick a library path")
|
.set_title("Pick a library path")
|
||||||
|
@ -286,4 +278,3 @@ fn create_new_library() -> Result<PathBuf, String> {
|
||||||
|
|
||||||
Ok(path)
|
Ok(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
46
src/App.tsx
46
src/App.tsx
|
@ -1,4 +1,4 @@
|
||||||
import React, { createRef, useEffect, useRef, useState } from "react";
|
import React, { createRef, ReactEventHandler, 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,6 +6,9 @@ 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 { Menu } from "@tauri-apps/api/menu";
|
||||||
|
import { listen } from "@tauri-apps/api/event";
|
||||||
|
|
||||||
const appWindow = getCurrentWebviewWindow();
|
const appWindow = getCurrentWebviewWindow();
|
||||||
|
|
||||||
|
@ -25,6 +28,7 @@ function App() {
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const unlisten = appWindow.listen<any>("now_playing_change", ({ payload, }) => {
|
const unlisten = appWindow.listen<any>("now_playing_change", ({ payload, }) => {
|
||||||
const displayArtwork = () => {
|
const displayArtwork = () => {
|
||||||
|
@ -240,6 +244,7 @@ function MainView({ lib_ref, viewName }: MainViewProps) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
interface SongProps {
|
interface SongProps {
|
||||||
location: any,
|
location: any,
|
||||||
playerLocation: string | {"Playlist" : any},
|
playerLocation: string | {"Playlist" : any},
|
||||||
|
@ -255,11 +260,43 @@ interface SongProps {
|
||||||
|
|
||||||
function Song(props: SongProps) {
|
function Song(props: SongProps) {
|
||||||
// console.log(props.tags);
|
// console.log(props.tags);
|
||||||
|
const add_to_queue_test = (_: string) => {
|
||||||
|
invoke('add_song_to_queue', { uuid: props.uuid, location: props.playerLocation }).then(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
const songMenuPromise = Menu.new({
|
||||||
|
items: [
|
||||||
|
{ id: "add_song_to_queue" + props.uuid, text: "Add to Queue", action: add_to_queue_test}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
async function clickHandler(event: React.MouseEvent) {
|
||||||
|
event.preventDefault();
|
||||||
|
const menu = await songMenuPromise;
|
||||||
|
const pos = new LogicalPosition(event.clientX, event.clientY);
|
||||||
|
menu.popup(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// const unlistenPromise = listen<string>("add_song_to_queue", (event) => {
|
||||||
|
// switch (event.payload) {
|
||||||
|
// default:
|
||||||
|
// console.log("Unimplemented application menu id:", event.payload);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
// return () => {
|
||||||
|
// unlistenPromise.then((unlisten) => unlisten());
|
||||||
|
// };
|
||||||
|
// }, []);
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<div onDoubleClick={() => {
|
<div
|
||||||
invoke("play_now", { uuid: props.uuid, location: props.playerLocation }).then(() => {})
|
onDoubleClick={() => {
|
||||||
}} className="song">
|
invoke("play_now", { uuid: props.uuid, location: props.playerLocation }).then(() => {})
|
||||||
|
}}
|
||||||
|
onContextMenu={clickHandler}
|
||||||
|
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>
|
||||||
<p className="album unselectable">{ props.tags.AlbumTitle }</p>
|
<p className="album unselectable">{ props.tags.AlbumTitle }</p>
|
||||||
|
@ -271,6 +308,7 @@ function Song(props: SongProps) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
interface PlayBarProps {
|
interface PlayBarProps {
|
||||||
playing: boolean,
|
playing: boolean,
|
||||||
setPlaying: React.Dispatch<React.SetStateAction<boolean>>
|
setPlaying: React.Dispatch<React.SetStateAction<boolean>>
|
||||||
|
|
Loading…
Reference in a new issue