Added playlist import for gui (yt only)

This commit is contained in:
Gvidas Juknevičius 2024-09-14 19:50:13 +03:00
parent 29c7e452b0
commit 776a88c4cf
Signed by: MCorange
GPG Key ID: 12B1346D720B7FBB
5 changed files with 740 additions and 653 deletions

File diff suppressed because it is too large Load Diff

View File

@ -4,16 +4,20 @@ mod song_edit_window;
use egui::{Color32, Label, Sense}; use egui::{Color32, Label, Sense};
use egui_extras::{Column, TableBuilder}; use egui_extras::{Column, TableBuilder};
use song_edit_window::{GuiError, GuiImportPlaylist, GuiNewSong};
use crate::{config::{Config, ConfigWrapper}, downloader::Downloader, manifest::{song::SongType, Manifest}}; use crate::{config::{Config, ConfigWrapper}, downloader::Downloader, manifest::{song::SongType, Manifest}};
use self::song_edit_window::GuiSongEditor; use self::song_edit_window::GuiSongEditor;
#[derive(Debug)] #[derive(Debug, Default)]
pub struct Gui { pub struct Gui {
manifest: Manifest, manifest: Manifest,
song_editor: GuiSongEditor, song_edit_w: GuiSongEditor,
new_song_w: GuiNewSong,
import_playlist_w: GuiImportPlaylist,
error_w: GuiError,
filter: String, filter: String,
downloader: Downloader, downloader: Downloader,
cfg: ConfigWrapper cfg: ConfigWrapper
@ -23,18 +27,10 @@ impl Gui {
fn new(_: &eframe::CreationContext<'_>, manifest: Manifest, downloader: Downloader, cfg: ConfigWrapper) -> Self { fn new(_: &eframe::CreationContext<'_>, manifest: Manifest, downloader: Downloader, cfg: ConfigWrapper) -> Self {
Self { Self {
manifest, manifest,
song_editor: GuiSongEditor {
is_new_open: false,
is_open: false,
song: Default::default(),
ed_url: String::new(),
ed_name: String::new(),
ed_playlist: Some(String::new()),
ed_type: SongType::Youtube
},
filter: String::new(), filter: String::new(),
downloader, downloader,
cfg, cfg,
..Default::default()
} }
} }
@ -61,6 +57,10 @@ impl Gui {
Ok(()) Ok(())
} }
pub fn throw_error(&mut self, text: impl ToString) {
self.error_w.is_open = true;
self.error_w.text = text.to_string();
}
} }
impl eframe::App for Gui { impl eframe::App for Gui {
@ -68,6 +68,8 @@ impl eframe::App for Gui {
self.draw_nav(ctx, frame); self.draw_nav(ctx, frame);
self.draw_song_edit_window(ctx, frame); self.draw_song_edit_window(ctx, frame);
self.draw_new_song_window(ctx, frame); self.draw_new_song_window(ctx, frame);
self.draw_import_playlist_window(ctx, frame);
self.draw_error_window(ctx, frame);
egui::CentralPanel::default().show(ctx, |ui| { egui::CentralPanel::default().show(ctx, |ui| {
// The central panel the region left after adding TopPanel's and SidePanel's // The central panel the region left after adding TopPanel's and SidePanel's
@ -163,14 +165,14 @@ impl eframe::App for Gui {
body.row(18.0, |mut row| { body.row(18.0, |mut row| {
row.col(|ui| { row.col(|ui| {
if ui.add(Label::new("[edit]").sense(Sense::click())).clicked() { if ui.add(Label::new("[edit]").sense(Sense::click())).clicked() {
self.song_editor.song = ( self.song_edit_w.song = (
pname.clone(), pname.clone(),
sname.clone(), sname.clone(),
); );
log::debug!("Label pressed"); log::debug!("Label pressed");
self.song_editor.is_open = true; self.song_edit_w.is_open = true;
self.song_editor.ed_name = sname.clone(); self.song_edit_w.ed_name = sname.clone();
self.song_editor.ed_url = s.get_url_str().clone(); self.song_edit_w.ed_url = s.get_url_str().clone();
} }
}); });

View File

@ -21,13 +21,17 @@ impl Gui {
if ui.button("Quit").clicked() { if ui.button("Quit").clicked() {
ctx.send_viewport_cmd(egui::ViewportCommand::Close); ctx.send_viewport_cmd(egui::ViewportCommand::Close);
} }
}); });
ui.menu_button("Song", |ui| { ui.menu_button("Song", |ui| {
if ui.button("Add New").clicked() { if ui.button("Add New").clicked() {
log::debug!("NEW SONG"); self.new_song_w.is_open = true;
self.song_editor.is_new_open = true; }
});
ui.menu_button("Playlist", |ui| {
if ui.button("Import").clicked() {
self.import_playlist_w.is_open = true;
} }
}); });

View File

@ -1,28 +1,46 @@
use egui::{Color32, TextBuffer}; use egui::{Color32, RichText, TextBuffer};
use crate::manifest::{playlist::Playlist, song::{Song, SongType}}; use crate::manifest::{playlist::Playlist, song::{Song, SongType}};
use super::Gui; use super::Gui;
#[derive(Debug)] #[derive(Debug, Default)]
pub struct GuiSongEditor { pub struct GuiSongEditor {
pub is_open: bool, pub is_open: bool,
pub is_new_open: bool,
pub song: (String, String), pub song: (String, String),
pub ed_url: String, pub ed_url: String,
pub ed_name: String, pub ed_name: String,
pub ed_playlist: Option<String>,
pub ed_type: SongType,
} }
#[derive(Debug, Default)]
pub struct GuiNewSong {
pub is_open: bool,
ed_type: SongType,
ed_name: String,
ed_playlist: Option<String>,
ed_url: String,
}
#[derive(Debug, Default)]
pub struct GuiImportPlaylist {
pub is_open: bool,
ed_name: String,
ed_url: String,
}
#[derive(Debug, Default)]
pub struct GuiError {
pub is_open: bool,
pub text: String,
}
impl Gui { impl Gui {
pub fn draw_song_edit_window(&mut self, ctx: &egui::Context, _: &mut eframe::Frame) { pub fn draw_song_edit_window(&mut self, ctx: &egui::Context, _: &mut eframe::Frame) {
let mut save = false; let mut save = false;
let (playlist, song_name) = self.song_editor.song.clone(); let (playlist, song_name) = self.song_edit_w.song.clone();
let Some(song) = self.manifest.get_song(&playlist, &song_name) else { let Some(song) = self.manifest.get_song(&playlist, &song_name) else {
return; return;
@ -30,7 +48,7 @@ impl Gui {
let song = song.clone(); let song = song.clone();
egui::Window::new("Song editor") egui::Window::new("Song editor")
.open(&mut self.song_editor.is_open) .open(&mut self.song_edit_w.is_open)
.show(ctx, .show(ctx,
|ui| { |ui| {
@ -51,11 +69,11 @@ impl Gui {
ui.horizontal(|ui| { ui.horizontal(|ui| {
ui.label("Name: "); ui.label("Name: ");
ui.text_edit_singleline(&mut self.song_editor.ed_name); ui.text_edit_singleline(&mut self.song_edit_w.ed_name);
}); });
ui.horizontal(|ui| { ui.horizontal(|ui| {
ui.label("Url: "); ui.label("Url: ");
ui.text_edit_singleline(&mut self.song_editor.ed_url); ui.text_edit_singleline(&mut self.song_edit_w.ed_url);
}); });
if ui.button("Save").clicked() { if ui.button("Save").clicked() {
@ -69,7 +87,7 @@ impl Gui {
return; return;
}; };
*song.get_url_str_mut() = self.song_editor.ed_url.clone(); *song.get_url_str_mut() = self.song_edit_w.ed_url.clone();
} }
let Some(playlist) = self.manifest.get_playlist_mut(&playlist) else { let Some(playlist) = self.manifest.get_playlist_mut(&playlist) else {
@ -78,7 +96,7 @@ impl Gui {
playlist.remove_song(&song_name); playlist.remove_song(&song_name);
playlist.add_song(self.song_editor.ed_name.clone(), song); playlist.add_song(self.song_edit_w.ed_name.clone(), song);
let _ = self.manifest.save(None); let _ = self.manifest.save(None);
} }
} }
@ -86,38 +104,38 @@ impl Gui {
pub fn draw_new_song_window(&mut self, ctx: &egui::Context, _: &mut eframe::Frame) { pub fn draw_new_song_window(&mut self, ctx: &egui::Context, _: &mut eframe::Frame) {
let mut save = false; let mut save = false;
egui::Window::new("New song") egui::Window::new("New song")
.open(&mut self.song_editor.is_new_open) .open(&mut self.new_song_w.is_open)
.show(ctx, |ui| { .show(ctx, |ui| {
ui.horizontal(|ui| { ui.horizontal(|ui| {
ui.label("Type: "); ui.label("Type: ");
egui::ComboBox::from_id_source("new_song_window_type") egui::ComboBox::from_id_source("new_song_window_type")
.selected_text(format!("{:?}", self.song_editor.ed_type)) .selected_text(format!("{:?}", self.new_song_w.ed_type))
.show_ui(ui, |ui| { .show_ui(ui, |ui| {
ui.selectable_value(&mut self.song_editor.ed_type, SongType::Youtube, "Youtube"); ui.selectable_value(&mut self.new_song_w.ed_type, SongType::Youtube, "Youtube");
ui.selectable_value(&mut self.song_editor.ed_type, SongType::Spotify, "Spotify"); ui.selectable_value(&mut self.new_song_w.ed_type, SongType::Spotify, "Spotify");
ui.selectable_value(&mut self.song_editor.ed_type, SongType::Soundcloud, "Soundcloud"); ui.selectable_value(&mut self.new_song_w.ed_type, SongType::Soundcloud, "Soundcloud");
} }
); );
}); });
ui.horizontal(|ui| { ui.horizontal(|ui| {
ui.label("Name: "); ui.label("Name: ");
ui.text_edit_singleline(&mut self.song_editor.ed_name); ui.text_edit_singleline(&mut self.new_song_w.ed_name);
}); });
ui.horizontal(|ui| { ui.horizontal(|ui| {
ui.label("Playlist: "); ui.label("Playlist: ");
egui::ComboBox::from_id_source("new_song_window_playlist") egui::ComboBox::from_id_source("new_song_window_playlist")
.selected_text(format!("{}", self.song_editor.ed_playlist.clone().unwrap())) .selected_text(format!("{}", self.new_song_w.ed_playlist.clone().unwrap()))
.show_ui(ui, |ui| { .show_ui(ui, |ui| {
for p in self.manifest.get_playlists().keys() { for p in self.manifest.get_playlists().keys() {
ui.selectable_value(&mut self.song_editor.ed_playlist, Option::Some(p.clone()), p.as_str()); ui.selectable_value(&mut self.new_song_w.ed_playlist, Option::Some(p.clone()), p.as_str());
} }
} }
); );
}); });
ui.horizontal(|ui| { ui.horizontal(|ui| {
ui.label("Url: "); ui.label("Url: ");
ui.text_edit_singleline(&mut self.song_editor.ed_url); ui.text_edit_singleline(&mut self.new_song_w.ed_url);
}); });
if ui.button("Save").clicked() { if ui.button("Save").clicked() {
@ -126,19 +144,81 @@ impl Gui {
}); });
if save { if save {
let Some(playlist) = self.manifest.get_playlist_mut(&self.song_editor.ed_playlist.clone().unwrap()) else { let Some(playlist) = self.manifest.get_playlist_mut(&self.new_song_w.ed_playlist.clone().unwrap()) else {
panic!("couldnt find playlist from a preset playlist list????????????"); panic!("couldnt find playlist from a preset playlist list????????????");
}; };
playlist.add_song( playlist.add_song(
self.song_editor.ed_name.clone(), self.new_song_w.ed_name.clone(),
Song::from_url_str(self.song_editor.ed_url.clone()).unwrap().set_type(self.song_editor.ed_type.clone()).clone() Song::from_url_str(self.new_song_w.ed_url.clone()).unwrap().set_type(self.new_song_w.ed_type.clone()).clone()
); );
let _ = self.manifest.save(None); let _ = self.manifest.save(None);
self.song_editor.is_new_open = false; self.new_song_w.is_open = false;
} }
} }
pub fn draw_import_playlist_window(&mut self, ctx: &egui::Context, _: &mut eframe::Frame) {
let mut save = false;
egui::Window::new("Import Playlist")
.open(&mut self.import_playlist_w.is_open)
.show(ctx, |ui| {
ui.horizontal(|ui| {
ui.label("Type: Youtube");
});
ui.horizontal(|ui| {
ui.label("Name: ");
ui.text_edit_singleline(&mut self.import_playlist_w.ed_name);
});
ui.horizontal(|ui| {
ui.label("Url: ");
ui.text_edit_singleline(&mut self.import_playlist_w.ed_url);
});
if ui.button("Import").clicked() {
save = true;
}
});
if save {
let name = self.import_playlist_w.ed_name.clone();
let url = self.import_playlist_w.ed_url.clone();
if self.manifest.get_playlist(&name).is_some() {
log::error!("Playlist {name} already exists");
self.throw_error(format!("Playlist {name} already exists"));
}
let songs = self.downloader.download_playlist_nb(&self.cfg, &url, &name, &self.manifest.get_format()).unwrap();
self.manifest.add_playlist(name.clone());
let playlist = self.manifest.get_playlist_mut(&name).expect("Unreachable");
for (sname, song) in songs {
log::info!("Added: {sname}");
playlist.add_song(sname, song);
}
let _ = self.manifest.save(None);
self.import_playlist_w.is_open = false;
}
}
pub fn draw_error_window(&mut self, ctx: &egui::Context, _: &mut eframe::Frame) {
egui::Window::new("ERROR!!!! D:")
.open(&mut self.error_w.is_open)
.show(ctx, |ui| {
ui.vertical(|ui| {
ui.label(RichText::new("Error:").size(30.0).color(Color32::RED));
ui.horizontal(|ui| {
ui.label("Mcmg had an error:");
ui.label(self.error_w.text.clone());
})
})
});
}
} }

View File

@ -4,8 +4,9 @@ use anyhow::{bail, Result};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Default)]
pub enum SongType { pub enum SongType {
#[default]
Youtube, Youtube,
Spotify, Spotify,
Soundcloud, Soundcloud,