almost have video adding and editing working
Some checks are pending
/ test (push) Waiting to run

This commit is contained in:
Chris Cochrun 2025-09-24 16:22:37 -05:00
parent 8068b57e71
commit 09654aef94
4 changed files with 153 additions and 104 deletions

View file

@ -15,7 +15,7 @@ use sqlx::{
SqlitePool, SqlitePool,
}; };
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use tracing::error; use tracing::{debug, error};
#[derive( #[derive(
Clone, Debug, Default, PartialEq, Serialize, Deserialize, Clone, Debug, Default, PartialEq, Serialize, Deserialize,

View file

@ -50,6 +50,7 @@ use ui::EditorMode;
use crate::core::kinds::ServiceItemKind; use crate::core::kinds::ServiceItemKind;
use crate::ui::text_svg::{self}; use crate::ui::text_svg::{self};
use crate::ui::video_editor::{self, VideoEditor};
use crate::ui::widgets::draggable; use crate::ui::widgets::draggable;
pub mod core; pub mod core;
@ -124,6 +125,7 @@ struct App {
library_open: bool, library_open: bool,
editor_mode: Option<EditorMode>, editor_mode: Option<EditorMode>,
song_editor: SongEditor, song_editor: SongEditor,
video_editor: VideoEditor,
searching: bool, searching: bool,
search_query: String, search_query: String,
search_results: Vec<ServiceItem>, search_results: Vec<ServiceItem>,
@ -171,6 +173,7 @@ enum Message {
Save(Option<PathBuf>), Save(Option<PathBuf>),
SaveAs, SaveAs,
OpenSettings, OpenSettings,
VideoEditor(video_editor::Message),
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -324,6 +327,7 @@ impl cosmic::Application for App {
library_open: true, library_open: true,
editor_mode: None, editor_mode: None,
song_editor, song_editor,
video_editor: VideoEditor::new(),
searching: false, searching: false,
search_results: vec![], search_results: vec![],
search_query: String::new(), search_query: String::new(),
@ -763,6 +767,27 @@ impl cosmic::Application for App {
song_editor::Action::None => Task::none(), song_editor::Action::None => Task::none(),
} }
} }
Message::VideoEditor(message) => {
match self.video_editor.update(message) {
video_editor::Action::Task(task) => {
task.map(|m| {
cosmic::Action::App(Message::VideoEditor(
m,
))
})
}
video_editor::Action::UpdateVideo(video) => {
if let Some(_) = &mut self.library {
self.update(Message::Library(
library::Message::UpdateVideo(video),
))
} else {
Task::none()
}
}
video_editor::Action::None => Task::none(),
}
}
Message::Present(message) => { Message::Present(message) => {
// debug!(?message); // debug!(?message);
if self.presentation_open if self.presentation_open
@ -917,53 +942,69 @@ impl cosmic::Application for App {
let mut song = Song::default(); let mut song = Song::default();
if let Some(library) = &mut self.library { if let Some(library) = &mut self.library {
match library.update(message) { match library.update(message) {
library::Action::OpenItem(None) => { library::Action::OpenItem(None) => {
return Task::none(); return Task::none();
} }
library::Action::Task(task) => { library::Action::Task(task) => {
return task.map(|message| { return task.map(|message| {
cosmic::Action::App(Message::Library( cosmic::Action::App(Message::Library(
message, message,
)) ))
}); });
} }
library::Action::None => return Task::none(), library::Action::None => return Task::none(),
library::Action::OpenItem(Some(( library::Action::OpenItem(Some((
kind, kind,
index, index,
))) => { ))) => {
debug!( match kind {
"Should get song at index: {:?}", core::model::LibraryKind::Song => {
index debug!(
); "Should get song at index: {:?}",
let Some(lib_song) = index
library.get_song(index) );
else { let Some(lib_song) =
return Task::none(); library.get_song(index)
}; else {
self.editor_mode = Some(kind.into()); return Task::none();
song = lib_song.to_owned(); };
debug!( self.editor_mode = Some(kind.into());
"Should change songs to: {:?}", song = lib_song.to_owned();
song debug!(
); "Should change songs to: {:?}",
} song
library::Action::DraggedItem( );
service_item,
) => { return self.update(Message::SongEditor(
debug!("hi"); song_editor::Message::ChangeSong(song),
self.library_dragged_item = ));
Some(service_item); },
// self.nav_model core::model::LibraryKind::Video => {
// .insert() let Some(lib_video) = library.get_video(index) else {
// .text(service_item.title.clone()) return Task::none();
// .data(service_item); };
} self.editor_mode = Some(kind.into());
} let video = lib_video.to_owned();
return self.update(Message::VideoEditor(video_editor::Message::ChangeVideo(video)));
},
core::model::LibraryKind::Image => todo!(),
core::model::LibraryKind::Presentation => todo!(),
}
}
library::Action::DraggedItem(
service_item,
) => {
debug!("hi");
self.library_dragged_item =
Some(service_item);
// self.nav_model
// .insert()
// .text(service_item.title.clone())
// .data(service_item);
}
}
} }
self.update(Message::SongEditor( Task::none()
song_editor::Message::ChangeSong(song),
))
} }
Message::File(file) => { Message::File(file) => {
self.file = file; self.file = file;
@ -998,16 +1039,16 @@ impl cosmic::Application for App {
Message::WindowOpened(id) => { Message::WindowOpened(id) => {
debug!(?id, "Window opened"); debug!(?id, "Window opened");
if self.cli_mode if self.cli_mode
|| id > self.core.main_window_id().expect("Cosmic core seems to be missing a main window, was this started in cli mode?") || id > self.core.main_window_id().expect("Cosmic core seems to be missing a main window, was this started in cli mode?")
{ {
self.presentation_open = true; self.presentation_open = true;
if let Some(video) = &mut self.presenter.video { if let Some(video) = &mut self.presenter.video {
video.set_muted(false); video.set_muted(false);
} }
window::change_mode(id, Mode::Fullscreen) window::change_mode(id, Mode::Fullscreen)
} else { } else {
Task::none() Task::none()
} }
} }
Message::WindowClosed(id) => { Message::WindowClosed(id) => {
warn!("Closing window: {id}"); warn!("Closing window: {id}");
@ -1283,8 +1324,20 @@ impl cosmic::Application for App {
Container::new(horizontal_space().width(0)) Container::new(horizontal_space().width(0))
}; };
let song_editor = let editor = self.editor_mode.as_ref().map_or_else(
self.song_editor.view().map(Message::SongEditor); || Element::from(Space::new(0, 0)),
|mode| match mode {
EditorMode::Song => {
self.song_editor.view().map(Message::SongEditor)
}
EditorMode::Image => todo!(),
EditorMode::Video => {
self.video_editor.view().map(Message::VideoEditor)
}
EditorMode::Presentation => todo!(),
EditorMode::Slide => todo!(),
},
);
let service_row = row![ let service_row = row![
service_list, service_list,
@ -1331,12 +1384,13 @@ impl cosmic::Application for App {
Container::new(horizontal_space()) Container::new(horizontal_space())
}; };
let main_area = if let Some(editor) = &self.editor_mode { let main_area = self.editor_mode.as_ref().map_or_else(
container(song_editor) || Container::new(service_row).center_y(Length::Fill),
.padding(cosmic::theme::spacing().space_xxl) |_| {
} else { container(editor)
Container::new(service_row).center_y(Length::Fill) .padding(cosmic::theme::spacing().space_xxl)
}; },
);
let column = column![ let column = column![
row![ row![

View file

@ -399,7 +399,9 @@ impl<'a> Library {
Ok(()) => { Ok(()) => {
return Action::Task( return Action::Task(
Task::future(self.db.acquire()).and_then( Task::future(self.db.acquire()).and_then(
move |conn| update_in_db(&song, conn), move |conn| {
song_db_update(&song, conn)
},
), ),
); );
} }
@ -463,13 +465,7 @@ impl<'a> Library {
return Action::Task( return Action::Task(
Task::future(self.db.acquire()).and_then( Task::future(self.db.acquire()).and_then(
move |conn| { move |conn| {
Task::perform( video_db_update(&video, conn)
update_video_in_db(
video.clone(),
conn,
),
|_| Message::VideoChanged,
)
}, },
), ),
); );
@ -477,7 +473,7 @@ impl<'a> Library {
Err(_) => todo!(), Err(_) => todo!(),
} }
} }
Message::VideoChanged => (), Message::VideoChanged => debug!("vid shoulda changed"),
Message::UpdatePresentation(presentation) => { Message::UpdatePresentation(presentation) => {
let Some((kind, index)) = self.editing_item else { let Some((kind, index)) = self.editing_item else {
error!("Not editing an item"); error!("Not editing an item");
@ -938,37 +934,12 @@ impl<'a> Library {
items.into_iter().map(|item| item.1).collect() items.into_iter().map(|item| item.1).collect()
} }
// fn update_item<C: Content>(self, item: C) -> Task<Message> { pub fn get_video(&self, index: i32) -> Option<&Video> {
// let Some((kind, index)) = self.editing_item else { self.video_library.get_item(index)
// error!("Not editing an item"); }
// return Task::none();
// };
// match kind {
// LibraryKind::Song => todo!(),
// LibraryKind::Video => todo!(),
// LibraryKind::Image => {
// match self
// .image_library
// .update_item(item as Image, index)
// {
// Ok(_) => Task::future(self.db.acquire())
// .and_then(|conn| {
// Task::perform(
// update_image_in_db(item, conn),
// |_| Message::ImageChanged,
// )
// }),
// Err(_) => todo!(),
// }
// }
// LibraryKind::Presentation => todo!(),
// }
// }
} }
async fn add_images() -> Option<Vec<Image>> { async fn add_images() -> Option<Vec<Image>> {
debug!("here man");
let paths = let paths =
Dialog::new().title("pick image").open_files().await.ok()?; Dialog::new().title("pick image").open_files().await.ok()?;
Some( Some(
@ -983,7 +954,6 @@ async fn add_images() -> Option<Vec<Image>> {
} }
async fn add_videos() -> Option<Vec<Video>> { async fn add_videos() -> Option<Vec<Video>> {
debug!("here man");
let paths = let paths =
Dialog::new().title("pick video").open_files().await.ok()?; Dialog::new().title("pick video").open_files().await.ok()?;
Some( Some(
@ -997,7 +967,31 @@ async fn add_videos() -> Option<Vec<Video>> {
) )
} }
fn update_in_db( fn video_db_update(
video: &Video,
conn: PoolConnection<Sqlite>,
) -> Task<Message> {
let video_title = video.title.clone();
warn!("Should have updated video: {:?}", video_title);
Task::perform(
update_video_in_db(video.to_owned(), conn).map(move |r| {
match r {
Ok(()) => {
warn!(
"Should have updated video: {:?}",
video_title
);
}
Err(e) => {
error!(?e);
}
}
}),
|()| Message::VideoChanged,
)
}
fn song_db_update(
song: &Song, song: &Song,
conn: PoolConnection<Sqlite>, conn: PoolConnection<Sqlite>,
) -> Task<Message> { ) -> Task<Message> {

View file

@ -8,6 +8,7 @@ pub mod slide_editor;
pub mod song_editor; pub mod song_editor;
pub mod text_svg; pub mod text_svg;
pub mod video; pub mod video;
pub mod video_editor;
pub mod widgets; pub mod widgets;
pub enum EditorMode { pub enum EditorMode {