trying some dialogs
Some checks are pending
/ test (push) Waiting to run

This commit is contained in:
Chris Cochrun 2025-09-24 12:01:14 -05:00
parent a56ff6a022
commit 0d3f7180c9
4 changed files with 198 additions and 1100 deletions

1184
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -34,13 +34,13 @@ resvg = "0.45.1"
image = "0.25.8" image = "0.25.8"
rapidhash = "4.0.0" rapidhash = "4.0.0"
rapidfuzz = "0.5.0" rapidfuzz = "0.5.0"
dragking = { git = "https://github.com/airstrike/dragking" } # dragking = { git = "https://github.com/airstrike/dragking" }
# femtovg = { version = "0.16.0", features = ["wgpu"] } # femtovg = { version = "0.16.0", features = ["wgpu"] }
# wgpu = "26.0.1" # wgpu = "26.0.1"
# mupdf = "0.5.0" # mupdf = "0.5.0"
mupdf = { version = "0.5.0", git = "https://github.com/messense/mupdf-rs", rev="2425c1405b326165b06834dcc1ca859015f92787"} mupdf = { version = "0.5.0", git = "https://github.com/messense/mupdf-rs", rev="2425c1405b326165b06834dcc1ca859015f92787"}
# rfd = { version = "0.14.1" } rfd = { version = "0.15.4", default-features = false, features = ["xdg-portal"] }
[dependencies.libcosmic] [dependencies.libcosmic]
git = "https://github.com/pop-os/libcosmic" git = "https://github.com/pop-os/libcosmic"

View file

@ -13,7 +13,7 @@ use sqlx::{
pool::PoolConnection, query, query_as, Sqlite, SqliteConnection, pool::PoolConnection, query, query_as, Sqlite, SqliteConnection,
SqlitePool, SqlitePool,
}; };
use std::path::PathBuf; use std::path::{Path, PathBuf};
use tracing::error; use tracing::error;
#[derive( #[derive(
@ -25,6 +25,28 @@ pub struct Image {
pub path: PathBuf, pub path: PathBuf,
} }
impl From<PathBuf> for Image {
fn from(value: PathBuf) -> Self {
let title = value
.file_name()
.unwrap_or_default()
.to_str()
.unwrap_or_default()
.to_string();
Self {
id: 0,
title,
path: value.canonicalize().unwrap_or(value),
}
}
}
impl From<&Path> for Image {
fn from(value: &Path) -> Self {
Self::from(value.to_owned())
}
}
impl From<&Image> for Value { impl From<&Image> for Value {
fn from(value: &Image) -> Self { fn from(value: &Image) -> Self {
Self::List(vec![Self::Symbol(Symbol("image".into()))]) Self::List(vec![Self::Symbol(Symbol("image".into()))])

View file

@ -1,6 +1,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use cosmic::{ use cosmic::{
dialog::file_chooser::open::Dialog,
iced::{ iced::{
alignment::Vertical, clipboard::dnd::DndAction, alignment::Vertical, clipboard::dnd::DndAction,
futures::FutureExt, Background, Border, Color, Length, futures::FutureExt, Background, Border, Color, Length,
@ -75,7 +76,7 @@ pub enum Action {
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub(crate) enum Message { pub enum Message {
AddItem, AddItem,
DeleteItem((LibraryKind, i32)), DeleteItem((LibraryKind, i32)),
OpenItem(Option<(LibraryKind, i32)>), OpenItem(Option<(LibraryKind, i32)>),
@ -95,6 +96,8 @@ pub(crate) enum Message {
Error(String), Error(String),
OpenContext(i32), OpenContext(i32),
None, None,
AddImages(Option<Vec<Image>>),
AddVideos(Option<Vec<Video>>),
} }
impl<'a> Library { impl<'a> Library {
@ -295,26 +298,16 @@ impl<'a> Library {
.ok() .ok()
} }
LibraryKind::Video => { LibraryKind::Video => {
let video = Video::default(); return Action::Task(Task::perform(
self.video_library add_videos(),
.add_item(video) |videos| Message::AddVideos(videos),
.map(|_| { ));
let index =
self.video_library.items.len();
(LibraryKind::Video, index as i32)
})
.ok()
} }
LibraryKind::Image => { LibraryKind::Image => {
let image = Image::default(); return Action::Task(Task::perform(
self.image_library add_images(),
.add_item(image) |images| Message::AddImages(images),
.map(|_| { ));
let index =
self.image_library.items.len();
(LibraryKind::Image, index as i32)
})
.ok()
} }
LibraryKind::Presentation => { LibraryKind::Presentation => {
let presentation = Presentation::default(); let presentation = Presentation::default();
@ -335,6 +328,37 @@ impl<'a> Library {
}; };
return self.update(Message::OpenItem(item)); return self.update(Message::OpenItem(item));
} }
Message::AddVideos(videos) => {
if let Some(videos) = videos {
for video in videos {
if let Err(e) =
self.video_library.add_item(video)
{
error!(?e);
}
}
}
return self.update(Message::OpenItem(Some((
LibraryKind::Video,
self.video_library.items.len() as i32 - 1,
))));
}
Message::AddImages(images) => {
debug!(?images);
if let Some(images) = images {
for image in images {
if let Err(e) =
self.image_library.add_item(image)
{
error!(?e);
}
}
}
return self.update(Message::OpenItem(Some((
LibraryKind::Image,
self.image_library.items.len() as i32 - 1,
))));
}
Message::OpenItem(item) => { Message::OpenItem(item) => {
debug!(?item); debug!(?item);
self.editing_item = item; self.editing_item = item;
@ -943,6 +967,30 @@ impl<'a> Library {
// } // }
} }
async fn add_images() -> Option<Vec<Image>> {
debug!("here man");
let paths =
Dialog::new().title("pick image").open_files().await.ok()?;
Some(
paths
.urls()
.iter()
.map(|path| {
Image::from(path.to_file_path().expect("oops"))
})
.collect(),
)
}
async fn add_videos() -> Option<Vec<Video>> {
let paths = rfd::AsyncFileDialog::new()
.set_title("Pick image")
.pick_files()
.await?;
debug!(?paths);
Some(paths.iter().map(|path| Video::from(path.path())).collect())
}
fn update_in_db( fn update_in_db(
song: &Song, song: &Song,
conn: PoolConnection<Sqlite>, conn: PoolConnection<Sqlite>,