Added "Add to Queue" test button

This commit is contained in:
MrDulfin 2025-05-26 13:58:40 -04:00
parent db595c13f0
commit 99bf0b6855
4 changed files with 74 additions and 28 deletions

View file

@ -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;

View file

@ -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(())
// }

View file

@ -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)
} }

View file

@ -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>>