changing presenter to use an action instead of the Task<Message>

This also helped me to find a bug in the system where we weren't
changing the audio if the slide we change to doesn't have audio.
This commit is contained in:
Chris Cochrun 2025-03-24 21:58:40 -05:00
parent d8699721b7
commit 4500fe7bf1
3 changed files with 49 additions and 46 deletions

View file

@ -8,9 +8,7 @@ use cosmic::app::{Core, Settings, Task};
use cosmic::iced::clipboard::dnd::DndAction; use cosmic::iced::clipboard::dnd::DndAction;
use cosmic::iced::keyboard::{Key, Modifiers}; use cosmic::iced::keyboard::{Key, Modifiers};
use cosmic::iced::window::{Mode, Position}; use cosmic::iced::window::{Mode, Position};
use cosmic::iced::{ use cosmic::iced::{self, event, window, Length, Padding, Point};
self, event, window, Color, Length, Padding, Point,
};
use cosmic::iced_futures::Subscription; use cosmic::iced_futures::Subscription;
use cosmic::iced_widget::{column, row}; use cosmic::iced_widget::{column, row};
use cosmic::widget::dnd_destination::DragId; use cosmic::widget::dnd_destination::DragId;
@ -28,7 +26,6 @@ use cosmic::{widget::Container, Theme};
use crisp::types::Value; use crisp::types::Value;
use lisp::parse_lisp; use lisp::parse_lisp;
use miette::{miette, Result}; use miette::{miette, Result};
use sqlx::{SqliteConnection, SqlitePool};
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::fs::read_to_string; use std::fs::read_to_string;
use std::path::PathBuf; use std::path::PathBuf;
@ -304,13 +301,14 @@ impl cosmic::Application for App {
let editor_toggle = toggler(self.editor_mode.is_some()) let editor_toggle = toggler(self.editor_mode.is_some())
.label("Editor") .label("Editor")
.spacing(10) .spacing(10)
.width(Length::Shrink)
.on_toggle(Message::EditorToggle); .on_toggle(Message::EditorToggle);
let presenter_window = self.windows.get(1); let presenter_window = self.windows.get(1);
let text = if self.presentation_open { let text = if self.presentation_open {
text::body("Close Presentation") text::body("End Presentation")
} else { } else {
text::body("Open Presentation") text::body("Present")
}; };
vec![ vec![
@ -449,10 +447,14 @@ impl cosmic::Application for App {
video.set_muted(false); video.set_muted(false);
} }
} }
self.presenter.update(message).map(|x| { match self.presenter.update(message) {
// debug!(?x); // debug!(?x);
cosmic::app::Message::App(Message::None) // cosmic::app::Message::App(Message::None)
}) presenter::Action::Task(task) => task.map(|m| {
cosmic::app::Message::App(Message::Present(m))
}),
presenter::Action::None => Task::none(),
}
} }
Message::Library(message) => { Message::Library(message) => {
let mut song = Song::default(); let mut song = Song::default();

View file

@ -358,6 +358,8 @@ impl<'a> Library {
model.items.iter().enumerate().map( model.items.iter().enumerate().map(
|(index, item)| { |(index, item)| {
let service_item = item.to_service_item(); let service_item = item.to_service_item();
let drag_item =
self.single_item(index, item, model);
let visual_item = self let visual_item = self
.single_item(index, item, model) .single_item(index, item, model)
.map(|_| Message::None); .map(|_| Message::None);
@ -384,8 +386,6 @@ impl<'a> Library {
)), )),
) )
// .drag_icon(move |i| { // .drag_icon(move |i| {
// let drag_item =
// self.single_item(index, item, model);
// let state = // let state =
// drag_item.as_widget().state(); // drag_item.as_widget().state();
// (drag_item, state, i) // (drag_item, state, i)

View file

@ -50,6 +50,11 @@ pub(crate) struct Presenter {
current_font: Font, current_font: Font,
} }
pub enum Action {
Task(Task<Message>),
None,
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) enum Message { pub(crate) enum Message {
NextSlide, NextSlide,
@ -153,7 +158,7 @@ impl Presenter {
} }
} }
pub fn update(&mut self, message: Message) -> Task<Message> { pub fn update(&mut self, message: Message) -> Action {
match message { match message {
Message::NextSlide => { Message::NextSlide => {
debug!("next slide"); debug!("next slide");
@ -161,21 +166,21 @@ impl Presenter {
== self.current_slide_index == self.current_slide_index
{ {
debug!("no more slides"); debug!("no more slides");
return Task::none(); return Action::None;
} }
self.update(Message::SlideChange( return self.update(Message::SlideChange(
self.current_slide_index + 1, self.current_slide_index + 1,
)) ));
} }
Message::PrevSlide => { Message::PrevSlide => {
debug!("prev slide"); debug!("prev slide");
if 0 == self.current_slide_index { if 0 == self.current_slide_index {
debug!("beginning slides"); debug!("beginning slides");
return Task::none(); return Action::None;
} }
self.update(Message::SlideChange( return self.update(Message::SlideChange(
self.current_slide_index - 1, self.current_slide_index - 1,
)) ));
} }
Message::SlideChange(id) => { Message::SlideChange(id) => {
debug!(id, "slide changed"); debug!(id, "slide changed");
@ -224,24 +229,23 @@ impl Presenter {
match &self.audio { match &self.audio {
Some(aud) if aud != &audio => { Some(aud) if aud != &audio => {
self.audio = Some(audio.clone()); self.audio = Some(audio.clone());
tasks.push( tasks.push(self.start_audio());
self.update(Message::StartAudio),
);
} }
Some(_) => (), Some(_) => (),
None => { None => {
self.audio = Some(audio.clone()); self.audio = Some(audio.clone());
tasks.push( tasks.push(self.start_audio());
self.update(Message::StartAudio),
);
} }
}; };
} else { } else {
self.audio = None; self.audio = None;
tasks.push(self.update(Message::EndAudio)); self.update(Message::EndAudio);
} }
} else {
self.audio = None;
self.update(Message::EndAudio);
} }
Task::batch(tasks) return Action::Task(Task::batch(tasks));
} }
Message::ChangeFont(s) => { Message::ChangeFont(s) => {
let font_name = s.into_boxed_str(); let font_name = s.into_boxed_str();
@ -256,7 +260,6 @@ impl Presenter {
style, style,
}; };
self.current_font = font; self.current_font = font;
Task::none()
} }
Message::EndVideo => { Message::EndVideo => {
// if self.current_slide.video_loop() { // if self.current_slide.video_loop() {
@ -269,7 +272,6 @@ impl Presenter {
// } // }
// } // }
// } // }
Task::none()
} }
Message::StartVideo => { Message::StartVideo => {
if let Some(video) = &mut self.video { if let Some(video) = &mut self.video {
@ -277,7 +279,6 @@ impl Presenter {
video video
.set_looping(self.current_slide.video_loop()); .set_looping(self.current_slide.video_loop());
} }
Task::none()
} }
Message::VideoPos(position) => { Message::VideoPos(position) => {
if let Some(video) = &mut self.video { if let Some(video) = &mut self.video {
@ -294,20 +295,18 @@ impl Presenter {
), ),
} }
} }
Task::none()
} }
Message::VideoFrame => { Message::VideoFrame => {
if let Some(video) = &self.video { if let Some(video) = &self.video {
self.video_position = self.video_position =
video.position().as_secs_f32(); video.position().as_secs_f32();
} }
Task::none()
} }
Message::MissingPlugin(element) => { Message::MissingPlugin(element) => {
if let Some(video) = &mut self.video { if let Some(video) = &mut self.video {
video.set_paused(true); video.set_paused(true);
} }
Task::perform( return Action::Task(Task::perform(
async move { async move {
tokio::task::spawn_blocking(move || { tokio::task::spawn_blocking(move || {
match gst_pbutils::MissingPluginMessage::parse(&element) { match gst_pbutils::MissingPluginMessage::parse(&element) {
@ -337,32 +336,34 @@ impl Presenter {
.unwrap() .unwrap()
}, },
|x| x, |x| x,
) ));
} }
Message::HoveredSlide(slide) => { Message::HoveredSlide(slide) => {
self.hovered_slide = slide; self.hovered_slide = slide;
Task::none()
} }
Message::StartAudio => { Message::StartAudio => {
if let Some(audio) = &mut self.audio { return Action::Task(self.start_audio())
let audio = audio.clone();
Task::perform(
start_audio(Arc::clone(&self.sink.1), audio),
|_| Message::None,
)
} else {
Task::none()
}
} }
Message::EndAudio => { Message::EndAudio => {
self.sink.1.stop(); self.sink.1.stop();
Task::none()
} }
Message::None => Task::none(), Message::None => debug!("Presenter Message::None"),
Message::Error(error) => { Message::Error(error) => {
error!(error); error!(error);
Task::none()
} }
};
Action::None
}
fn start_audio(&mut self) -> Task<Message> {
if let Some(audio) = &mut self.audio {
let audio = audio.clone();
Task::perform(
start_audio(Arc::clone(&self.sink.1), audio),
|_| Message::None,
)
} else {
Task::none()
} }
} }