diff --git a/Cargo.lock b/Cargo.lock index f90879a..911f69f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2224,6 +2224,7 @@ dependencies = [ "tokio-util", "toml", "urlencoding", + "winresource", ] [[package]] @@ -2285,6 +2286,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "want" version = "0.3.1" @@ -2700,6 +2707,16 @@ dependencies = [ "memchr", ] +[[package]] +name = "winresource" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba4a67c78ee5782c0c1cb41bebc7e12c6e79644daa1650ebbc1de5d5b08593f7" +dependencies = [ + "toml", + "version_check", +] + [[package]] name = "wit-bindgen-rt" version = "0.39.0" diff --git a/Cargo.toml b/Cargo.toml index 988e650..dd6f1d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,3 +23,6 @@ opt-level = "z" lto = "thin" strip = true panic = "abort" + +[build-dependencies] +winresource = "0.1.20" diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..52233ae --- /dev/null +++ b/build.rs @@ -0,0 +1,13 @@ +use std::{env, io}; + +use winresource::WindowsResource; + +fn main() -> Result<(), io::Error> { + if env::var_os("CARGO_CFG_WINDOWS").is_some() { + WindowsResource::new() + .set_icon("res/tyrolienne.ico") + .compile()?; + } + + Ok(()) +} diff --git a/res/tyrolienne.ico b/res/tyrolienne.ico new file mode 100644 index 0000000..4bbf991 Binary files /dev/null and b/res/tyrolienne.ico differ diff --git a/src/main.rs b/src/main.rs index db9edd2..609d956 100644 --- a/src/main.rs +++ b/src/main.rs @@ -159,6 +159,8 @@ impl AsyncComponent for Tyrolienne { gtk::ListBox { set_selection_mode: gtk::SelectionMode::None, set_css_classes: &["boxed-list"], + #[watch] + set_sensitive: matches!(model.step, Step::Waiting), adw::ActionRow { set_activatable: true, @@ -391,7 +393,6 @@ impl AsyncComponent for Tyrolienne { } } -// TODO app icon (windows) fn main() { match ffmpeg::check().and_then(|_| get_config()) { Ok(config) => RelmApp::new("net.uku3lig.tyrolienne").run_async::(config), diff --git a/src/relm.rs b/src/relm.rs index 3c84af0..b01336d 100644 --- a/src/relm.rs +++ b/src/relm.rs @@ -150,7 +150,6 @@ impl SimpleComponent for Toast { pub struct StandaloneDialog; -// TODO: don't open a window, just give a HeaderBar to the dialog impl SimpleComponent for StandaloneDialog { type Init = String; type Input = (); diff --git a/src/zipline.rs b/src/zipline.rs index f4d8690..1744e54 100644 --- a/src/zipline.rs +++ b/src/zipline.rs @@ -1,6 +1,6 @@ -use std::{path::Path, sync::LazyLock}; +use std::{error::Error, fmt::Display, path::Path, sync::LazyLock}; -use anyhow::{Result, bail}; +use anyhow::Result; use futures::StreamExt; use relm4::Sender; use reqwest::{ @@ -47,6 +47,25 @@ pub struct ZiplineShortUrl { url: String, } +#[derive(Debug, serde::Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ZiplineError { + error: String, + status_code: usize, +} + +impl Display for ZiplineError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "An error occurred ({}): {}", + self.status_code, self.error + ) + } +} + +impl Error for ZiplineError {} + impl ZiplineFileInfo { pub fn thumbnail_url(&self, config: &Config) -> Option { self.thumbnail @@ -80,7 +99,6 @@ async fn wrap_file(path: &Path, sender: Sender) -> Result }) } -// TODO: make a ZiplineError type pub async fn get_folders(config: &Config) -> Result> { let url = format!("{}api/user/folders?noincl=true", config.fixed_url()); @@ -91,11 +109,7 @@ pub async fn get_folders(config: &Config) -> Result> { .await?; if res.status() != StatusCode::OK { - bail!( - "an error occurred ({}): {}", - res.status(), - res.text().await? - ); + Err(res.json::().await?.into()) } else { res.json().await.map_err(Into::into) } @@ -125,11 +139,7 @@ pub async fn upload_file( let res = req.send().await?; if res.status() != StatusCode::OK { - bail!( - "an error occurred ({}): {}", - res.status(), - res.text().await? - ); + Err(res.json::().await?.into()) } else { res.json().await.map_err(Into::into) } @@ -146,11 +156,7 @@ pub async fn recalc_thumbnails(config: &Config) -> Result<()> { .await?; if res.status() != StatusCode::OK { - bail!( - "an error occurred ({}): {}", - res.status(), - res.text().await? - ); + Err(res.json::().await?.into()) } else { Ok(()) } @@ -166,11 +172,7 @@ pub async fn get_file_details(config: &Config, id: &str) -> Result().await?.into()) } else { res.json().await.map_err(Into::into) } @@ -193,11 +195,7 @@ pub async fn shorten_url(config: &Config, to_shorten: &str) -> Result { .await?; if res.status() != StatusCode::OK { - bail!( - "an error occurred ({}): {}", - res.status(), - res.text().await? - ); + Err(res.json::().await?.into()) } else { let out: ZiplineShortUrl = res.json().await?;