This commit is contained in:
parent
f9f3f7f95f
commit
20843f1b2c
3 changed files with 86 additions and 21 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{borrow::Cow, mem::replace};
|
use std::{borrow::Cow, mem::replace, path::{Path, PathBuf}};
|
||||||
|
|
||||||
use cosmic::iced::clipboard::mime::{AllowedMimeTypes, AsMimeTypes};
|
use cosmic::iced::clipboard::mime::{AllowedMimeTypes, AsMimeTypes};
|
||||||
use miette::{IntoDiagnostic, Result, miette};
|
use miette::{IntoDiagnostic, Result, miette};
|
||||||
|
|
@ -23,18 +23,29 @@ pub enum LibraryKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Debug, Clone, PartialEq, Eq, Copy, Hash, Serialize, Deserialize,
|
Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize,
|
||||||
)]
|
)]
|
||||||
pub struct KindWrapper(pub (LibraryKind, i32));
|
pub struct KindWrapper(pub (LibraryKind, i32));
|
||||||
|
|
||||||
|
impl From<PathBuf> for LibraryKind {
|
||||||
|
fn from(value: PathBuf) -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl TryFrom<(Vec<u8>, String)> for KindWrapper {
|
impl TryFrom<(Vec<u8>, String)> for KindWrapper {
|
||||||
type Error = miette::Error;
|
type Error = miette::Error;
|
||||||
|
|
||||||
fn try_from(
|
fn try_from(
|
||||||
value: (Vec<u8>, String),
|
value: (Vec<u8>, String),
|
||||||
) -> std::result::Result<Self, Self::Error> {
|
) -> std::result::Result<Self, Self::Error> {
|
||||||
debug!(?value);
|
let (data, mime) = value;
|
||||||
ron::de::from_bytes(&value.0).into_diagnostic()
|
match mime.as_str() {
|
||||||
|
"application/service-item" => {
|
||||||
|
ron::de::from_bytes(&data).into_diagnostic()
|
||||||
|
}
|
||||||
|
_ => Err(miette!("Wrong mime type: {mime}"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use cosmic::iced::clipboard::mime::{AllowedMimeTypes, AsMimeTypes};
|
use cosmic::iced::clipboard::mime::{AllowedMimeTypes, AsMimeTypes};
|
||||||
use crisp::types::{Keyword, Symbol, Value};
|
use crisp::types::{Keyword, Symbol, Value};
|
||||||
use miette::{IntoDiagnostic, Result};
|
use miette::{IntoDiagnostic, Result, miette};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tracing::{debug, error};
|
use tracing::{debug, error};
|
||||||
|
|
||||||
|
|
@ -48,13 +49,8 @@ impl TryFrom<(Vec<u8>, String)> for ServiceItem {
|
||||||
value: (Vec<u8>, String),
|
value: (Vec<u8>, String),
|
||||||
) -> std::result::Result<Self, Self::Error> {
|
) -> std::result::Result<Self, Self::Error> {
|
||||||
let (data, mime) = value;
|
let (data, mime) = value;
|
||||||
match mime.as_str() {
|
debug!(?mime);
|
||||||
"application/service_item" => {}
|
ron::de::from_bytes(&data).into_diagnostic()
|
||||||
"text/uri-list" => {}
|
|
||||||
"x-special/gnome-copied-files" => {}
|
|
||||||
}
|
|
||||||
debug!(?value);
|
|
||||||
ron::de::from_bytes(&value.0).into_diagnostic()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -86,6 +82,29 @@ impl AsMimeTypes for ServiceItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TryFrom<PathBuf> for ServiceItem {
|
||||||
|
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::from(&Image::from(path)))
|
||||||
|
}
|
||||||
|
"mp4" | "mkv" | "webm" => {
|
||||||
|
Ok(Self::from(&Video::from(path)))
|
||||||
|
}
|
||||||
|
_ => Err(miette!("Unkown service item")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<&ServiceItem> for Value {
|
impl From<&ServiceItem> for Value {
|
||||||
fn from(value: &ServiceItem) -> Self {
|
fn from(value: &ServiceItem) -> Self {
|
||||||
match &value.kind {
|
match &value.kind {
|
||||||
|
|
|
||||||
53
src/main.rs
53
src/main.rs
|
|
@ -167,6 +167,7 @@ enum Message {
|
||||||
AddSelectServiceItem(usize),
|
AddSelectServiceItem(usize),
|
||||||
HoveredServiceItem(Option<usize>),
|
HoveredServiceItem(Option<usize>),
|
||||||
AddServiceItem(usize, KindWrapper),
|
AddServiceItem(usize, KindWrapper),
|
||||||
|
AddServiceItemsFiles(usize, Vec<ServiceItem>),
|
||||||
RemoveServiceItem(usize),
|
RemoveServiceItem(usize),
|
||||||
AddServiceItemDrop(usize),
|
AddServiceItemDrop(usize),
|
||||||
AppendServiceItem(ServiceItem),
|
AppendServiceItem(ServiceItem),
|
||||||
|
|
@ -1231,6 +1232,13 @@ impl cosmic::Application for App {
|
||||||
self.presenter.update_items(self.service.clone());
|
self.presenter.update_items(self.service.clone());
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
Message::AddServiceItemsFiles(index, items) => {
|
||||||
|
for item in items {
|
||||||
|
self.service.insert(index, item);
|
||||||
|
}
|
||||||
|
self.presenter.update_items(self.service.clone());
|
||||||
|
Task::none()
|
||||||
|
}
|
||||||
Message::RemoveServiceItem(index) => {
|
Message::RemoveServiceItem(index) => {
|
||||||
self.service.remove(index);
|
self.service.remove(index);
|
||||||
self.presenter.update_items(self.service.clone());
|
self.presenter.update_items(self.service.clone());
|
||||||
|
|
@ -1786,17 +1794,44 @@ where
|
||||||
.gap(cosmic::theme::spacing().space_xs);
|
.gap(cosmic::theme::spacing().space_xs);
|
||||||
dnd_destination(
|
dnd_destination(
|
||||||
tooltip,
|
tooltip,
|
||||||
vec!["application/service-item".into()],
|
vec!["application/service-item".into(), "text/uri-list".into(), "x-special/gnome-copied-files".into()],
|
||||||
)
|
)
|
||||||
.on_finish(move |mime, data, _, _, _| {
|
.on_finish(move |mime, data, _, _, _| {
|
||||||
let Ok(item) =
|
match mime.as_str() {
|
||||||
KindWrapper::try_from((data, mime))
|
"application/service-item" => {
|
||||||
else {
|
let Ok(item) =
|
||||||
error!("couldn't drag in Service item");
|
KindWrapper::try_from((data, mime))
|
||||||
return Message::None;
|
else {
|
||||||
};
|
error!("couldn't drag in Service item");
|
||||||
debug!(?item, index, "adding Service item");
|
return Message::None;
|
||||||
Message::AddServiceItem(index, item)
|
};
|
||||||
|
debug!(?item, index, "adding Service item");
|
||||||
|
Message::AddServiceItem(index, item)
|
||||||
|
}
|
||||||
|
"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 = ServiceItem::try_from(path);
|
||||||
|
match item {
|
||||||
|
Ok(item) => items.push(item),
|
||||||
|
Err(e) => error!(?e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Message::AddServiceItemsFiles(index, items)
|
||||||
|
}
|
||||||
|
_ => Message::None
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue