This commit is contained in:
parent
894c68338d
commit
7f30b4395f
2 changed files with 190 additions and 89 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{error::Error, fmt::Display};
|
use std::{error::Error, fmt::Display, path::PathBuf};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
|
@ -21,6 +21,29 @@ pub enum ServiceItemKind {
|
||||||
Content(Slide),
|
Content(Slide),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TryFrom<PathBuf> for ServiceItemKind {
|
||||||
|
type Error = miette::Error;
|
||||||
|
|
||||||
|
fn try_from(path: PathBuf) -> Result<Self, Self::Error> {
|
||||||
|
let ext = path
|
||||||
|
.extension()
|
||||||
|
.map(|ext| ext.to_str())
|
||||||
|
.flatten()
|
||||||
|
.ok_or(miette::miette!(
|
||||||
|
"There isn't an extension on this file"
|
||||||
|
))?;
|
||||||
|
match ext {
|
||||||
|
"png" | "jpg" | "jpeg" => {
|
||||||
|
Ok(Self::Image(Image::from(path)))
|
||||||
|
}
|
||||||
|
"mp4" | "mkv" | "webm" => {
|
||||||
|
Ok(Self::Video(Video::from(path)))
|
||||||
|
}
|
||||||
|
_ => Err(miette::miette!("Unknown item")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ServiceItemKind {
|
impl ServiceItemKind {
|
||||||
pub fn title(&self) -> String {
|
pub fn title(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ use crate::core::{
|
||||||
self, Presentation, add_presentation_to_db,
|
self, Presentation, add_presentation_to_db,
|
||||||
update_presentation_in_db,
|
update_presentation_in_db,
|
||||||
},
|
},
|
||||||
service_items::{ServiceItem, ServiceTrait},
|
service_items::ServiceItem,
|
||||||
songs::{self, Song, update_song_in_db},
|
songs::{self, Song, update_song_in_db},
|
||||||
videos::{self, Video, update_video_in_db},
|
videos::{self, Video, update_video_in_db},
|
||||||
};
|
};
|
||||||
|
|
@ -100,6 +100,7 @@ pub enum Message {
|
||||||
Error(String),
|
Error(String),
|
||||||
OpenContext(i32),
|
OpenContext(i32),
|
||||||
None,
|
None,
|
||||||
|
AddFiles(Vec<ServiceItemKind>),
|
||||||
AddImages(Option<Vec<Image>>),
|
AddImages(Option<Vec<Image>>),
|
||||||
AddVideos(Option<Vec<Video>>),
|
AddVideos(Option<Vec<Video>>),
|
||||||
AddPresentations(Option<Vec<Presentation>>),
|
AddPresentations(Option<Vec<Presentation>>),
|
||||||
|
|
@ -561,6 +562,55 @@ impl<'a> Library {
|
||||||
self.selected_items = Some(items.to_vec());
|
self.selected_items = Some(items.to_vec());
|
||||||
self.context_menu = Some(index);
|
self.context_menu = Some(index);
|
||||||
}
|
}
|
||||||
|
Message::AddFiles(items) => {
|
||||||
|
for item in items {
|
||||||
|
match item {
|
||||||
|
ServiceItemKind::Song(song) => {
|
||||||
|
let Some(e) = self
|
||||||
|
.song_library
|
||||||
|
.add_item(song)
|
||||||
|
.err()
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
error!(?e);
|
||||||
|
}
|
||||||
|
ServiceItemKind::Video(video) => {
|
||||||
|
let Some(e) = self
|
||||||
|
.video_library
|
||||||
|
.add_item(video)
|
||||||
|
.err()
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
error!(?e);
|
||||||
|
}
|
||||||
|
ServiceItemKind::Image(image) => {
|
||||||
|
let Some(e) = self
|
||||||
|
.image_library
|
||||||
|
.add_item(image)
|
||||||
|
.err()
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
error!(?e);
|
||||||
|
}
|
||||||
|
ServiceItemKind::Presentation(
|
||||||
|
presentation,
|
||||||
|
) => {
|
||||||
|
let Some(e) = self
|
||||||
|
.presentation_library
|
||||||
|
.add_item(presentation)
|
||||||
|
.err()
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
error!(?e);
|
||||||
|
}
|
||||||
|
ServiceItemKind::Content(slide) => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Action::None
|
Action::None
|
||||||
}
|
}
|
||||||
|
|
@ -572,7 +622,7 @@ impl<'a> Library {
|
||||||
let presentation_library =
|
let presentation_library =
|
||||||
self.library_item(&self.presentation_library);
|
self.library_item(&self.presentation_library);
|
||||||
|
|
||||||
column![
|
let library_column = column![
|
||||||
text::heading("Library").center().width(Length::Fill),
|
text::heading("Library").center().width(Length::Fill),
|
||||||
cosmic::iced::widget::horizontal_rule(1),
|
cosmic::iced::widget::horizontal_rule(1),
|
||||||
song_library,
|
song_library,
|
||||||
|
|
@ -582,8 +632,67 @@ impl<'a> Library {
|
||||||
]
|
]
|
||||||
.height(Length::Fill)
|
.height(Length::Fill)
|
||||||
.padding(10)
|
.padding(10)
|
||||||
.spacing(10)
|
.spacing(10);
|
||||||
.into()
|
let library_dnd = dnd_destination(
|
||||||
|
library_column,
|
||||||
|
vec![
|
||||||
|
"image/png".into(),
|
||||||
|
"image/jpg".into(),
|
||||||
|
"image/heif".into(),
|
||||||
|
"image/gif".into(),
|
||||||
|
"video/mp4".into(),
|
||||||
|
"video/AV1".into(),
|
||||||
|
"video/H264".into(),
|
||||||
|
"video/H265".into(),
|
||||||
|
"video/mpeg".into(),
|
||||||
|
"video/mkv".into(),
|
||||||
|
"video/webm".into(),
|
||||||
|
"video/ogg".into(),
|
||||||
|
"video/vnd.youtube.yt".into(),
|
||||||
|
"video/x-matroska".into(),
|
||||||
|
"application/pdf".into(),
|
||||||
|
"text/html".into(),
|
||||||
|
"text/md".into(),
|
||||||
|
"text/org".into(),
|
||||||
|
"text/uri-list".into(),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.on_enter(|_, _, mimes| {
|
||||||
|
warn!(?mimes);
|
||||||
|
Message::None
|
||||||
|
})
|
||||||
|
.on_finish(|mime, data, action, _, _| {
|
||||||
|
// warn!(?mime, ?data, ?action);
|
||||||
|
match mime.as_str() {
|
||||||
|
"text/uri-list" => {
|
||||||
|
let Ok(text) = str::from_utf8(&data) else {
|
||||||
|
return Message::None;
|
||||||
|
};
|
||||||
|
let mut items = Vec::new();
|
||||||
|
for line in text.lines() {
|
||||||
|
let Ok(url) = url::Url::parse(line) else {
|
||||||
|
error!(
|
||||||
|
?line,
|
||||||
|
"problem parsing this file url"
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let Ok(path) = url.to_file_path() else {
|
||||||
|
error!(?url, "invalid file URL");
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let item = ServiceItemKind::try_from(path);
|
||||||
|
match item {
|
||||||
|
Ok(item) => items.push(item),
|
||||||
|
Err(e) => error!(?e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Message::AddFiles(items)
|
||||||
|
}
|
||||||
|
_ => Message::None,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
container(library_dnd).padding(2).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn library_item<T>(
|
pub fn library_item<T>(
|
||||||
|
|
@ -767,38 +876,7 @@ impl<'a> Library {
|
||||||
);
|
);
|
||||||
let library_column =
|
let library_column =
|
||||||
column![library_toolbar, items].spacing(3);
|
column![library_toolbar, items].spacing(3);
|
||||||
let library_dnd = dnd_destination(
|
Container::new(library_column).padding(5)
|
||||||
library_column,
|
|
||||||
vec![
|
|
||||||
"image/png".into(),
|
|
||||||
"image/jpg".into(),
|
|
||||||
"image/heif".into(),
|
|
||||||
"image/gif".into(),
|
|
||||||
"video/mp4".into(),
|
|
||||||
"video/AV1".into(),
|
|
||||||
"video/H264".into(),
|
|
||||||
"video/H265".into(),
|
|
||||||
"video/mpeg".into(),
|
|
||||||
"video/mkv".into(),
|
|
||||||
"video/webm".into(),
|
|
||||||
"video/ogg".into(),
|
|
||||||
"video/vnd.youtube.yt".into(),
|
|
||||||
"video/x-matroska".into(),
|
|
||||||
"application/pdf".into(),
|
|
||||||
"text/html".into(),
|
|
||||||
"text/md".into(),
|
|
||||||
"text/org".into(),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
.on_enter(|_, _, mimes| {
|
|
||||||
warn!(?mimes);
|
|
||||||
Message::None
|
|
||||||
})
|
|
||||||
.on_finish(|mime, data, action, _, _| {
|
|
||||||
warn!(?mime, ?data, ?action);
|
|
||||||
Message::None
|
|
||||||
});
|
|
||||||
Container::new(library_dnd).padding(5)
|
|
||||||
} else {
|
} else {
|
||||||
Container::new(Space::new(0, 0))
|
Container::new(Space::new(0, 0))
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue