From 9ac58dd5464c9bd32e244cb3befc08d6f5439ea7 Mon Sep 17 00:00:00 2001
From: Chris Cochrun <chris@cochrun.xyz>
Date: Fri, 13 Dec 2024 23:40:48 -0600
Subject: [PATCH] async instead of thread based sound is working

---
 src/main.rs         |  29 +++--------
 src/ui/presenter.rs | 124 ++++++++++++++++++++++++++++++++------------
 2 files changed, 96 insertions(+), 57 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 7ad3219..9c716a2 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -381,29 +381,10 @@ impl cosmic::Application for App {
                         video.set_muted(false);
                     }
                 }
-                let task = self.presenter.update(message);
-                debug!("Past");
-                // let task = Task::perform(
-                //     async { debug!("inside async") },
-                //     |_| cosmic::app::Message::App(Message::None),
-                // );
-                // self.core.nav_bar_toggle();
-                task.then(move |x| {
+                self.presenter.update(message).map(|x| {
                     debug!(?x);
-                    Task::perform(
-                        async move {
-                            println!("hi");
-                            debug!(?x);
-                        },
-                        |_| cosmic::app::Message::App(Message::None),
-                    )
+                    cosmic::app::Message::App(Message::None)
                 })
-                // let task = task.map(|x| {
-                //     debug!(?x);
-                //     cosmic::app::Message::App(Message::None)
-                // });
-                // task.chain(Task::none())
-                // task
             }
             Message::File(file) => {
                 self.file = file;
@@ -520,7 +501,9 @@ impl cosmic::Application for App {
         let slide_preview = column![
             Space::with_height(Length::Fill),
             Container::new(
-                self.presenter.view().map(|m| Message::Present(m)),
+                self.presenter
+                    .view_preview()
+                    .map(|m| Message::Present(m)),
             )
             .align_bottom(Length::Fill),
             Container::new(if self.presenter.video.is_some() {
@@ -587,7 +570,7 @@ impl cosmic::Application for App {
             Container::new(row).center_y(Length::Fill),
             Container::new(
                 self.presenter
-                    .slide_preview()
+                    .preview_bar()
                     .map(|m| Message::Present(m))
             )
             .clip(true)
diff --git a/src/ui/presenter.rs b/src/ui/presenter.rs
index a41ca61..420e1e0 100644
--- a/src/ui/presenter.rs
+++ b/src/ui/presenter.rs
@@ -157,8 +157,8 @@ impl Presenter {
                     },
                     y: 0.0,
                 };
-                let op: Task<Message> =
-                    scroll_to(self.scroll_id.clone(), offset);
+                let mut tasks = vec![];
+                tasks.push(scroll_to(self.scroll_id.clone(), offset));
 
                 self.reset_video();
                 if let Some(audio) = &mut self.current_slide.audio() {
@@ -177,22 +177,24 @@ impl Presenter {
                         match &self.audio {
                             Some(aud) if aud != &audio => {
                                 self.audio = Some(audio.clone());
-                                let _ =
-                                    self.update(Message::StartAudio);
+                                tasks.push(
+                                    self.update(Message::StartAudio),
+                                );
                             }
                             Some(_) => (),
                             None => {
                                 self.audio = Some(audio.clone());
-                                let _ =
-                                    self.update(Message::StartAudio);
+                                tasks.push(
+                                    self.update(Message::StartAudio),
+                                );
                             }
-                        }
+                        };
                     } else {
                         self.audio = None;
                         let _ = self.update(Message::EndAudio);
                     }
                 }
-                op
+                Task::batch(tasks)
             }
             Message::EndVideo => {
                 // if self.current_slide.video_loop() {
@@ -246,13 +248,13 @@ impl Presenter {
             Message::StartAudio => {
                 if let Some(audio) = &mut self.audio {
                     let audio = audio.clone();
-                    debug!("hi");
-                    start_audio(Arc::clone(&self.sink.1), audio);
+                    Task::perform(
+                        start_audio(Arc::clone(&self.sink.1), audio),
+                        |_| Message::None,
+                    )
+                } else {
+                    Task::none()
                 }
-                Task::perform(
-                    async { debug!("inside async") },
-                    |_| Message::None,
-                )
             }
             Message::EndAudio => {
                 self.sink.1.stop();
@@ -263,6 +265,71 @@ impl Presenter {
     }
 
     pub fn view(&self) -> Element<Message> {
+        responsive(|size| {
+            let family = Family::Name("VictorMono Nerd Font");
+            let weight = Weight::Normal;
+            let stretch = Stretch::Normal;
+            let style = Style::Normal;
+            let font = Font {
+                family,
+                weight,
+                stretch,
+                style,
+            };
+            let font_size = if self.current_slide.font_size() > 0 {
+                (size.width / self.current_slide.font_size() as f32)
+                    * 3.0
+            } else {
+                50.0
+            };
+            let text = text(self.current_slide.text())
+                .size(font_size)
+                .font(font);
+            let text = Container::new(text).center(Length::Fill);
+            let black = Container::new(Space::new(0, 0))
+                .style(|_| {
+                    container::background(Background::Color(
+                        Color::BLACK,
+                    ))
+                })
+                .width(size.width)
+                .height(size.height);
+            let container = match self.current_slide.background().kind
+            {
+                BackgroundKind::Image => {
+                    let path =
+                        self.current_slide.background().path.clone();
+                    Container::new(
+                        image(path)
+                            .content_fit(ContentFit::Cover)
+                            .width(size.width)
+                            .height(size.height),
+                    )
+                }
+                BackgroundKind::Video => {
+                    if let Some(video) = &self.video {
+                        Container::new(
+                            VideoPlayer::new(video)
+                                .width(size.width)
+                                .height(size.width * 9.0 / 16.0)
+                                .on_end_of_stream(Message::EndVideo)
+                                .on_new_frame(Message::VideoFrame)
+                                .content_fit(ContentFit::Cover),
+                        )
+                    } else {
+                        Container::new(Space::new(0, 0))
+                    }
+                }
+            };
+            stack!(black, container.center(Length::Fill), text)
+                .width(Length::Fill)
+                .height(Length::Fill)
+                .into()
+        })
+        .into()
+    }
+
+    pub fn view_preview(&self) -> Element<Message> {
         responsive(|size| {
             let family = Family::Name("VictorMono Nerd Font");
             let weight = Weight::Normal;
@@ -327,7 +394,7 @@ impl Presenter {
         .into()
     }
 
-    pub fn slide_preview(&self) -> Element<Message> {
+    pub fn preview_bar(&self) -> Element<Message> {
         let mut items = vec![];
         for slide in self.slides.iter() {
             items.push(self.slide_delegate(slide));
@@ -474,23 +541,12 @@ impl Presenter {
     }
 }
 
-fn start_audio(sink: Arc<Sink>, audio: PathBuf) {
-    thread::spawn(move || {
-        let file = BufReader::new(File::open(audio).unwrap());
-        debug!(?file);
-        let source = Decoder::new(file).unwrap();
-        let empty = sink.empty();
-        let paused = sink.is_paused();
-        debug!(empty, paused);
-        sink.append(source);
-        let empty = sink.empty();
-        let paused = sink.is_paused();
-        debug!(empty, paused);
-        sink.sleep_until_end();
-        // tokio::time::sleep(Duration::from_secs(10));
-        // let stream = cosmic::iced::time::every(
-        //     cosmic::iced::time::Duration::from_secs(1),
-        // );
-        debug!(empty, paused, "Finished running");
-    });
+async fn start_audio(sink: Arc<Sink>, audio: PathBuf) {
+    let file = BufReader::new(File::open(audio).unwrap());
+    debug!(?file);
+    let source = Decoder::new(file).unwrap();
+    sink.append(source);
+    let empty = sink.empty();
+    let paused = sink.is_paused();
+    debug!(empty, paused, "Finished running");
 }