diff --git a/src/Cargo.lock b/src/Cargo.lock index cf0f736..614b350 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -69,13 +69,32 @@ dependencies = [ "futures-lite 1.13.0", "log", "parking", - "polling", - "rustix", + "polling 2.8.0", + "rustix 0.37.27", "slab", "socket2", "waker-fn", ] +[[package]] +name = "async-io" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6afaa937395a620e33dc6a742c593c01aced20aa376ffb0f628121198578ccc7" +dependencies = [ + "async-lock 3.2.0", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite 2.1.0", + "parking", + "polling 3.3.1", + "rustix 0.38.28", + "slab", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "async-lock" version = "2.8.0" @@ -96,6 +115,42 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "async-process" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15c1cd5d253ecac3d3cf15e390fd96bd92a13b1d14497d81abf077304794fb04" +dependencies = [ + "async-channel 2.1.1", + "async-io 2.2.2", + "async-lock 3.2.0", + "async-signal", + "blocking", + "cfg-if", + "event-listener 4.0.1", + "futures-lite 2.1.0", + "rustix 0.38.28", + "windows-sys 0.52.0", +] + +[[package]] +name = "async-signal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" +dependencies = [ + "async-io 2.2.2", + "async-lock 2.8.0", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix 0.38.28", + "signal-hook-registry", + "slab", + "windows-sys 0.48.0", +] + [[package]] name = "async-task" version = "4.6.0" @@ -948,7 +1003,10 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aeee267a1883f7ebef3700f262d2d54de95dfaf38189015a74fdc4e0c7ad8143" dependencies = [ + "fastrand 2.0.1", "futures-core", + "futures-io", + "parking", "pin-project-lite", ] @@ -1522,6 +1580,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "lib" version = "0.1.0" +dependencies = [ + "async-process", +] [[package]] name = "libc" @@ -1535,6 +1596,12 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +[[package]] +name = "linux-raw-sys" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" + [[package]] name = "lock_api" version = "0.4.11" @@ -1993,6 +2060,20 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "polling" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf63fa624ab313c11656b4cda960bfc46c410187ad493c41f6ba2d8c1e991c9e" +dependencies = [ + "cfg-if", + "concurrent-queue", + "pin-project-lite", + "rustix 0.38.28", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -2204,7 +2285,7 @@ version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fe664af397d2b6a13a8ba1d172a2b5c87c6c5149039edbf8fa122b98c9ed96f" dependencies = [ - "async-io", + "async-io 1.13.0", "block", "dispatch", "futures-util", @@ -2254,10 +2335,23 @@ dependencies = [ "errno", "io-lifetimes", "libc", - "linux-raw-sys", + "linux-raw-sys 0.3.8", "windows-sys 0.48.0", ] +[[package]] +name = "rustix" +version = "0.38.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys 0.4.12", + "windows-sys 0.52.0", +] + [[package]] name = "ryu" version = "1.0.16" @@ -2387,6 +2481,15 @@ dependencies = [ "digest", ] +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + [[package]] name = "simd-adler32" version = "0.3.7" diff --git a/src/src/main.rs b/src/src/main.rs index 4b0b881..1689d31 100644 --- a/src/src/main.rs +++ b/src/src/main.rs @@ -1,6 +1,7 @@ #![allow(non_snake_case)] // import the prelude to get access to the `rsx!` macro and the `Scope` and `Element` types use dioxus::prelude::*; +use dioxus::hooks::use_future; use lib; use base64::{engine::general_purpose, Engine as _}; use core::cmp::Ordering; @@ -14,9 +15,9 @@ fn main() { // define a component that renders a div with the text "Hello, world!" fn App(cx: Scope) -> Element { - let file = use_state(cx, String::new); - let analysis = use_state(cx, Analysis::new); - let status = use_state(cx, String::new); + let file = use_state(cx, || String::new()); + let status = use_state(cx, || String::new()); + let analysis = use_state(cx, || Analysis::new()); cx.render(rsx! { header { style { " @@ -38,6 +39,7 @@ fn App(cx: Scope) -> Element { div { input { r#type: "file", + disabled: status.get().starts_with("[WORKING]"), onchange: |evt| { to_owned![file]; if let Some(file_engine) = &evt.files { @@ -50,23 +52,27 @@ fn App(cx: Scope) -> Element { p { file.get().clone() } } div { - input { r#type: "button", value: "analyze", disabled: file.get().len() == 0, onclick: |evt| { - to_owned![file]; - to_owned![analysis]; - to_owned![status]; - async move { - let analyzed = analyze(file.get().clone()); - if analyzed.err.len() > 0 { - status.set(analyzed.err.clone()); - } else { - status.set(format!( - "found {} clips to keep and {} clips to drop", - analyzed.result.iter().filter(|x| x.has_content).count(), - analyzed.result.iter().filter(|x| !x.has_content).count(), - )); + input { r#type: "button", value: "analyze", disabled: file.get().len() == 0 || status.get().starts_with("[WORKING]"), onclick: move |_| { + cx.spawn({ + let file = file.to_owned(); + let status = status.to_owned(); + let analysis = analysis.to_owned(); + + async move { + status.set(format!("[WORKING] analyzing {file}... (this may take a while, like 5 minutes, but I promise I'm working on it)")); + let analyzed = analyze(file.get().clone()).await; + if analyzed.err.len() > 0 { + status.set(analyzed.err.clone()); + } else { + status.set(format!( + "found {} clips to keep and {} clips to drop", + analyzed.result.iter().filter(|x| x.has_content).count(), + analyzed.result.iter().filter(|x| !x.has_content).count(), + )); + } + analysis.set(analyzed); } - analysis.set(analyzed); - } + }); }} } div { @@ -89,7 +95,7 @@ fn App(cx: Scope) -> Element { } }) .collect(); - status.set(format!("clipifying {:?}", content_spans)); + status.set(format!("[WORKING] clipifying {:?}...", content_spans)); let file = file.get().clone(); to_owned![status]; async move { @@ -97,7 +103,7 @@ fn App(cx: Scope) -> Element { status.set(f); } }, - input { r#type: "submit", value: "clipify selected spans", disabled: file.get().len() == 0 } + input { r#type: "submit", value: "clipify selected spans", disabled: file.get().len() == 0 || status.get().starts_with("[WORKING]") } hr {} analysis.get().result.iter().map(|a| { rsx! { @@ -144,8 +150,8 @@ struct Analyzed { has_content: bool, } -fn analyze(file: String) -> Analysis { - let content_spans = lib::video::inspect(&file); // TODO desktop +async fn analyze(file: String) -> Analysis { + let content_spans = lib::video::inspect_async(&file).await; // TODO desktop //let content_spans: Result, String> = Ok(vec![lib::video::ContentSpan{start: 0.5, stop: 20.2}]); if content_spans.is_err() { return Analysis{