mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-20 17:02:53 -04:00
better events (#646)
This commit is contained in:
Vendored
+13
-4
@@ -1,6 +1,15 @@
|
||||
{
|
||||
"files.exclude": {
|
||||
"**/*~": true,
|
||||
"frontend_old/**": true
|
||||
}
|
||||
"files.exclude": {
|
||||
"**/*~": true,
|
||||
".sqlx/**": true,
|
||||
"_elasticsearch/**": true,
|
||||
"_sql/**": true,
|
||||
"frontend_old/**": true,
|
||||
"includes/**": true,
|
||||
"target/**": true,
|
||||
"test_data/**": true,
|
||||
"tmp/**": true,
|
||||
"virtualenv/**": true,
|
||||
"windows_dlls/**": true,
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+47
-47
@@ -12,7 +12,7 @@ dependencies = [
|
||||
"actix-rt",
|
||||
"actix_derive",
|
||||
"bitflags 2.5.0",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"crossbeam-channel",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
@@ -34,7 +34,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"memchr",
|
||||
@@ -73,7 +73,7 @@ dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bitflags 2.5.0",
|
||||
"brotli 6.0.0",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"bytestring",
|
||||
"derive_more 0.99.17",
|
||||
"encoding_rs",
|
||||
@@ -117,7 +117,7 @@ dependencies = [
|
||||
"actix-multipart-derive",
|
||||
"actix-utils",
|
||||
"actix-web",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"derive_more 0.99.17",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
@@ -226,7 +226,7 @@ dependencies = [
|
||||
"actix-utils",
|
||||
"actix-web-codegen",
|
||||
"ahash 0.8.11",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"bytestring",
|
||||
"cfg-if 1.0.0",
|
||||
"cookie 0.16.2",
|
||||
@@ -261,7 +261,7 @@ dependencies = [
|
||||
"actix-codec",
|
||||
"actix-http",
|
||||
"actix-web",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"bytestring",
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
@@ -296,7 +296,7 @@ dependencies = [
|
||||
"ahash 0.8.11",
|
||||
"arc-swap",
|
||||
"async-trait",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"bytestring",
|
||||
"csv",
|
||||
"derive_more 0.99.17",
|
||||
@@ -650,7 +650,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.22.1",
|
||||
"build_metadata",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"chrono",
|
||||
"directories",
|
||||
"dirs",
|
||||
@@ -1057,7 +1057,7 @@ dependencies = [
|
||||
"async-trait",
|
||||
"axum-core",
|
||||
"bitflags 1.3.2",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"futures-util",
|
||||
"http 0.2.11",
|
||||
"http-body 0.4.6",
|
||||
@@ -1083,7 +1083,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"futures-util",
|
||||
"http 0.2.11",
|
||||
"http-body 0.4.6",
|
||||
@@ -1595,9 +1595,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.10.0"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9"
|
||||
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@@ -1608,7 +1608,7 @@ version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74d80203ea6b29df88012294f62733de21cfeab47f17b41af3a38bc30a03ee72"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1947,7 +1947,7 @@ version = "4.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"memchr",
|
||||
]
|
||||
|
||||
@@ -3165,7 +3165,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40d9bd57d914cc66ce878f098f63ed7b5d5b64c30644a5adb950b008f874a6c6"
|
||||
dependencies = [
|
||||
"base64 0.11.0",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"dyn-clone",
|
||||
"lazy_static",
|
||||
"percent-encoding",
|
||||
@@ -4316,7 +4316,7 @@ version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"fnv",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
@@ -4336,7 +4336,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab"
|
||||
dependencies = [
|
||||
"atomic-waker",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"fnv",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
@@ -4546,7 +4546,7 @@ version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"fnv",
|
||||
"itoa 1.0.11",
|
||||
]
|
||||
@@ -4557,7 +4557,7 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"fnv",
|
||||
"itoa 1.0.11",
|
||||
]
|
||||
@@ -4568,7 +4568,7 @@ version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"http 0.2.11",
|
||||
"pin-project-lite",
|
||||
]
|
||||
@@ -4579,7 +4579,7 @@ version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"http 1.1.0",
|
||||
]
|
||||
|
||||
@@ -4589,7 +4589,7 @@ version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"futures-util",
|
||||
"http 1.1.0",
|
||||
"http-body 1.0.0",
|
||||
@@ -4658,7 +4658,7 @@ version = "0.14.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
@@ -4682,7 +4682,7 @@ version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"h2 0.4.5",
|
||||
@@ -4733,7 +4733,7 @@ version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"hyper 0.14.28",
|
||||
"native-tls",
|
||||
"tokio",
|
||||
@@ -4746,7 +4746,7 @@ version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"http-body-util",
|
||||
"hyper 1.6.0",
|
||||
"hyper-util",
|
||||
@@ -4762,7 +4762,7 @@ version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"http 1.1.0",
|
||||
@@ -6201,7 +6201,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c9ef834d5ed55e494a2ae350220314dc4aacd1c43a9498b00e320e0ea352a5c3"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"num-rational",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -7603,7 +7603,7 @@ version = "0.12.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"prost-derive",
|
||||
]
|
||||
|
||||
@@ -7755,7 +7755,7 @@ version = "0.11.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"pin-project-lite",
|
||||
"quinn-proto",
|
||||
"quinn-udp",
|
||||
@@ -7773,7 +7773,7 @@ version = "0.11.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"rand 0.8.5",
|
||||
"ring",
|
||||
"rustc-hash",
|
||||
@@ -8068,7 +8068,7 @@ version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6435842fc2fea44b528719eb8c32203bbc1bb2f5b619fbe0c0a3d8350fd8d2a8"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"futures 0.3.31",
|
||||
"pin-project-lite",
|
||||
]
|
||||
@@ -8246,7 +8246,7 @@ checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62"
|
||||
dependencies = [
|
||||
"async-compression",
|
||||
"base64 0.21.7",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"encoding_rs",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
@@ -8288,7 +8288,7 @@ checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb"
|
||||
dependencies = [
|
||||
"async-compression",
|
||||
"base64 0.22.1",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"cookie 0.18.1",
|
||||
"cookie_store",
|
||||
"encoding_rs",
|
||||
@@ -8412,7 +8412,7 @@ checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b"
|
||||
dependencies = [
|
||||
"bitvec",
|
||||
"bytecheck",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"hashbrown 0.12.3",
|
||||
"ptr_meta",
|
||||
"rend",
|
||||
@@ -8551,7 +8551,7 @@ dependencies = [
|
||||
"aws-creds",
|
||||
"aws-region",
|
||||
"base64 0.22.1",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"cfg-if 1.0.0",
|
||||
"futures 0.3.31",
|
||||
"hex",
|
||||
@@ -8583,7 +8583,7 @@ checksum = "b082d80e3e3cc52b2ed634388d436fe1f4de6af5786cc2de9ba9737527bdf555"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"borsh",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"num-traits",
|
||||
"rand 0.8.5",
|
||||
"rkyv",
|
||||
@@ -8743,7 +8743,7 @@ version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65bc94b580d0f5a6b7a2d604e597513d3c673154b52ddeccd1d5c32360d945ee"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"rxml_validation",
|
||||
]
|
||||
|
||||
@@ -9565,7 +9565,7 @@ dependencies = [
|
||||
"atoi",
|
||||
"bigdecimal",
|
||||
"byteorder",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"chrono",
|
||||
"crc",
|
||||
"crossbeam-queue",
|
||||
@@ -9652,7 +9652,7 @@ dependencies = [
|
||||
"bigdecimal",
|
||||
"bitflags 2.5.0",
|
||||
"byteorder",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"chrono",
|
||||
"crc",
|
||||
"digest 0.10.7",
|
||||
@@ -10384,7 +10384,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d08db1ff9e011e04014e737ec022610d756c0eae0b3b3a9037bccaf3003173a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"dirs",
|
||||
"dunce",
|
||||
"embed_plist",
|
||||
@@ -10552,7 +10552,7 @@ dependencies = [
|
||||
name = "tauri-plugin-http"
|
||||
version = "2.4.3"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"cookie_store",
|
||||
"data-url",
|
||||
"http 1.1.0",
|
||||
@@ -10926,7 +10926,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"libc",
|
||||
"mio 1.0.2",
|
||||
"parking_lot 0.12.2",
|
||||
@@ -11102,7 +11102,7 @@ version = "0.7.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"pin-project-lite",
|
||||
@@ -11207,7 +11207,7 @@ dependencies = [
|
||||
"async-trait",
|
||||
"axum",
|
||||
"base64 0.21.7",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"h2 0.3.26",
|
||||
"http 0.2.11",
|
||||
"http-body 0.4.6",
|
||||
@@ -12068,7 +12068,7 @@ dependencies = [
|
||||
name = "web_scrapers"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"chrono",
|
||||
"enums",
|
||||
"errors",
|
||||
@@ -12744,7 +12744,7 @@ dependencies = [
|
||||
"block-buffer 0.9.0",
|
||||
"bytemuck",
|
||||
"byteorder",
|
||||
"bytes 1.10.0",
|
||||
"bytes 1.10.1",
|
||||
"cc",
|
||||
"chrono",
|
||||
"clap",
|
||||
|
||||
@@ -37,7 +37,7 @@ tokens = { workspace = true }
|
||||
# External
|
||||
anyhow = { workspace = true }
|
||||
base64 = { workspace = true }
|
||||
bytes = "1.10"
|
||||
bytes = "1.10.1"
|
||||
chrono = { workspace = true }
|
||||
directories = "6.0.0"
|
||||
dirs = "6.0.0"
|
||||
|
||||
+7
-19
@@ -14,8 +14,6 @@ use crate::core::utils::simple_http_download::simple_http_download;
|
||||
use crate::core::utils::simple_http_download_to_tempfile::simple_http_download_to_tempfile;
|
||||
use crate::services::fal::state::fal_credential_manager::FalCredentialManager;
|
||||
use crate::services::fal::state::fal_task_queue::FalTaskQueue;
|
||||
use crate::services::sora::events::sora_image_enqueue_failure_event::SoraImageEnqueueFailureEvent;
|
||||
use crate::services::sora::events::sora_image_enqueue_success_event::SoraImageEnqueueSuccessEvent;
|
||||
use crate::services::sora::state::read_sora_credentials_from_disk::read_sora_credentials_from_disk;
|
||||
use crate::services::sora::state::sora_credential_holder::SoraCredentialHolder;
|
||||
use crate::services::sora::state::sora_credential_manager::SoraCredentialManager;
|
||||
@@ -101,6 +99,7 @@ pub enum EnqueueTextToImageErrorType {
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn enqueue_text_to_image_command(
|
||||
app: AppHandle,
|
||||
request: EnqueueTextToImageRequest,
|
||||
app_data_root: State<'_, AppDataRoot>,
|
||||
fal_creds_manager: State<'_, FalCredentialManager>,
|
||||
@@ -113,6 +112,7 @@ pub async fn enqueue_text_to_image_command(
|
||||
info!("enqueue_text_to_image called");
|
||||
|
||||
let result = handle_request(
|
||||
&app,
|
||||
request,
|
||||
&app_data_root,
|
||||
&fal_creds_manager,
|
||||
@@ -126,12 +126,6 @@ pub async fn enqueue_text_to_image_command(
|
||||
Err(err) => {
|
||||
error!("error: {:?}", err);
|
||||
|
||||
//let event = SoraImageEnqueueFailureEvent {};
|
||||
//let result = event.send(&app);
|
||||
//if let Err(err) = result {
|
||||
// error!("Failed to emit event: {:?}", err);
|
||||
//}
|
||||
|
||||
let mut status = CommandErrorStatus::ServerError;
|
||||
let mut error_type = EnqueueTextToImageErrorType::ServerError;
|
||||
let mut error_message = "A server error occurred. Please try again. If it continues, please tell our staff about the problem.";
|
||||
@@ -157,21 +151,15 @@ pub async fn enqueue_text_to_image_command(
|
||||
error_details: None,
|
||||
})
|
||||
}
|
||||
Ok(result) => {
|
||||
//let event = SoraImageEnqueueSuccessEvent {};
|
||||
//let result = event.send(&app);
|
||||
//if let Err(err) = result {
|
||||
// error!("Failed to emit event: {:?}", err);
|
||||
//}
|
||||
|
||||
Ok(EnqueueTextToImageSuccessResponse {
|
||||
}.into())
|
||||
Ok(()) => {
|
||||
Ok(EnqueueTextToImageSuccessResponse {}.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub async fn handle_request(
|
||||
app: &AppHandle,
|
||||
request: EnqueueTextToImageRequest,
|
||||
app_data_root: &AppDataRoot,
|
||||
fal_creds_manager: &FalCredentialManager,
|
||||
@@ -186,10 +174,10 @@ pub async fn handle_request(
|
||||
return Err(InternalImageError::NoModelSpecified);
|
||||
}
|
||||
Some(EnqueueTextToImageModel::FluxProUltra) | Some(EnqueueTextToImageModel::Recraft3) => {
|
||||
handle_fal(request, fal_creds_manager, fal_task_queue).await?;
|
||||
handle_fal(&app, request, fal_creds_manager, fal_task_queue).await?;
|
||||
},
|
||||
Some(EnqueueTextToImageModel::GptImage1) => {
|
||||
handle_sora(request, sora_creds_manager, sora_task_queue).await?;
|
||||
handle_sora(&app, request, sora_creds_manager, sora_task_queue).await?;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
use crate::core::commands::enqueue::image::enqueue_text_to_image_command::{EnqueueTextToImageModel, EnqueueTextToImageRequest};
|
||||
use crate::core::commands::enqueue::image::internal_image_error::InternalImageError;
|
||||
use crate::core::events::basic_sendable_event_trait::BasicSendableEvent;
|
||||
use crate::core::events::generation_events::common::{GenerationAction, GenerationServiceProvider};
|
||||
use crate::core::events::generation_events::generation_enqueue_failure_event::GenerationEnqueueFailureEvent;
|
||||
use crate::core::events::generation_events::generation_enqueue_success_event::GenerationEnqueueSuccessEvent;
|
||||
use crate::core::state::data_dir::app_data_root::AppDataRoot;
|
||||
use crate::services::fal::state::fal_credential_manager::FalCredentialManager;
|
||||
use crate::services::fal::state::fal_task_queue::FalTaskQueue;
|
||||
@@ -10,8 +14,10 @@ use anyhow::anyhow;
|
||||
use fal_client::requests::image_gen::enqueue_flux_pro_ultra_text_to_image::{enqueue_flux_pro_ultra_text_to_image, FluxProUltraTextToImageArgs};
|
||||
use fal_client::requests::image_gen::enqueue_recraft3_text_to_image::{enqueue_recraft3_text_to_image, Recraft3TextToImageArgs};
|
||||
use log::{error, info, warn};
|
||||
use tauri::AppHandle;
|
||||
|
||||
pub async fn handle_fal(
|
||||
app: &AppHandle,
|
||||
request: EnqueueTextToImageRequest,
|
||||
fal_creds_manager: &FalCredentialManager,
|
||||
fal_task_queue: &FalTaskQueue,
|
||||
@@ -52,6 +58,16 @@ pub async fn handle_fal(
|
||||
Ok(enqueued) => {
|
||||
info!("Successfully enqueued text to image");
|
||||
|
||||
let event = GenerationEnqueueSuccessEvent {
|
||||
action: GenerationAction::GenerateImage,
|
||||
service: GenerationServiceProvider::Fal,
|
||||
model: None,
|
||||
};
|
||||
|
||||
if let Err(err) = event.send(app) {
|
||||
error!("Failed to emit event: {:?}", err); // Fail open.
|
||||
}
|
||||
|
||||
if let Err(err) = fal_task_queue.insert(&enqueued) {
|
||||
error!("Failed to enqueue task: {:?}", err);
|
||||
return Err(InternalImageError::AnyhowError(anyhow!("Failed to enqueue task: {:?}", err)));
|
||||
@@ -59,6 +75,18 @@ pub async fn handle_fal(
|
||||
}
|
||||
Err(err) => {
|
||||
error!("Failed to enqueue text to image: {:?}", err);
|
||||
|
||||
let event = GenerationEnqueueFailureEvent {
|
||||
action: GenerationAction::GenerateImage,
|
||||
service: GenerationServiceProvider::Fal,
|
||||
model: None,
|
||||
reason: None,
|
||||
};
|
||||
|
||||
if let Err(err) = event.send(app) {
|
||||
error!("Failed to emit event: {:?}", err); // Fail open.
|
||||
}
|
||||
|
||||
return Err(InternalImageError::FalError(err));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
use crate::core::commands::enqueue::image::enqueue_text_to_image_command::{EnqueueTextToImageModel, EnqueueTextToImageRequest};
|
||||
use crate::core::commands::enqueue::image::internal_image_error::InternalImageError;
|
||||
use crate::core::events::basic_sendable_event_trait::BasicSendableEvent;
|
||||
use crate::core::events::generation_events::common::{GenerationAction, GenerationServiceProvider};
|
||||
use crate::core::events::generation_events::generation_enqueue_failure_event::GenerationEnqueueFailureEvent;
|
||||
use crate::core::events::generation_events::generation_enqueue_success_event::GenerationEnqueueSuccessEvent;
|
||||
use crate::core::state::data_dir::app_data_root::AppDataRoot;
|
||||
use crate::services::fal::state::fal_credential_manager::FalCredentialManager;
|
||||
use crate::services::fal::state::fal_task_queue::FalTaskQueue;
|
||||
@@ -17,10 +21,12 @@ use openai_sora_client::recipes::simple_image_gen_with_session_auto_renew::{simp
|
||||
use openai_sora_client::requests::image_gen::common::{ImageSize, NumImages, SoraImageGenResponse};
|
||||
use openai_sora_client::sora_error::SoraError;
|
||||
use std::time::Duration;
|
||||
use tauri::AppHandle;
|
||||
|
||||
const SORA_SIMPLE_IMAGE_GEN_TIMEOUT : Duration = Duration::from_millis(1000 * 30); // 30 seconds
|
||||
|
||||
pub async fn handle_sora(
|
||||
app: &AppHandle,
|
||||
request: EnqueueTextToImageRequest,
|
||||
sora_creds_manager: &SoraCredentialManager,
|
||||
sora_task_queue: &SoraTaskQueue,
|
||||
@@ -60,6 +66,17 @@ pub async fn handle_sora(
|
||||
match result {
|
||||
Ok((response, maybe_new_creds)) => (response, maybe_new_creds),
|
||||
Err(err) => {
|
||||
let event = GenerationEnqueueFailureEvent {
|
||||
action: GenerationAction::GenerateImage,
|
||||
service: GenerationServiceProvider::Sora,
|
||||
model: None,
|
||||
reason: None,
|
||||
};
|
||||
|
||||
if let Err(err) = event.send(app) {
|
||||
error!("Failed to emit event: {:?}", err); // Fail open.
|
||||
}
|
||||
|
||||
return Err(InternalImageError::SoraError(err));
|
||||
}
|
||||
};
|
||||
@@ -73,5 +90,15 @@ pub async fn handle_sora(
|
||||
|
||||
sora_task_queue.insert(&response.task_id)?;
|
||||
|
||||
let event = GenerationEnqueueSuccessEvent {
|
||||
action: GenerationAction::GenerateImage,
|
||||
service: GenerationServiceProvider::Sora,
|
||||
model: None,
|
||||
};
|
||||
|
||||
if let Err(err) = event.send(app) {
|
||||
error!("Failed to emit event: {:?}", err); // Fail open.
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
use crate::core::events::sendable_event_error::SendableEventError;
|
||||
use log::info;
|
||||
use serde::Serialize;
|
||||
use std::fmt::Debug;
|
||||
use tauri::{AppHandle, Emitter};
|
||||
|
||||
// Tagged enums here are waaay too "Rustic"
|
||||
// #[derive(Clone, Serialize)]
|
||||
// #[serde(rename_all = "camelCase", rename_all_fields = "camelCase", tag = "event", content = "data")]
|
||||
// pub enum BasicEvent<T: Serialize> {
|
||||
// Success(T),
|
||||
// Failure(T),
|
||||
// }
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum BasicEventStatus {
|
||||
Success,
|
||||
Failure,
|
||||
}
|
||||
|
||||
/// Wrap the event with "status" and "data" fields.
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
struct BasicEventWrapper<T: Serialize + Debug> {
|
||||
status: BasicEventStatus,
|
||||
data: T,
|
||||
}
|
||||
|
||||
pub trait BasicSendableEvent : Clone + Debug + Serialize {
|
||||
/// This is the name of the event that the frontend subscribes to.
|
||||
const FRONTEND_EVENT_NAME: &'static str;
|
||||
|
||||
/// This is the status of the event: Success, Failure, etc.
|
||||
const EVENT_STATUS: BasicEventStatus;
|
||||
|
||||
/// Default implementation of send().
|
||||
/// This serializes and sends the event to the frontend.
|
||||
fn send(&self, app: &AppHandle) -> Result<(), SendableEventError> {
|
||||
let wrapped = BasicEventWrapper {
|
||||
status: Self::EVENT_STATUS,
|
||||
data: self.clone(),
|
||||
};
|
||||
info!("Sending event to frontend: {} ; payload = {:?}", Self::FRONTEND_EVENT_NAME, wrapped);
|
||||
let result = app.emit(Self::FRONTEND_EVENT_NAME, wrapped);
|
||||
if let Err(err) = result {
|
||||
return Err(SendableEventError::from(err));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, Copy, Clone, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerationServiceProvider {
|
||||
Sora,
|
||||
Fal,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerationModel {
|
||||
#[serde(rename = "kling_1.6")]
|
||||
Kling1_6,
|
||||
#[serde(rename = "kling_2.0")]
|
||||
Kling2_0,
|
||||
Sora,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerationAction {
|
||||
GenerateImage,
|
||||
GenerateVideo,
|
||||
RemoveBackground,
|
||||
#[serde(rename = "image_to_3d")]
|
||||
ImageTo3d,
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
use crate::core::events::basic_sendable_event_trait::{BasicEventStatus, BasicSendableEvent};
|
||||
use crate::core::events::generation_events::common::{GenerationAction, GenerationModel, GenerationServiceProvider};
|
||||
use serde_derive::Serialize;
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct GenerationCompleteEvent {
|
||||
pub action: Option<GenerationAction>,
|
||||
pub service: GenerationServiceProvider,
|
||||
pub model: Option<GenerationModel>,
|
||||
}
|
||||
|
||||
impl BasicSendableEvent for GenerationCompleteEvent {
|
||||
const FRONTEND_EVENT_NAME: &'static str = "generation-complete-event";
|
||||
const EVENT_STATUS: BasicEventStatus = BasicEventStatus::Success;
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
use crate::core::events::basic_sendable_event_trait::{BasicEventStatus, BasicSendableEvent};
|
||||
use crate::core::events::generation_events::common::{GenerationAction, GenerationModel, GenerationServiceProvider};
|
||||
use serde_derive::Serialize;
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct GenerationEnqueueFailureEvent {
|
||||
pub action: GenerationAction,
|
||||
pub service: GenerationServiceProvider,
|
||||
pub model: Option<GenerationModel>,
|
||||
|
||||
/// User-facing reason for the failure, if available.
|
||||
pub reason: Option<String>,
|
||||
}
|
||||
|
||||
impl BasicSendableEvent for GenerationEnqueueFailureEvent {
|
||||
const FRONTEND_EVENT_NAME: &'static str = "generation-enqueue-failure-event";
|
||||
const EVENT_STATUS: BasicEventStatus = BasicEventStatus::Failure;
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
use crate::core::events::basic_sendable_event_trait::{BasicEventStatus, BasicSendableEvent};
|
||||
use crate::core::events::generation_events::common::{GenerationAction, GenerationModel, GenerationServiceProvider};
|
||||
use serde_derive::Serialize;
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct GenerationEnqueueSuccessEvent {
|
||||
pub action: GenerationAction,
|
||||
pub service: GenerationServiceProvider,
|
||||
pub model: Option<GenerationModel>,
|
||||
}
|
||||
|
||||
impl BasicSendableEvent for GenerationEnqueueSuccessEvent {
|
||||
const FRONTEND_EVENT_NAME: &'static str = "generation-enqueue-success-event";
|
||||
const EVENT_STATUS: BasicEventStatus = BasicEventStatus::Success;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
use crate::core::events::basic_sendable_event_trait::{BasicEventStatus, BasicSendableEvent};
|
||||
use crate::core::events::generation_events::common::{GenerationAction, GenerationModel, GenerationServiceProvider};
|
||||
use serde_derive::Serialize;
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct GenerationFailedEvent {
|
||||
pub action: GenerationAction,
|
||||
pub service: GenerationServiceProvider,
|
||||
pub model: Option<GenerationModel>,
|
||||
|
||||
/// User-facing reason for the failure, if available.
|
||||
pub reason: Option<String>,
|
||||
}
|
||||
|
||||
impl BasicSendableEvent for GenerationFailedEvent {
|
||||
const FRONTEND_EVENT_NAME: &'static str = "generation-failed-event";
|
||||
const EVENT_STATUS: BasicEventStatus = BasicEventStatus::Failure;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
pub mod common;
|
||||
pub mod generation_enqueue_failure_event;
|
||||
pub mod generation_enqueue_success_event;
|
||||
pub mod generation_complete_event;
|
||||
pub mod generation_failed_event;
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod notification_event;
|
||||
pub mod basic_sendable_event_trait;
|
||||
pub mod generation_events;
|
||||
pub mod sendable_event_error;
|
||||
pub mod sendable_event_trait;
|
||||
@@ -1,45 +0,0 @@
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Clone, Copy, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum NotificationModelType {
|
||||
ImageSegmentation,
|
||||
TextEncoder,
|
||||
TextTokenizer,
|
||||
Unet,
|
||||
Vae,
|
||||
Json,
|
||||
ClipEncoder,
|
||||
FluxModel,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum NotificationEvent<'a> {
|
||||
ModelDownloadStarted {
|
||||
model_name: &'a str,
|
||||
model_type: NotificationModelType,
|
||||
},
|
||||
ModelDownloadProgress {
|
||||
model_name: &'a str,
|
||||
model_type: NotificationModelType,
|
||||
currently_downloaded_bytes: usize,
|
||||
total_file_bytes: usize,
|
||||
},
|
||||
ModelDownloadComplete {
|
||||
model_name: &'a str,
|
||||
model_type: NotificationModelType,
|
||||
},
|
||||
ModelLoading {
|
||||
model_name: String,
|
||||
model_type: NotificationModelType,
|
||||
},
|
||||
ModelInference {
|
||||
model_name: String,
|
||||
model_type: NotificationModelType,
|
||||
},
|
||||
ModelInferenceComplete {
|
||||
model_name: String,
|
||||
model_type: NotificationModelType,
|
||||
},
|
||||
}
|
||||
@@ -1,15 +1,17 @@
|
||||
use log::info;
|
||||
use crate::core::events::sendable_event_error::SendableEventError;
|
||||
use log::info;
|
||||
use serde::Serialize;
|
||||
use tauri::{AppHandle, Emitter};
|
||||
|
||||
/// Implement this on a Serializable object to be able to send it as an event to the frontend.
|
||||
#[deprecated(note = "Use BasicSendableEvent instead as it wraps the event with status and data fields.")]
|
||||
pub trait SendableEvent : Serialize {
|
||||
/// This is the name of the event that the frontend subscribes to.
|
||||
const FRONTEND_EVENT_NAME: &'static str;
|
||||
|
||||
/// Default implementation of send().
|
||||
/// This serializes and sends the event to the frontend.
|
||||
#[deprecated(note = "Use BasicSendableEvent instead as it wraps the event with status and data fields.")]
|
||||
fn send(&self, app: &AppHandle) -> Result<(), SendableEventError> {
|
||||
info!("Sending event to frontend: {}", Self::FRONTEND_EVENT_NAME);
|
||||
let result = app.emit(Self::FRONTEND_EVENT_NAME, self);
|
||||
|
||||
+26
-19
@@ -1,6 +1,10 @@
|
||||
use crate::core::commands::response::failure_response_wrapper::{CommandErrorResponseWrapper, CommandErrorStatus};
|
||||
use crate::core::commands::response::shorthand::Response;
|
||||
use crate::core::commands::response::success_response_wrapper::SerializeMarker;
|
||||
use crate::core::events::basic_sendable_event_trait::BasicSendableEvent;
|
||||
use crate::core::events::generation_events::common::{GenerationAction, GenerationServiceProvider};
|
||||
use crate::core::events::generation_events::generation_enqueue_failure_event::GenerationEnqueueFailureEvent;
|
||||
use crate::core::events::generation_events::generation_enqueue_success_event::GenerationEnqueueSuccessEvent;
|
||||
use crate::core::events::sendable_event_trait::SendableEvent;
|
||||
use crate::core::state::data_dir::app_data_root::AppDataRoot;
|
||||
use crate::core::state::data_dir::trait_data_subdir::DataSubdir;
|
||||
@@ -10,8 +14,6 @@ use crate::core::utils::save_base64_image_to_temp_dir::save_base64_image_to_temp
|
||||
use crate::core::utils::simple_http_download::simple_http_download;
|
||||
use crate::core::utils::simple_http_download_to_tempfile::simple_http_download_to_tempfile;
|
||||
use crate::services::fal::state::fal_credential_manager::FalCredentialManager;
|
||||
use crate::services::sora::events::sora_image_enqueue_failure_event::SoraImageEnqueueFailureEvent;
|
||||
use crate::services::sora::events::sora_image_enqueue_success_event::SoraImageEnqueueSuccessEvent;
|
||||
use crate::services::sora::state::read_sora_credentials_from_disk::read_sora_credentials_from_disk;
|
||||
use crate::services::sora::state::sora_credential_holder::SoraCredentialHolder;
|
||||
use crate::services::sora::state::sora_credential_manager::SoraCredentialManager;
|
||||
@@ -87,6 +89,7 @@ pub enum BackgroundRemovalErrorType {
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn fal_background_removal_command(
|
||||
app: AppHandle,
|
||||
request: FalBackgroundRemovalRequest,
|
||||
app_data_root: State<'_, AppDataRoot>,
|
||||
fal_creds_manager: State<'_, FalCredentialManager>,
|
||||
@@ -109,6 +112,16 @@ pub async fn fal_background_removal_command(
|
||||
});
|
||||
}
|
||||
|
||||
let event = GenerationEnqueueSuccessEvent {
|
||||
action: GenerationAction::RemoveBackground,
|
||||
service: GenerationServiceProvider::Fal,
|
||||
model: None,
|
||||
};
|
||||
|
||||
if let Err(err) = event.send(&app) {
|
||||
error!("Failed to emit event: {:?}", err); // Fail open.
|
||||
}
|
||||
|
||||
let result = remove_background(
|
||||
request,
|
||||
&app_data_root,
|
||||
@@ -120,20 +133,21 @@ pub async fn fal_background_removal_command(
|
||||
Err(err) => {
|
||||
error!("error: {:?}", err);
|
||||
|
||||
//let event = SoraImageEnqueueFailureEvent {};
|
||||
//let result = event.send(&app);
|
||||
//if let Err(err) = result {
|
||||
// error!("Failed to emit event: {:?}", err);
|
||||
//}
|
||||
|
||||
let event = GenerationEnqueueFailureEvent {
|
||||
action: GenerationAction::RemoveBackground,
|
||||
service: GenerationServiceProvider::Fal,
|
||||
model: None,
|
||||
reason: None,
|
||||
};
|
||||
|
||||
if let Err(err) = event.send(&app) {
|
||||
error!("Failed to emit event: {:?}", err); // Fail open.
|
||||
}
|
||||
|
||||
let mut status = CommandErrorStatus::ServerError;
|
||||
let mut error_type = BackgroundRemovalErrorType::ServerError;
|
||||
let mut error_message = "A server error occurred. Please try again. If it continues, please tell our staff about the problem.";
|
||||
|
||||
//match (err) {
|
||||
// _ => {},
|
||||
//}
|
||||
|
||||
Err(CommandErrorResponseWrapper {
|
||||
status,
|
||||
error_message: Some(error_message.to_string()),
|
||||
@@ -142,12 +156,6 @@ pub async fn fal_background_removal_command(
|
||||
})
|
||||
}
|
||||
Ok(result) => {
|
||||
//let event = SoraImageEnqueueSuccessEvent {};
|
||||
//let result = event.send(&app);
|
||||
//if let Err(err) = result {
|
||||
// error!("Failed to emit event: {:?}", err);
|
||||
//}
|
||||
|
||||
Ok(FalBackgroundRemovalSuccessResponse {
|
||||
media_token: result.0.media_file.token,
|
||||
cdn_url: result.0.media_file.media_links.cdn_url,
|
||||
@@ -256,4 +264,3 @@ pub async fn remove_background(
|
||||
|
||||
Ok((response, base64_bytes))
|
||||
}
|
||||
|
||||
|
||||
+28
-20
@@ -1,3 +1,9 @@
|
||||
use crate::core::commands::response::failure_response_wrapper::{CommandErrorResponseWrapper, CommandErrorStatus};
|
||||
use crate::core::commands::response::shorthand::Response;
|
||||
use crate::core::events::basic_sendable_event_trait::BasicSendableEvent;
|
||||
use crate::core::events::generation_events::common::{GenerationAction, GenerationServiceProvider};
|
||||
use crate::core::events::generation_events::generation_enqueue_failure_event::GenerationEnqueueFailureEvent;
|
||||
use crate::core::events::generation_events::generation_enqueue_success_event::GenerationEnqueueSuccessEvent;
|
||||
use crate::core::events::sendable_event_trait::SendableEvent;
|
||||
use crate::core::state::data_dir::app_data_root::AppDataRoot;
|
||||
use crate::core::state::data_dir::trait_data_subdir::DataSubdir;
|
||||
@@ -8,8 +14,6 @@ use crate::core::utils::simple_http_download::simple_http_download;
|
||||
use crate::core::utils::simple_http_download_to_tempfile::simple_http_download_to_tempfile;
|
||||
use crate::services::fal::state::fal_credential_manager::FalCredentialManager;
|
||||
use crate::services::fal::state::fal_task_queue::FalTaskQueue;
|
||||
use crate::services::sora::events::sora_image_enqueue_failure_event::SoraImageEnqueueFailureEvent;
|
||||
use crate::services::sora::events::sora_image_enqueue_success_event::SoraImageEnqueueSuccessEvent;
|
||||
use crate::services::sora::state::read_sora_credentials_from_disk::read_sora_credentials_from_disk;
|
||||
use crate::services::sora::state::sora_credential_holder::SoraCredentialHolder;
|
||||
use crate::services::sora::state::sora_credential_manager::SoraCredentialManager;
|
||||
@@ -52,8 +56,6 @@ use storyteller_client::utils::api_host::ApiHost;
|
||||
use tauri::{AppHandle, Emitter, Manager, State};
|
||||
use tempfile::NamedTempFile;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use crate::core::commands::response::failure_response_wrapper::{CommandErrorResponseWrapper, CommandErrorStatus};
|
||||
use crate::core::commands::response::shorthand::Response;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct FalHunyuanImageTo3dRequest {
|
||||
@@ -76,6 +78,7 @@ pub enum HunyuanErrorType {
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn fal_hunyuan_image_to_3d_command(
|
||||
app: AppHandle,
|
||||
request: FalHunyuanImageTo3dRequest,
|
||||
app_data_root: State<'_, AppDataRoot>,
|
||||
fal_creds_manager: State<'_, FalCredentialManager>,
|
||||
@@ -110,20 +113,21 @@ pub async fn fal_hunyuan_image_to_3d_command(
|
||||
if let Err(err) = result {
|
||||
error!("error: {:?}", err);
|
||||
|
||||
//let event = SoraImageEnqueueFailureEvent {};
|
||||
//let result = event.send(&app);
|
||||
//if let Err(err) = result {
|
||||
// error!("Failed to emit event: {:?}", err);
|
||||
//}
|
||||
let event = GenerationEnqueueFailureEvent {
|
||||
action: GenerationAction::ImageTo3d,
|
||||
service: GenerationServiceProvider::Fal,
|
||||
model: None,
|
||||
reason: None,
|
||||
};
|
||||
|
||||
if let Err(err) = event.send(&app) {
|
||||
error!("Failed to emit event: {:?}", err); // Fail open.
|
||||
}
|
||||
|
||||
let mut status = CommandErrorStatus::ServerError;
|
||||
let mut error_type = HunyuanErrorType::ServerError;
|
||||
let mut error_message = "A server error occurred. Please try again. If it continues, please tell our staff about the problem.";
|
||||
|
||||
//match (err) {
|
||||
// _ => {},
|
||||
//}
|
||||
|
||||
return Err(CommandErrorResponseWrapper {
|
||||
status,
|
||||
error_message: Some(error_message.to_string()),
|
||||
@@ -131,13 +135,17 @@ pub async fn fal_hunyuan_image_to_3d_command(
|
||||
error_details: None,
|
||||
})
|
||||
}
|
||||
|
||||
//let event = SoraImageEnqueueSuccessEvent {};
|
||||
//let result = event.send(&app);
|
||||
//if let Err(err) = result {
|
||||
// error!("Failed to emit event: {:?}", err);
|
||||
//}
|
||||
|
||||
|
||||
let event = GenerationEnqueueSuccessEvent {
|
||||
action: GenerationAction::ImageTo3d,
|
||||
service: GenerationServiceProvider::Fal,
|
||||
model: None,
|
||||
};
|
||||
|
||||
if let Err(err) = event.send(&app) {
|
||||
error!("Failed to emit event: {:?}", err); // Fail open.
|
||||
}
|
||||
|
||||
Ok(().into())
|
||||
}
|
||||
|
||||
|
||||
+28
-20
@@ -1,3 +1,9 @@
|
||||
use crate::core::commands::response::failure_response_wrapper::{CommandErrorResponseWrapper, CommandErrorStatus};
|
||||
use crate::core::commands::response::shorthand::Response;
|
||||
use crate::core::events::basic_sendable_event_trait::BasicSendableEvent;
|
||||
use crate::core::events::generation_events::common::{GenerationAction, GenerationServiceProvider};
|
||||
use crate::core::events::generation_events::generation_enqueue_failure_event::GenerationEnqueueFailureEvent;
|
||||
use crate::core::events::generation_events::generation_enqueue_success_event::GenerationEnqueueSuccessEvent;
|
||||
use crate::core::events::sendable_event_trait::SendableEvent;
|
||||
use crate::core::state::data_dir::app_data_root::AppDataRoot;
|
||||
use crate::core::state::data_dir::trait_data_subdir::DataSubdir;
|
||||
@@ -8,8 +14,6 @@ use crate::core::utils::simple_http_download::simple_http_download;
|
||||
use crate::core::utils::simple_http_download_to_tempfile::simple_http_download_to_tempfile;
|
||||
use crate::services::fal::state::fal_credential_manager::FalCredentialManager;
|
||||
use crate::services::fal::state::fal_task_queue::FalTaskQueue;
|
||||
use crate::services::sora::events::sora_image_enqueue_failure_event::SoraImageEnqueueFailureEvent;
|
||||
use crate::services::sora::events::sora_image_enqueue_success_event::SoraImageEnqueueSuccessEvent;
|
||||
use crate::services::sora::state::read_sora_credentials_from_disk::read_sora_credentials_from_disk;
|
||||
use crate::services::sora::state::sora_credential_holder::SoraCredentialHolder;
|
||||
use crate::services::sora::state::sora_credential_manager::SoraCredentialManager;
|
||||
@@ -20,8 +24,8 @@ use base64::prelude::BASE64_STANDARD;
|
||||
use base64::{DecodeError, Engine};
|
||||
use errors::{AnyhowError, AnyhowResult};
|
||||
use fal_client::error::fal_error_plus::FalErrorPlus;
|
||||
use fal_client::requests::video_gen::enqueue_kling_16_image_to_video::{enqueue_kling_16_image_to_video, Kling16Args, Kling16Duration};
|
||||
use fal_client::requests::remove_background_rembg::remove_background_rembg;
|
||||
use fal_client::requests::video_gen::enqueue_kling_16_image_to_video::{enqueue_kling_16_image_to_video, Kling16Args, Kling16Duration};
|
||||
use filesys::file_read_bytes::file_read_bytes;
|
||||
use image::codecs::png::{CompressionType, FilterType, PngEncoder};
|
||||
use image::{DynamicImage, EncodableLayout, ImageReader};
|
||||
@@ -52,8 +56,6 @@ use storyteller_client::utils::api_host::ApiHost;
|
||||
use tauri::{AppHandle, Emitter, Manager, State};
|
||||
use tempfile::NamedTempFile;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use crate::core::commands::response::failure_response_wrapper::{CommandErrorResponseWrapper, CommandErrorStatus};
|
||||
use crate::core::commands::response::shorthand::Response;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct FalKlingImageToVideoRequest {
|
||||
@@ -81,6 +83,7 @@ pub enum KlingImageToVideoErrorType {
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn fal_kling_image_to_video_command(
|
||||
app: AppHandle,
|
||||
request: FalKlingImageToVideoRequest,
|
||||
app_data_root: State<'_, AppDataRoot>,
|
||||
fal_creds_manager: State<'_, FalCredentialManager>,
|
||||
@@ -115,20 +118,21 @@ pub async fn fal_kling_image_to_video_command(
|
||||
if let Err(err) = result {
|
||||
error!("error: {:?}", err);
|
||||
|
||||
//let event = SoraImageEnqueueFailureEvent {};
|
||||
//let result = event.send(&app);
|
||||
//if let Err(err) = result {
|
||||
// error!("Failed to emit event: {:?}", err);
|
||||
//}
|
||||
let event = GenerationEnqueueFailureEvent {
|
||||
action: GenerationAction::GenerateVideo,
|
||||
service: GenerationServiceProvider::Fal,
|
||||
model: None,
|
||||
reason: None,
|
||||
};
|
||||
|
||||
if let Err(err) = event.send(&app) {
|
||||
error!("Failed to emit event: {:?}", err); // Fail open.
|
||||
}
|
||||
|
||||
let mut status = CommandErrorStatus::ServerError;
|
||||
let mut error_type = KlingImageToVideoErrorType::ServerError;
|
||||
let mut error_message = "A server error occurred. Please try again. If it continues, please tell our staff about the problem.";
|
||||
|
||||
//match (err) {
|
||||
// _ => {},
|
||||
//}
|
||||
|
||||
return Err(CommandErrorResponseWrapper {
|
||||
status,
|
||||
error_message: Some(error_message.to_string()),
|
||||
@@ -137,12 +141,16 @@ pub async fn fal_kling_image_to_video_command(
|
||||
})
|
||||
}
|
||||
|
||||
//let event = SoraImageEnqueueSuccessEvent {};
|
||||
//let result = event.send(&app);
|
||||
//if let Err(err) = result {
|
||||
// error!("Failed to emit event: {:?}", err);
|
||||
//}
|
||||
|
||||
let event = GenerationEnqueueSuccessEvent {
|
||||
action: GenerationAction::GenerateVideo,
|
||||
service: GenerationServiceProvider::Fal,
|
||||
model: None,
|
||||
};
|
||||
|
||||
if let Err(err) = event.send(&app) {
|
||||
error!("Failed to emit event: {:?}", err); // Fail open.
|
||||
}
|
||||
|
||||
Ok(().into())
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
use crate::core::events::generation_events::common::GenerationAction;
|
||||
use fal_client::model::fal_endpoint::FalEndpoint;
|
||||
|
||||
/// Adapter of generation types/categories for FAL
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum FalGenerationType {
|
||||
TextToImage,
|
||||
ImageToImage,
|
||||
TextToVideo,
|
||||
ImageToVideo,
|
||||
ImageTo3d,
|
||||
ImageBackgroundRemoval,
|
||||
}
|
||||
|
||||
impl FalGenerationType {
|
||||
pub fn from_fal_endpoint(endpoint: &FalEndpoint) -> Option<Self> {
|
||||
match endpoint {
|
||||
FalEndpoint::FluxProUltraTextToImage => Some(Self::TextToImage),
|
||||
FalEndpoint::Hunyuan3d2Base => Some(Self::ImageTo3d),
|
||||
FalEndpoint::Kling16ImageToVideo => Some(Self::ImageToVideo),
|
||||
FalEndpoint::Minimax01ImageToVideo => Some(Self::ImageToVideo),
|
||||
FalEndpoint::RecraftV3TextToImage => Some(Self::TextToImage),
|
||||
FalEndpoint::Other(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_event_generation_action(&self) -> GenerationAction {
|
||||
match self {
|
||||
Self::TextToImage => GenerationAction::GenerateImage,
|
||||
Self::ImageToImage => GenerationAction::GenerateImage,
|
||||
Self::TextToVideo => GenerationAction::GenerateVideo,
|
||||
Self::ImageToVideo => GenerationAction::GenerateVideo,
|
||||
Self::ImageTo3d => GenerationAction::ImageTo3d,
|
||||
Self::ImageBackgroundRemoval => GenerationAction::RemoveBackground,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::services::fal::state::fal_generation_type::FalGenerationType;
|
||||
use chrono::{DateTime, Utc};
|
||||
use errors::AnyhowResult;
|
||||
use fal_client::model::enqueued_request::EnqueuedRequest;
|
||||
@@ -10,12 +11,14 @@ use std::sync::{Arc, RwLock};
|
||||
pub struct FalTaskDetails {
|
||||
pub enqueue_time: DateTime<Utc>,
|
||||
pub enqueued_request: EnqueuedRequest,
|
||||
pub generation_type: Option<FalGenerationType>,
|
||||
}
|
||||
|
||||
impl FalTaskDetails {
|
||||
pub fn for_request(request: EnqueuedRequest) -> Self {
|
||||
Self {
|
||||
enqueue_time: Utc::now(),
|
||||
generation_type: FalGenerationType::from_fal_endpoint(&request.fal_endpoint),
|
||||
enqueued_request: request,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod fal_credential_manager;
|
||||
pub mod fal_task_queue;
|
||||
pub mod read_fal_api_key_from_disk;
|
||||
pub mod read_fal_api_key_from_disk;
|
||||
mod fal_generation_type;
|
||||
@@ -1,11 +1,11 @@
|
||||
use crate::core::events::sendable_event_trait::SendableEvent;
|
||||
use crate::core::events::basic_sendable_event_trait::BasicSendableEvent;
|
||||
use crate::core::events::generation_events::common::{GenerationAction, GenerationServiceProvider};
|
||||
use crate::core::events::generation_events::generation_complete_event::GenerationCompleteEvent;
|
||||
use crate::core::state::data_dir::app_data_root::AppDataRoot;
|
||||
use crate::core::state::data_dir::trait_data_subdir::DataSubdir;
|
||||
use crate::core::utils::download_url_to_temp_dir::download_url_to_temp_dir;
|
||||
use crate::services::fal::state::fal_credential_manager::FalCredentialManager;
|
||||
use crate::services::fal::state::fal_task_queue::FalTaskQueue;
|
||||
use crate::services::sora::events::sora_image_generation_complete_event::SoraImageGenerationCompleteEvent;
|
||||
use crate::services::sora::events::sora_image_generation_failed_event::SoraImageGenerationFailedEvent;
|
||||
use crate::services::sora::state::sora_credential_manager::SoraCredentialManager;
|
||||
use crate::services::storyteller::state::storyteller_credential_manager::StorytellerCredentialManager;
|
||||
use errors::AnyhowResult;
|
||||
@@ -146,10 +146,17 @@ async fn polling_loop(
|
||||
Ok(success) => {
|
||||
info!("Uploaded to API backend: {:?}", success.media_file_token);
|
||||
|
||||
//let event = SoraImageGenerationCompleteEvent {
|
||||
// media_file_token: success.media_file_token,
|
||||
//};
|
||||
//event.send(&app_handle)?;
|
||||
let event = GenerationCompleteEvent {
|
||||
//media_file_token: result.media_file_token,
|
||||
action: task.generation_type
|
||||
.map(|typ| typ.to_event_generation_action()),
|
||||
service: GenerationServiceProvider::Fal,
|
||||
model: None,
|
||||
};
|
||||
|
||||
if let Err(err) = event.send(&app_handle) {
|
||||
error!("Failed to send GenerationCompleteEvent: {:?}", err); // Fail open
|
||||
}
|
||||
|
||||
succeeded_tasks.push(task_id);
|
||||
}
|
||||
@@ -158,7 +165,6 @@ async fn polling_loop(
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -228,7 +234,7 @@ async fn polling_loop(
|
||||
|
||||
fal_task_queue.remove_list(&succeeded_task_ids)?;
|
||||
|
||||
tokio::time::sleep(std::time::Duration::from_millis(6_000)).await;
|
||||
tokio::time::sleep(std::time::Duration::from_millis(1_000)).await;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
use crate::core::commands::response::failure_response_wrapper::{CommandErrorResponseWrapper, CommandErrorStatus};
|
||||
use crate::core::commands::response::shorthand::Response;
|
||||
use crate::core::events::basic_sendable_event_trait::BasicSendableEvent;
|
||||
use crate::core::events::generation_events::common::{GenerationAction, GenerationServiceProvider};
|
||||
use crate::core::events::generation_events::generation_enqueue_failure_event::GenerationEnqueueFailureEvent;
|
||||
use crate::core::events::generation_events::generation_enqueue_success_event::GenerationEnqueueSuccessEvent;
|
||||
use crate::core::events::sendable_event_trait::SendableEvent;
|
||||
use crate::core::state::data_dir::app_data_root::AppDataRoot;
|
||||
use crate::core::state::data_dir::trait_data_subdir::DataSubdir;
|
||||
use crate::core::utils::get_url_file_extension::get_url_file_extension;
|
||||
use crate::core::utils::simple_http_download::simple_http_download;
|
||||
use crate::services::sora::events::sora_image_enqueue_failure_event::SoraImageEnqueueFailureEvent;
|
||||
use crate::services::sora::events::sora_image_enqueue_success_event::SoraImageEnqueueSuccessEvent;
|
||||
use crate::services::sora::state::read_sora_credentials_from_disk::read_sora_credentials_from_disk;
|
||||
use crate::services::sora::state::sora_credential_holder::SoraCredentialHolder;
|
||||
use crate::services::sora::state::sora_credential_manager::SoraCredentialManager;
|
||||
@@ -108,9 +110,23 @@ pub async fn sora_image_remix_command(
|
||||
|
||||
if !has_credentials {
|
||||
warn!("No apparently completed credentials found");
|
||||
|
||||
let error_message = "You need to log into Sora to continue. See the settings menu.";
|
||||
|
||||
let event = GenerationEnqueueFailureEvent {
|
||||
action: GenerationAction::GenerateImage,
|
||||
service: GenerationServiceProvider::Sora,
|
||||
model: None,
|
||||
reason: Some(error_message.to_string()),
|
||||
};
|
||||
|
||||
if let Err(err) = event.send(&app) {
|
||||
error!("Failed to emit event: {:?}", err); // Fail open.
|
||||
}
|
||||
|
||||
return Err(CommandErrorResponseWrapper {
|
||||
status: CommandErrorStatus::Unauthorized,
|
||||
error_message: Some("You need to log into Sora to continue. See the settings menu.".to_string()),
|
||||
error_message: Some(error_message.to_string()),
|
||||
error_type: Some(SoraImageRemixErrorType::SoraLoginRequired),
|
||||
error_details: None,
|
||||
});
|
||||
@@ -120,38 +136,42 @@ pub async fn sora_image_remix_command(
|
||||
|
||||
match result {
|
||||
Err(err) => {
|
||||
error!("error: {:?}", err);
|
||||
error!("Sora image remix error: {:?}", err);
|
||||
|
||||
let event = SoraImageEnqueueFailureEvent {};
|
||||
let result = event.send(&app);
|
||||
|
||||
if let Err(err) = result {
|
||||
error!("Failed to emit event: {:?}", err);
|
||||
}
|
||||
|
||||
let mut status = CommandErrorStatus::ServerError;
|
||||
let mut error_type = SoraImageRemixErrorType::ServerError;
|
||||
let mut error_message = "A server error occurred. Please try again. If it continues, please tell our staff about the problem.";
|
||||
|
||||
let mut error_message = "An error occurred. Please try again. If it continues, please tell our staff about the problem.";
|
||||
|
||||
match (err) {
|
||||
InnerError::SoraError(SoraError::TooManyConcurrentTasks) => {
|
||||
error_type = SoraImageRemixErrorType::TooManyConcurrentTasks;
|
||||
status = CommandErrorStatus::ServerError;
|
||||
error_message = "You already have work in progress. Please wait for it to finish.";
|
||||
error_message = "You have too many Sora image generation tasks running. Please wait a moment.";
|
||||
},
|
||||
InnerError::SoraError(SoraError::SoraUsernameNotYetCreated) => {
|
||||
error_type = SoraImageRemixErrorType::SoraUsernameNotYetCreated;
|
||||
status = CommandErrorStatus::BadRequest;
|
||||
error_message = "You need to create a username on Sora.com to continue.";
|
||||
error_message = "Your Sora username is not yet created. Please visit the Sora.com website to create it first.";
|
||||
},
|
||||
InnerError::SoraError(SoraError::BadGateway(_) | SoraError::CloudFlareTimeout(_)) => {
|
||||
error_type = SoraImageRemixErrorType::SoraIsHavingProblems;
|
||||
status = CommandErrorStatus::ServerError;
|
||||
error_message = "Sora is having problems. Please wait a moment and then retry.";
|
||||
error_message = "Sora is having problems. Please try again later.";
|
||||
}
|
||||
_ => {},
|
||||
}
|
||||
|
||||
let event = GenerationEnqueueFailureEvent {
|
||||
action: GenerationAction::GenerateImage,
|
||||
service: GenerationServiceProvider::Sora,
|
||||
model: None,
|
||||
reason: Some(error_message.to_string()),
|
||||
};
|
||||
|
||||
if let Err(err) = event.send(&app) {
|
||||
error!("Failed to emit event: {:?}", err); // Fail open.
|
||||
}
|
||||
|
||||
Err(CommandErrorResponseWrapper {
|
||||
status,
|
||||
error_message: Some(error_message.to_string()),
|
||||
@@ -160,11 +180,14 @@ pub async fn sora_image_remix_command(
|
||||
})
|
||||
}
|
||||
Ok(_) => {
|
||||
let event = SoraImageEnqueueSuccessEvent {};
|
||||
let result = event.send(&app);
|
||||
let event = GenerationEnqueueSuccessEvent {
|
||||
action: GenerationAction::GenerateImage,
|
||||
service: GenerationServiceProvider::Sora,
|
||||
model: None,
|
||||
};
|
||||
|
||||
if let Err(err) = result {
|
||||
error!("Failed to emit event: {:?}", err);
|
||||
if let Err(err) = event.send(&app) {
|
||||
error!("Failed to emit event: {:?}", err); // Fail open.
|
||||
}
|
||||
|
||||
Ok(().into())
|
||||
|
||||
@@ -1,5 +1 @@
|
||||
pub mod sora_image_enqueue_failure_event;
|
||||
pub mod sora_image_enqueue_success_event;
|
||||
pub mod sora_image_generation_complete_event;
|
||||
pub mod sora_image_generation_failed_event;
|
||||
pub mod sora_login_success_event;
|
||||
@@ -1,11 +0,0 @@
|
||||
use crate::core::events::sendable_event_trait::SendableEvent;
|
||||
use serde_derive::Serialize;
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct SoraImageEnqueueFailureEvent {
|
||||
// TODO: Reason.
|
||||
}
|
||||
|
||||
impl SendableEvent for SoraImageEnqueueFailureEvent {
|
||||
const FRONTEND_EVENT_NAME: &'static str = "sora-image-enqueue-failure";
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
use crate::core::events::sendable_event_trait::SendableEvent;
|
||||
use serde_derive::Serialize;
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct SoraImageEnqueueSuccessEvent {
|
||||
// TODO: Token, etc.
|
||||
}
|
||||
|
||||
impl SendableEvent for SoraImageEnqueueSuccessEvent {
|
||||
const FRONTEND_EVENT_NAME: &'static str = "sora-image-enqueue-success";
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
use serde_derive::Serialize;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use crate::core::events::sendable_event_trait::SendableEvent;
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct SoraImageGenerationCompleteEvent {
|
||||
pub media_file_token: MediaFileToken,
|
||||
}
|
||||
|
||||
impl SendableEvent for SoraImageGenerationCompleteEvent {
|
||||
const FRONTEND_EVENT_NAME: &'static str = "sora-image-generation-complete";
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
use serde_derive::Serialize;
|
||||
use crate::core::events::sendable_event_trait::SendableEvent;
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct SoraImageGenerationFailedEvent {
|
||||
pub prompt: String,
|
||||
}
|
||||
|
||||
impl SendableEvent for SoraImageGenerationFailedEvent {
|
||||
const FRONTEND_EVENT_NAME: &'static str = "sora-image-generation-failed";
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use crate::core::events::basic_sendable_event_trait::BasicSendableEvent;
|
||||
use crate::core::events::generation_events::common::{GenerationAction, GenerationServiceProvider};
|
||||
use crate::core::events::generation_events::generation_complete_event::GenerationCompleteEvent;
|
||||
use crate::core::events::generation_events::generation_failed_event::GenerationFailedEvent;
|
||||
use crate::core::events::sendable_event_trait::SendableEvent;
|
||||
use crate::services::sora::events::sora_image_generation_complete_event::SoraImageGenerationCompleteEvent;
|
||||
use crate::services::sora::events::sora_image_generation_failed_event::SoraImageGenerationFailedEvent;
|
||||
use crate::core::state::data_dir::app_data_root::AppDataRoot;
|
||||
use crate::core::state::data_dir::trait_data_subdir::DataSubdir;
|
||||
use crate::services::sora::state::sora_credential_manager::SoraCredentialManager;
|
||||
@@ -95,13 +97,19 @@ async fn polling_loop(
|
||||
|
||||
for task in failed_tasks.iter() {
|
||||
if sora_task_queue.contains_key(&task.id)? {
|
||||
let event = SoraImageGenerationFailedEvent {
|
||||
prompt: task.prompt
|
||||
.as_deref()
|
||||
.map(|s| s.to_string())
|
||||
.unwrap_or_else(||"".to_string()),
|
||||
let event = GenerationFailedEvent {
|
||||
action: GenerationAction::GenerateImage,
|
||||
service: GenerationServiceProvider::Sora,
|
||||
model: None,
|
||||
reason: None,
|
||||
// prompt: task.prompt
|
||||
// .as_deref()
|
||||
// .map(|s| s.to_string())
|
||||
// .unwrap_or_else(||"".to_string()),
|
||||
};
|
||||
event.send(&app_handle)?;
|
||||
if let Err(err) = event.send(&app_handle) {
|
||||
error!("Failed to send GenerationFailedEvent: {:?}", err); // Fail open
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,12 +137,17 @@ async fn polling_loop(
|
||||
let result = upload_image_media_file_from_file(&api_host, Some(&creds), download_path).await?;
|
||||
|
||||
info!("Uploaded to API backend: {:?}", result.media_file_token);
|
||||
|
||||
let event = SoraImageGenerationCompleteEvent {
|
||||
media_file_token: result.media_file_token,
|
||||
|
||||
let event = GenerationCompleteEvent {
|
||||
//media_file_token: result.media_file_token,
|
||||
action: Some(GenerationAction::GenerateImage),
|
||||
service: GenerationServiceProvider::Sora,
|
||||
model: None,
|
||||
};
|
||||
|
||||
event.send(&app_handle)?;
|
||||
|
||||
if let Err(err) = event.send(&app_handle) {
|
||||
error!("Failed to send GenerationCompleteEvent: {:?}", err); // Fail open
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,10 @@ import {
|
||||
showPrecisionSelector,
|
||||
} from "./signals/precisionSelectorMenu";
|
||||
import { InstallSounds } from "~/pages/PageEnigma/InstallSounds";
|
||||
import { useImageGenerationFailureEvent } from "./TauriEvents/useImageGenerationFailureEvent";
|
||||
import { useImageGenerationSuccessEvent } from "./TauriEvents/useImageGenerationSuccessEvent";
|
||||
import { useGenerationEnqueueFailureEvent } from "./TauriEvents/generations/useGenerationEnqueueFailureEvent";
|
||||
import { useGenerationEnqueueSuccessEvent } from "./TauriEvents/generations/useGenerationEnqueueSuccessEvent";
|
||||
import { useGenerationFailedEvent } from "./TauriEvents/generations/useGenerationFailedEvent";
|
||||
import { useGenerationCompleteEvent } from "./TauriEvents/generations/useGenerationCompleteEvent";
|
||||
import { PageEditor } from "~/pages/PageEnigma/PageEditor";
|
||||
import { GalleryDragComponent } from "@storyteller/ui-gallery-modal";
|
||||
import { LoadingDots } from "@storyteller/ui-loading";
|
||||
@@ -91,8 +93,10 @@ export const PageEnigma = ({ sceneToken }: { sceneToken?: string }) => {
|
||||
});
|
||||
});
|
||||
|
||||
useImageGenerationSuccessEvent();
|
||||
useImageGenerationFailureEvent();
|
||||
useGenerationEnqueueSuccessEvent();
|
||||
useGenerationEnqueueFailureEvent();
|
||||
useGenerationCompleteEvent();
|
||||
useGenerationFailedEvent();
|
||||
|
||||
useEffect(() => {
|
||||
console.log("installing event listeners");
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
export enum BasicEventStatus {
|
||||
Success = "success",
|
||||
Failure = "failure",
|
||||
};
|
||||
|
||||
export interface BasicEventWrapper<T> {
|
||||
status: BasicEventStatus,
|
||||
data: T,
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
|
||||
export enum GenerationServiceProvider {
|
||||
Sora = "sora",
|
||||
Fal = "fal",
|
||||
}
|
||||
|
||||
export enum GenerationModel {
|
||||
Kling1_6 = "kling_1.6",
|
||||
Kling2_0 = "kling_2.0",
|
||||
Sora = "sora",
|
||||
}
|
||||
|
||||
export enum GenerationAction {
|
||||
GenerateImage = "generate_image",
|
||||
GenerateVideo = "generate_video",
|
||||
RemoveBackground = "remove_background",
|
||||
ImageTo3d = "image_to_3d",
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
import { useEffect } from "react";
|
||||
import { listen, UnlistenFn } from '@tauri-apps/api/event';
|
||||
import { SoundRegistry } from "@storyteller/soundboard";
|
||||
import { GetAppPreferences } from "@storyteller/tauri-api";
|
||||
import { toast } from "@storyteller/ui-toaster";
|
||||
import { GenerationAction, GenerationModel, GenerationServiceProvider } from "./common";
|
||||
import { BasicEventWrapper } from "../BasicEventWrapper";
|
||||
|
||||
type GenerationCompleteEvent = {
|
||||
action?: GenerationAction,
|
||||
service: GenerationServiceProvider,
|
||||
model?: GenerationModel,
|
||||
};
|
||||
|
||||
export const useGenerationCompleteEvent = () => {
|
||||
useEffect(() => {
|
||||
let isUnmounted = false;
|
||||
let unlisten: Promise<UnlistenFn>;
|
||||
|
||||
const setup = async () => {
|
||||
unlisten = listen<BasicEventWrapper<GenerationCompleteEvent>>('generation-complete-event', async (event) => {
|
||||
console.log("Generation complete event received:", event);
|
||||
const prefs = await GetAppPreferences();
|
||||
const soundName = prefs.preferences?.generation_success_sound;
|
||||
if (soundName !== undefined) {
|
||||
const registry = SoundRegistry.getInstance();
|
||||
registry.playSound(soundName);
|
||||
}
|
||||
const message = makeMessage(event.payload.data);
|
||||
toast.success(message);
|
||||
});
|
||||
|
||||
if (isUnmounted) {
|
||||
unlisten.then(f => f()); // Unsubscribe if unmounted early.
|
||||
}
|
||||
};
|
||||
|
||||
setup();
|
||||
|
||||
return () => {
|
||||
isUnmounted = true;
|
||||
unlisten.then(f => f());
|
||||
};
|
||||
|
||||
}, []);
|
||||
}
|
||||
|
||||
const makeMessage = (event: GenerationCompleteEvent) => {
|
||||
if (!event.action) {
|
||||
return "Generation complete!";
|
||||
}
|
||||
switch (event.action) {
|
||||
case GenerationAction.GenerateImage:
|
||||
return "Image generation complete!";
|
||||
case GenerationAction.GenerateVideo:
|
||||
return "Video generation complete!";
|
||||
case GenerationAction.RemoveBackground:
|
||||
return "Background removal complete!";
|
||||
case GenerationAction.ImageTo3d:
|
||||
return "Image to 3D complete!";
|
||||
default:
|
||||
return "Generation complete!";
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
import { useEffect } from "react";
|
||||
import { listen, UnlistenFn } from '@tauri-apps/api/event';
|
||||
import { SoundRegistry } from "@storyteller/soundboard";
|
||||
import { GetAppPreferences } from "@storyteller/tauri-api";
|
||||
import { toast } from "@storyteller/ui-toaster";
|
||||
import { GenerationAction, GenerationModel, GenerationServiceProvider } from "./common";
|
||||
import { BasicEventWrapper } from "../BasicEventWrapper";
|
||||
|
||||
type GenerationEnqueueFailureEvent = {
|
||||
action: GenerationAction,
|
||||
service: GenerationServiceProvider,
|
||||
model?: GenerationModel,
|
||||
reason?: string,
|
||||
};
|
||||
|
||||
export const useGenerationEnqueueFailureEvent = () => {
|
||||
useEffect(() => {
|
||||
let isUnmounted = false;
|
||||
let unlisten: Promise<UnlistenFn>;
|
||||
|
||||
const setup = async () => {
|
||||
unlisten = listen<BasicEventWrapper<GenerationEnqueueFailureEvent>>('generation-enqueue-failure-event', async (event) => {
|
||||
console.log("Generation enqueue failure event received:", event);
|
||||
const prefs = await GetAppPreferences();
|
||||
const soundName = prefs.preferences?.enqueue_failure_sound;
|
||||
if (soundName !== undefined) {
|
||||
const registry = SoundRegistry.getInstance();
|
||||
registry.playSound(soundName);
|
||||
}
|
||||
const message = makeMessage(event.payload.data);
|
||||
toast.error(message);
|
||||
});
|
||||
|
||||
if (isUnmounted) {
|
||||
unlisten.then(f => f()); // Unsubscribe if unmounted early.
|
||||
}
|
||||
};
|
||||
|
||||
setup();
|
||||
|
||||
return () => {
|
||||
isUnmounted = true;
|
||||
unlisten.then(f => f());
|
||||
};
|
||||
|
||||
}, []);
|
||||
}
|
||||
|
||||
const makeMessage = (event: GenerationEnqueueFailureEvent) => {
|
||||
if (!!event.reason) {
|
||||
return event.reason;
|
||||
}
|
||||
switch (event.action) {
|
||||
case GenerationAction.GenerateImage:
|
||||
return "Couldn't enqueue image generation!";
|
||||
case GenerationAction.GenerateVideo:
|
||||
return "Couldn't enqueue video generation!";
|
||||
case GenerationAction.RemoveBackground:
|
||||
return "Couldn't enqueue background removal!";
|
||||
case GenerationAction.ImageTo3d:
|
||||
return "Couldn't enqueue image to 3D!";
|
||||
default:
|
||||
return "Couldn't enqueue generation!";
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
import { useEffect } from "react";
|
||||
import { listen, UnlistenFn } from '@tauri-apps/api/event';
|
||||
import { SoundRegistry } from "@storyteller/soundboard";
|
||||
import { GetAppPreferences } from "@storyteller/tauri-api";
|
||||
import { toast } from "@storyteller/ui-toaster";
|
||||
import { GenerationAction, GenerationModel, GenerationServiceProvider } from "./common";
|
||||
import { BasicEventWrapper } from "../BasicEventWrapper";
|
||||
|
||||
type GenerationEnqueueSuccessEvent = {
|
||||
action: GenerationAction,
|
||||
service: GenerationServiceProvider,
|
||||
model?: GenerationModel,
|
||||
};
|
||||
|
||||
export const useGenerationEnqueueSuccessEvent = () => {
|
||||
useEffect(() => {
|
||||
let isUnmounted = false;
|
||||
let unlisten: Promise<UnlistenFn>;
|
||||
|
||||
const setup = async () => {
|
||||
unlisten = listen<BasicEventWrapper<GenerationEnqueueSuccessEvent>>('generation-enqueue-success-event', async (event) => {
|
||||
console.log("Generation enqueue success event received:", event);
|
||||
const prefs = await GetAppPreferences();
|
||||
const soundName = prefs.preferences?.enqueue_success_sound;
|
||||
if (soundName !== undefined) {
|
||||
const registry = SoundRegistry.getInstance();
|
||||
registry.playSound(soundName);
|
||||
}
|
||||
const message = makeMessage(event.payload.data);
|
||||
toast.success(message);
|
||||
});
|
||||
|
||||
if (isUnmounted) {
|
||||
unlisten.then(f => f()); // Unsubscribe if unmounted early.
|
||||
}
|
||||
};
|
||||
|
||||
setup();
|
||||
|
||||
return () => {
|
||||
isUnmounted = true;
|
||||
unlisten.then(f => f());
|
||||
};
|
||||
|
||||
}, []);
|
||||
}
|
||||
|
||||
const makeMessage = (event: GenerationEnqueueSuccessEvent) => {
|
||||
switch (event.action) {
|
||||
case GenerationAction.GenerateImage:
|
||||
return "Image generation enqueued!";
|
||||
case GenerationAction.GenerateVideo:
|
||||
return "Video generation enqueued!";
|
||||
case GenerationAction.RemoveBackground:
|
||||
return "Background removal enqueued!";
|
||||
case GenerationAction.ImageTo3d:
|
||||
return "Image to 3D enqueued!";
|
||||
default:
|
||||
return "Generation enqueued!";
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
import { useEffect } from "react";
|
||||
import { listen, UnlistenFn } from '@tauri-apps/api/event';
|
||||
import { SoundRegistry } from "@storyteller/soundboard";
|
||||
import { GetAppPreferences } from "@storyteller/tauri-api";
|
||||
import { toast } from "@storyteller/ui-toaster";
|
||||
import { GenerationAction, GenerationModel, GenerationServiceProvider } from "./common";
|
||||
import { BasicEventWrapper } from "../BasicEventWrapper";
|
||||
|
||||
type GenerationFailedEvent = {
|
||||
action: GenerationAction,
|
||||
service: GenerationServiceProvider,
|
||||
model?: GenerationModel,
|
||||
reason?: string,
|
||||
};
|
||||
|
||||
export const useGenerationFailedEvent = () => {
|
||||
useEffect(() => {
|
||||
let isUnmounted = false;
|
||||
let unlisten: Promise<UnlistenFn>;
|
||||
|
||||
const setup = async () => {
|
||||
unlisten = listen<BasicEventWrapper<GenerationFailedEvent>>('generation-failed-event', async (event) => {
|
||||
console.log("Generation failed event received:", event);
|
||||
const prefs = await GetAppPreferences();
|
||||
const soundName = prefs.preferences?.generation_failure_sound;
|
||||
if (soundName !== undefined) {
|
||||
const registry = SoundRegistry.getInstance();
|
||||
registry.playSound(soundName);
|
||||
}
|
||||
const message = makeMessage(event.payload.data);
|
||||
toast.error(message);
|
||||
});
|
||||
|
||||
if (isUnmounted) {
|
||||
unlisten.then(f => f()); // Unsubscribe if unmounted early.
|
||||
}
|
||||
};
|
||||
|
||||
setup();
|
||||
|
||||
return () => {
|
||||
isUnmounted = true;
|
||||
unlisten.then(f => f());
|
||||
};
|
||||
|
||||
}, []);
|
||||
}
|
||||
|
||||
const makeMessage = (event: GenerationFailedEvent) => {
|
||||
if (!!event.reason) {
|
||||
return event.reason;
|
||||
}
|
||||
switch (event.action) {
|
||||
case GenerationAction.GenerateImage:
|
||||
return "Image generation failed!";
|
||||
case GenerationAction.GenerateVideo:
|
||||
return "Video generation failed!";
|
||||
case GenerationAction.RemoveBackground:
|
||||
return "Background removal failed!";
|
||||
case GenerationAction.ImageTo3d:
|
||||
return "Image to 3D failed!";
|
||||
default:
|
||||
return "Generation failed!";
|
||||
}
|
||||
}
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
import { useEffect } from "react";
|
||||
import { listen, UnlistenFn } from '@tauri-apps/api/event';
|
||||
import { SoundRegistry } from "@storyteller/soundboard";
|
||||
import { GetAppPreferences } from "@storyteller/tauri-api";
|
||||
import { toast } from "@storyteller/ui-toaster";
|
||||
|
||||
type SoraImageGenerationFailed = {
|
||||
prompt: string,
|
||||
};
|
||||
|
||||
export const useImageGenerationFailureEvent = () => {
|
||||
useEffect(() => {
|
||||
let isUnmounted = false;
|
||||
let unlisten: Promise<UnlistenFn>;
|
||||
|
||||
const setup = async () => {
|
||||
unlisten = listen<SoraImageGenerationFailed>('sora-image-generation-failed', async (event) => {
|
||||
console.log("Image generation failure event received:", event);
|
||||
const prefs = await GetAppPreferences();
|
||||
const soundName = prefs.preferences?.generation_failure_sound;
|
||||
if (soundName !== undefined) {
|
||||
const registry = SoundRegistry.getInstance();
|
||||
registry.playSound(soundName);
|
||||
}
|
||||
toast.error("Image generation failed!");
|
||||
});
|
||||
|
||||
if (isUnmounted) {
|
||||
unlisten.then(f => f()); // Unsubscribe if unmounted early.
|
||||
}
|
||||
};
|
||||
|
||||
setup();
|
||||
|
||||
return () => {
|
||||
isUnmounted = true;
|
||||
unlisten.then(f => f());
|
||||
};
|
||||
|
||||
}, []);
|
||||
}
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
import { useEffect } from "react";
|
||||
import { listen, UnlistenFn } from '@tauri-apps/api/event';
|
||||
import { SoundRegistry } from "@storyteller/soundboard";
|
||||
import { GetAppPreferences } from "@storyteller/tauri-api";
|
||||
import { toast } from "@storyteller/ui-toaster";
|
||||
|
||||
type ImageGenerationSuccess = {
|
||||
media_file_token: string,
|
||||
};
|
||||
|
||||
export const useImageGenerationSuccessEvent = () => {
|
||||
useEffect(() => {
|
||||
let isUnmounted = false;
|
||||
let unlisten: Promise<UnlistenFn>;
|
||||
|
||||
const setup = async () => {
|
||||
unlisten = listen<ImageGenerationSuccess>('sora-image-generation-complete', async (event) => {
|
||||
console.log("Image generation success event received:", event);
|
||||
const prefs = await GetAppPreferences();
|
||||
const soundName = prefs.preferences?.generation_success_sound;
|
||||
if (soundName !== undefined) {
|
||||
const registry = SoundRegistry.getInstance();
|
||||
registry.playSound(soundName);
|
||||
}
|
||||
toast.success("Image generated!");
|
||||
});
|
||||
|
||||
if (isUnmounted) {
|
||||
unlisten.then(f => f()); // Unsubscribe if unmounted early.
|
||||
}
|
||||
};
|
||||
|
||||
setup();
|
||||
|
||||
return () => {
|
||||
isUnmounted = true;
|
||||
unlisten.then(f => f());
|
||||
};
|
||||
|
||||
}, []);
|
||||
}
|
||||
@@ -302,49 +302,6 @@ export const PromptBox2D = ({
|
||||
});
|
||||
|
||||
console.log("generateResponse", generateResponse);
|
||||
|
||||
if (generateResponse.status === CommandSuccessStatus.Success) {
|
||||
const prefs = await GetAppPreferences();
|
||||
const soundName = prefs.preferences?.enqueue_success_sound;
|
||||
if (soundName !== undefined) {
|
||||
const registry = SoundRegistry.getInstance();
|
||||
registry.playSound(soundName);
|
||||
}
|
||||
toast.success("Image added to queue");
|
||||
} else {
|
||||
const prefs = await GetAppPreferences();
|
||||
const soundName = prefs.preferences?.enqueue_failure_sound;
|
||||
if (soundName !== undefined) {
|
||||
const registry = SoundRegistry.getInstance();
|
||||
registry.playSound(soundName);
|
||||
}
|
||||
|
||||
let errorMessage = "Failed to enqueue image";
|
||||
|
||||
if ("error_type" in generateResponse) {
|
||||
switch (generateResponse.error_type) {
|
||||
case SoraImageRemixErrorType.SoraLoginRequired:
|
||||
errorMessage =
|
||||
"You need to log into Sora to continue. See the settings menu.";
|
||||
break;
|
||||
case SoraImageRemixErrorType.ServerError:
|
||||
errorMessage = "Server error. Failed to enqueue image.";
|
||||
break;
|
||||
case SoraImageRemixErrorType.TooManyConcurrentTasks:
|
||||
errorMessage =
|
||||
"You have too many Sora image generation tasks running. Please wait a moment.";
|
||||
break;
|
||||
case SoraImageRemixErrorType.SoraUsernameNotYetCreated:
|
||||
errorMessage =
|
||||
"Your Sora username is not yet created. Please visit the Sora.com website to create it first.";
|
||||
break;
|
||||
case SoraImageRemixErrorType.SoraIsHavingProblems:
|
||||
errorMessage = "Sora is having problems. Please try again later.";
|
||||
break;
|
||||
}
|
||||
}
|
||||
toast.error(errorMessage);
|
||||
}
|
||||
};
|
||||
|
||||
const handleWebEnqueue = async () => {
|
||||
|
||||
@@ -429,49 +429,9 @@ export const PromptBox3D = ({
|
||||
console.log("generateResponse", generateResponse);
|
||||
|
||||
if (generateResponse.status === CommandSuccessStatus.Success) {
|
||||
const prefs = await GetAppPreferences();
|
||||
const soundName = prefs.preferences?.enqueue_success_sound;
|
||||
if (soundName !== undefined) {
|
||||
const registry = SoundRegistry.getInstance();
|
||||
registry.playSound(soundName);
|
||||
}
|
||||
toast.success("Image added to queue");
|
||||
setisEnqueueing(false);
|
||||
return;
|
||||
} else {
|
||||
const prefs = await GetAppPreferences();
|
||||
const soundName = prefs.preferences?.enqueue_failure_sound;
|
||||
if (soundName !== undefined) {
|
||||
const registry = SoundRegistry.getInstance();
|
||||
registry.playSound(soundName);
|
||||
}
|
||||
|
||||
let errorMessage = "Failed to enqueue image";
|
||||
|
||||
if ("error_type" in generateResponse) {
|
||||
switch (generateResponse.error_type) {
|
||||
case SoraImageRemixErrorType.SoraLoginRequired:
|
||||
errorMessage =
|
||||
"You need to log into Sora to continue. See the settings menu.";
|
||||
break;
|
||||
case SoraImageRemixErrorType.ServerError:
|
||||
errorMessage = "Server error. Failed to enqueue image.";
|
||||
break;
|
||||
case SoraImageRemixErrorType.TooManyConcurrentTasks:
|
||||
errorMessage =
|
||||
"You have too many Sora image generation tasks running. Please wait a moment.";
|
||||
break;
|
||||
case SoraImageRemixErrorType.SoraUsernameNotYetCreated:
|
||||
errorMessage =
|
||||
"Your Sora username is not yet created. Please visit the Sora.com website to create it first.";
|
||||
break;
|
||||
case SoraImageRemixErrorType.SoraIsHavingProblems:
|
||||
errorMessage =
|
||||
"Sora is having problems. Please try again later.";
|
||||
break;
|
||||
}
|
||||
}
|
||||
toast.error(errorMessage);
|
||||
setisEnqueueing(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { useState, useRef, useEffect } from "react";
|
||||
import { useSignals } from "@preact/signals-react/runtime";
|
||||
import { toast } from "@storyteller/ui-toaster";
|
||||
import { JobContextType } from "@storyteller/common";
|
||||
import { downloadFileFromUrl } from "@storyteller/api";
|
||||
import { PopoverMenu, PopoverItem } from "@storyteller/ui-popover";
|
||||
@@ -25,11 +24,6 @@ import {
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { IsDesktopApp } from "@storyteller/tauri-utils";
|
||||
import { GalleryItem, GalleryModal } from "@storyteller/ui-gallery-modal";
|
||||
import {
|
||||
CommandSuccessStatus,
|
||||
GetAppPreferences,
|
||||
} from "@storyteller/tauri-api";
|
||||
import { SoundRegistry } from "@storyteller/soundboard";
|
||||
|
||||
interface ReferenceImage {
|
||||
id: string;
|
||||
@@ -209,48 +203,6 @@ export const PromptBoxImage = ({
|
||||
console.log("generateResponse", generateResponse);
|
||||
|
||||
onEnqueuePressed?.();
|
||||
if (generateResponse.status === CommandSuccessStatus.Success) {
|
||||
const prefs = await GetAppPreferences();
|
||||
const soundName = prefs.preferences?.enqueue_success_sound;
|
||||
if (soundName !== undefined) {
|
||||
const registry = SoundRegistry.getInstance();
|
||||
registry.playSound(soundName);
|
||||
}
|
||||
toast.success("Image added to queue");
|
||||
} else {
|
||||
const prefs = await GetAppPreferences();
|
||||
const soundName = prefs.preferences?.enqueue_failure_sound;
|
||||
if (soundName !== undefined) {
|
||||
const registry = SoundRegistry.getInstance();
|
||||
registry.playSound(soundName);
|
||||
}
|
||||
}
|
||||
|
||||
// let errorMessage = "Failed to enqueue image";
|
||||
// if ("error_type" in generateResponse) {
|
||||
// switch (generateResponse.error_type) {
|
||||
// case SoraImageRemixErrorType.SoraLoginRequired:
|
||||
// errorMessage =
|
||||
// "You need to log into Sora to continue. See the settings menu.";
|
||||
// break;
|
||||
// case SoraImageRemixErrorType.ServerError:
|
||||
// errorMessage = "Server error. Failed to enqueue image.";
|
||||
// break;
|
||||
// case SoraImageRemixErrorType.TooManyConcurrentTasks:
|
||||
// errorMessage =
|
||||
// "You have too many Sora image generation tasks running. Please wait a moment.";
|
||||
// break;
|
||||
// case SoraImageRemixErrorType.SoraUsernameNotYetCreated:
|
||||
// errorMessage =
|
||||
// "Your Sora username is not yet created. Please visit the Sora.com website to create it first.";
|
||||
// break;
|
||||
// case SoraImageRemixErrorType.SoraIsHavingProblems:
|
||||
// errorMessage = "Sora is having problems. Please try again later.";
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// toast.error(errorMessage);
|
||||
// }
|
||||
|
||||
setIsEnqueueing(false);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { useState, useRef, useEffect } from "react";
|
||||
import { useSignals } from "@preact/signals-react/runtime";
|
||||
import { toast } from "@storyteller/ui-toaster";
|
||||
import { JobContextType } from "@storyteller/common";
|
||||
import { downloadFileFromUrl } from "@storyteller/api";
|
||||
import { PopoverMenu, PopoverItem } from "@storyteller/ui-popover";
|
||||
@@ -21,11 +20,6 @@ import { faRectangle } from "@fortawesome/pro-regular-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { IsDesktopApp } from "@storyteller/tauri-utils";
|
||||
import { GalleryItem, GalleryModal } from "@storyteller/ui-gallery-modal";
|
||||
import {
|
||||
CommandSuccessStatus,
|
||||
GetAppPreferences,
|
||||
} from "@storyteller/tauri-api";
|
||||
import { SoundRegistry } from "@storyteller/soundboard";
|
||||
|
||||
interface ReferenceImage {
|
||||
id: string;
|
||||
@@ -196,48 +190,6 @@ export const PromptBoxVideo = ({
|
||||
console.log("generateResponse", generateResponse);
|
||||
|
||||
onEnqueuePressed?.();
|
||||
if (generateResponse.status === CommandSuccessStatus.Success) {
|
||||
const prefs = await GetAppPreferences();
|
||||
const soundName = prefs.preferences?.enqueue_success_sound;
|
||||
if (soundName !== undefined) {
|
||||
const registry = SoundRegistry.getInstance();
|
||||
registry.playSound(soundName);
|
||||
}
|
||||
toast.success("Image added to queue");
|
||||
} else {
|
||||
const prefs = await GetAppPreferences();
|
||||
const soundName = prefs.preferences?.enqueue_failure_sound;
|
||||
if (soundName !== undefined) {
|
||||
const registry = SoundRegistry.getInstance();
|
||||
registry.playSound(soundName);
|
||||
}
|
||||
}
|
||||
|
||||
// let errorMessage = "Failed to enqueue image";
|
||||
// if ("error_type" in generateResponse) {
|
||||
// switch (generateResponse.error_type) {
|
||||
// case SoraImageRemixErrorType.SoraLoginRequired:
|
||||
// errorMessage =
|
||||
// "You need to log into Sora to continue. See the settings menu.";
|
||||
// break;
|
||||
// case SoraImageRemixErrorType.ServerError:
|
||||
// errorMessage = "Server error. Failed to enqueue image.";
|
||||
// break;
|
||||
// case SoraImageRemixErrorType.TooManyConcurrentTasks:
|
||||
// errorMessage =
|
||||
// "You have too many Sora image generation tasks running. Please wait a moment.";
|
||||
// break;
|
||||
// case SoraImageRemixErrorType.SoraUsernameNotYetCreated:
|
||||
// errorMessage =
|
||||
// "Your Sora username is not yet created. Please visit the Sora.com website to create it first.";
|
||||
// break;
|
||||
// case SoraImageRemixErrorType.SoraIsHavingProblems:
|
||||
// errorMessage = "Sora is having problems. Please try again later.";
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// toast.error(errorMessage);
|
||||
// }
|
||||
|
||||
setIsEnqueueing(false);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user