feat: show toast after upload is finished
This commit is contained in:
parent
3b75134572
commit
1d93482209
4 changed files with 336 additions and 59 deletions
196
Cargo.lock
generated
196
Cargo.lock
generated
|
@ -26,6 +26,22 @@ dependencies = [
|
|||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arboard"
|
||||
version = "3.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1df21f715862ede32a0c525ce2ca4d52626bb0007f8c18b87a384503ac33e70"
|
||||
dependencies = [
|
||||
"clipboard-win",
|
||||
"log",
|
||||
"objc2",
|
||||
"objc2-app-kit",
|
||||
"objc2-foundation",
|
||||
"parking_lot",
|
||||
"percent-encoding",
|
||||
"x11rb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ashpd"
|
||||
version = "0.11.0"
|
||||
|
@ -192,6 +208,15 @@ version = "0.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||
|
||||
[[package]]
|
||||
name = "clipboard-win"
|
||||
version = "5.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15efe7a882b08f34e38556b14f2fb3daa98769d06c7f0c1b076dfd0d983bc892"
|
||||
dependencies = [
|
||||
"error-code",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "color-eyre"
|
||||
version = "0.6.4"
|
||||
|
@ -340,6 +365,12 @@ dependencies = [
|
|||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "error-code"
|
||||
version = "3.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59"
|
||||
|
||||
[[package]]
|
||||
name = "event-listener"
|
||||
version = "5.4.0"
|
||||
|
@ -579,6 +610,16 @@ dependencies = [
|
|||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gethostname"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.16"
|
||||
|
@ -1136,6 +1177,12 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.9.4"
|
||||
|
@ -1280,6 +1327,7 @@ dependencies = [
|
|||
"bitflags",
|
||||
"block2",
|
||||
"objc2",
|
||||
"objc2-core-graphics",
|
||||
"objc2-foundation",
|
||||
]
|
||||
|
||||
|
@ -1294,6 +1342,19 @@ dependencies = [
|
|||
"objc2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-core-graphics"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"dispatch2 0.3.0",
|
||||
"objc2",
|
||||
"objc2-core-foundation",
|
||||
"objc2-io-surface",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-encode"
|
||||
version = "4.1.0"
|
||||
|
@ -1311,6 +1372,17 @@ dependencies = [
|
|||
"objc2-core-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-io-surface"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7282e9ac92529fa3457ce90ebb15f4ecbc383e8338060960760fa2cf75420c3c"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"objc2",
|
||||
"objc2-core-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.7"
|
||||
|
@ -1384,6 +1456,29 @@ version = "2.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.1"
|
||||
|
@ -1555,6 +1650,15 @@ version = "0.6.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539"
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.5.0"
|
||||
|
@ -1752,6 +1856,19 @@ dependencies = [
|
|||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys 0.4.15",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.0.7"
|
||||
|
@ -1761,7 +1878,7 @@ dependencies = [
|
|||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"linux-raw-sys 0.9.4",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
|
@ -2032,7 +2149,7 @@ dependencies = [
|
|||
"fastrand",
|
||||
"getrandom 0.3.3",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"rustix 1.0.7",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
|
@ -2280,6 +2397,7 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
|||
name = "tyrolienne"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"arboard",
|
||||
"color-eyre",
|
||||
"dirs",
|
||||
"futures",
|
||||
|
@ -2580,6 +2698,21 @@ dependencies = [
|
|||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.48.5",
|
||||
"windows_aarch64_msvc 0.48.5",
|
||||
"windows_i686_gnu 0.48.5",
|
||||
"windows_i686_msvc 0.48.5",
|
||||
"windows_x86_64_gnu 0.48.5",
|
||||
"windows_x86_64_gnullvm 0.48.5",
|
||||
"windows_x86_64_msvc 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
|
@ -2612,6 +2745,12 @@ dependencies = [
|
|||
"windows_x86_64_msvc 0.53.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
|
@ -2624,6 +2763,12 @@ version = "0.53.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
|
@ -2636,6 +2781,12 @@ version = "0.53.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
|
@ -2660,6 +2811,12 @@ version = "0.53.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
|
@ -2672,6 +2829,12 @@ version = "0.53.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
|
@ -2684,6 +2847,12 @@ version = "0.53.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
|
@ -2696,6 +2865,12 @@ version = "0.53.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
|
@ -2732,6 +2907,23 @@ version = "0.6.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
|
||||
|
||||
[[package]]
|
||||
name = "x11rb"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12"
|
||||
dependencies = [
|
||||
"gethostname",
|
||||
"rustix 0.38.44",
|
||||
"x11rb-protocol",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x11rb-protocol"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d"
|
||||
|
||||
[[package]]
|
||||
name = "yoke"
|
||||
version = "0.8.0"
|
||||
|
|
|
@ -4,6 +4,7 @@ version = "0.1.0"
|
|||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
arboard = { version = "3.5.0", default-features = false }
|
||||
color-eyre = "0.6.4"
|
||||
dirs = "6.0.0"
|
||||
futures = "0.3.31"
|
||||
|
|
120
src/main.rs
120
src/main.rs
|
@ -6,7 +6,7 @@ use std::{borrow::Cow, path::PathBuf, time::Duration};
|
|||
|
||||
use color_eyre::eyre::{OptionExt, Result, bail};
|
||||
use gobject::GtkZiplineFolder;
|
||||
use relm::{Dialog, DialogInput};
|
||||
use relm::{Dialog, DialogInput, Toast, ToastInput};
|
||||
use relm4::{
|
||||
Component, ComponentController, Controller, RelmApp, Sender,
|
||||
adw::{self, prelude::*},
|
||||
|
@ -51,7 +51,7 @@ enum Message {
|
|||
enum ProgressMessage {
|
||||
SetTotal(usize),
|
||||
Progress(usize),
|
||||
Finish,
|
||||
Finish(String),
|
||||
Error(String),
|
||||
}
|
||||
|
||||
|
@ -69,6 +69,7 @@ struct Tyrolienne {
|
|||
video_path: Option<PathBuf>,
|
||||
folder: Option<ZiplineFolder>,
|
||||
dialog: Controller<Dialog>,
|
||||
toast: Controller<Toast>,
|
||||
}
|
||||
|
||||
impl Tyrolienne {
|
||||
|
@ -100,63 +101,68 @@ impl AsyncComponent for Tyrolienne {
|
|||
set_title: Some("Tyrolienne"),
|
||||
set_default_width: 500,
|
||||
|
||||
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 0,
|
||||
|
||||
adw::HeaderBar {},
|
||||
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 32,
|
||||
set_margin_top: 32,
|
||||
set_margin_bottom: 32,
|
||||
set_margin_start: 32,
|
||||
set_margin_end: 32,
|
||||
|
||||
gtk::ListBox {
|
||||
set_selection_mode: gtk::SelectionMode::None,
|
||||
set_css_classes: &["boxed-list"],
|
||||
|
||||
adw::ActionRow {
|
||||
set_activatable: true,
|
||||
set_css_classes: &["property"],
|
||||
set_title: "Video file",
|
||||
#[watch]
|
||||
set_subtitle: &model.display_video_path(),
|
||||
connect_activated => Message::OpenFilePicker,
|
||||
},
|
||||
|
||||
adw::ComboRow {
|
||||
set_title: "Folder",
|
||||
set_model: Some(&folder_store),
|
||||
set_expression: Some(&folder_expression),
|
||||
connect_activated[sender] => move |r| {
|
||||
if let Some(item) = r
|
||||
.selected_item()
|
||||
.and_then(|i| i.downcast::<GtkZiplineFolder>().ok())
|
||||
{
|
||||
sender.input(Message::SetFolder(item.as_folder()));
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
#[local_ref]
|
||||
toast_overlay -> adw::ToastOverlay {
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 10,
|
||||
set_spacing: 32,
|
||||
set_margin_top: 32,
|
||||
set_margin_bottom: 32,
|
||||
set_margin_start: 32,
|
||||
set_margin_end: 32,
|
||||
|
||||
gtk::ProgressBar {
|
||||
#[watch]
|
||||
set_fraction: model.progress as f64 / model.total as f64,
|
||||
gtk::ListBox {
|
||||
set_selection_mode: gtk::SelectionMode::None,
|
||||
set_css_classes: &["boxed-list"],
|
||||
|
||||
adw::ActionRow {
|
||||
set_activatable: true,
|
||||
set_css_classes: &["property"],
|
||||
set_title: "Video file",
|
||||
#[watch]
|
||||
set_subtitle: &model.display_video_path(),
|
||||
connect_activated => Message::OpenFilePicker,
|
||||
},
|
||||
|
||||
adw::ComboRow {
|
||||
set_title: "Folder",
|
||||
set_model: Some(&folder_store),
|
||||
set_expression: Some(&folder_expression),
|
||||
connect_activated[sender] => move |r| {
|
||||
if let Some(item) = r
|
||||
.selected_item()
|
||||
.and_then(|i| i.downcast::<GtkZiplineFolder>().ok())
|
||||
{
|
||||
sender.input(Message::SetFolder(item.as_folder()));
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
gtk::Button {
|
||||
#[watch]
|
||||
set_label: if model.locked { "Uploading..." } else { "Send" },
|
||||
#[watch]
|
||||
set_sensitive: !model.locked && model.video_path.is_some(),
|
||||
connect_clicked => Message::StartTheProcess,
|
||||
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 10,
|
||||
|
||||
gtk::ProgressBar {
|
||||
#[watch]
|
||||
set_fraction: model.progress as f64 / model.total as f64,
|
||||
},
|
||||
|
||||
gtk::Button {
|
||||
#[watch]
|
||||
set_label: if model.locked { "Uploading..." } else { "Send" },
|
||||
#[watch]
|
||||
set_sensitive: !model.locked && model.video_path.is_some(),
|
||||
connect_clicked => Message::StartTheProcess,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -169,6 +175,8 @@ impl AsyncComponent for Tyrolienne {
|
|||
root: Self::Root,
|
||||
sender: relm4::AsyncComponentSender<Self>,
|
||||
) -> AsyncComponentParts<Self> {
|
||||
let toast_overlay = adw::ToastOverlay::new();
|
||||
|
||||
let model = Tyrolienne {
|
||||
config,
|
||||
locked: false,
|
||||
|
@ -177,7 +185,10 @@ impl AsyncComponent for Tyrolienne {
|
|||
video_path: None,
|
||||
folder: None,
|
||||
dialog: Dialog::builder()
|
||||
.launch(root.clone())
|
||||
.launch(toast_overlay.clone())
|
||||
.forward(sender.input_sender(), |_| Message::Nothing),
|
||||
toast: Toast::builder()
|
||||
.launch(toast_overlay.clone())
|
||||
.forward(sender.input_sender(), |_| Message::Nothing),
|
||||
};
|
||||
|
||||
|
@ -242,10 +253,7 @@ impl AsyncComponent for Tyrolienne {
|
|||
shutdown
|
||||
.register(async move {
|
||||
match the_process(info, &out).await {
|
||||
Ok(url) => {
|
||||
tracing::info!("{url}");
|
||||
out.emit(ProgressMessage::Finish);
|
||||
}
|
||||
Ok(url) => out.emit(ProgressMessage::Finish(url)),
|
||||
Err(e) => out.emit(ProgressMessage::Error(e.to_string())),
|
||||
}
|
||||
})
|
||||
|
@ -265,12 +273,14 @@ impl AsyncComponent for Tyrolienne {
|
|||
match message {
|
||||
ProgressMessage::SetTotal(total) => self.total = total,
|
||||
ProgressMessage::Progress(prog) => self.progress += prog,
|
||||
ProgressMessage::Finish | ProgressMessage::Error(_) => {
|
||||
ProgressMessage::Finish(_) | ProgressMessage::Error(_) => {
|
||||
self.locked = false;
|
||||
self.progress = 0;
|
||||
self.total = 1;
|
||||
|
||||
if let ProgressMessage::Error(e) = message {
|
||||
if let ProgressMessage::Finish(url) = message {
|
||||
self.toast.emit(ToastInput::Show(url));
|
||||
} else if let ProgressMessage::Error(e) = message {
|
||||
self.dialog.emit(DialogInput::Show {
|
||||
heading: "An error occurred".into(),
|
||||
body: e.to_string(),
|
||||
|
|
78
src/relm.rs
78
src/relm.rs
|
@ -5,7 +5,9 @@ use relm4::{
|
|||
};
|
||||
|
||||
pub struct Dialog {
|
||||
window: adw::ApplicationWindow,
|
||||
// toast overlay looks like an odd choice but i think it's fitting considering it acts as a
|
||||
// "box" for the main content
|
||||
window: adw::ToastOverlay,
|
||||
visible: bool,
|
||||
heading: String,
|
||||
body: String,
|
||||
|
@ -22,7 +24,7 @@ pub struct DialogWidgets {
|
|||
}
|
||||
|
||||
impl SimpleComponent for Dialog {
|
||||
type Init = adw::ApplicationWindow;
|
||||
type Init = adw::ToastOverlay;
|
||||
type Root = adw::AlertDialog;
|
||||
type Widgets = DialogWidgets;
|
||||
type Input = DialogInput;
|
||||
|
@ -80,3 +82,75 @@ impl SimpleComponent for Dialog {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Toast {
|
||||
root: adw::ToastOverlay,
|
||||
visible: bool,
|
||||
text: String,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ToastInput {
|
||||
Show(String),
|
||||
Copy,
|
||||
Dismiss,
|
||||
}
|
||||
|
||||
#[relm4::component(pub)]
|
||||
impl SimpleComponent for Toast {
|
||||
type Input = ToastInput;
|
||||
type Output = ();
|
||||
type Init = adw::ToastOverlay;
|
||||
|
||||
view! {
|
||||
#[name = "toast"]
|
||||
adw::Toast {
|
||||
#[watch]
|
||||
set_title: &model.text,
|
||||
set_button_label: Some("Copy"),
|
||||
connect_button_clicked => ToastInput::Copy,
|
||||
connect_dismissed => ToastInput::Dismiss,
|
||||
}
|
||||
}
|
||||
|
||||
fn init(
|
||||
init: Self::Init,
|
||||
root: Self::Root,
|
||||
_sender: relm4::ComponentSender<Self>,
|
||||
) -> relm4::ComponentParts<Self> {
|
||||
let model = Self {
|
||||
root: init,
|
||||
visible: false,
|
||||
text: String::new(),
|
||||
};
|
||||
|
||||
let widgets = view_output!();
|
||||
relm4::ComponentParts { model, widgets }
|
||||
}
|
||||
|
||||
fn update(&mut self, message: Self::Input, _sender: relm4::ComponentSender<Self>) {
|
||||
match message {
|
||||
ToastInput::Show(text) => {
|
||||
self.visible = true;
|
||||
self.text = text;
|
||||
}
|
||||
ToastInput::Copy => {
|
||||
if let Err(e) =
|
||||
arboard::Clipboard::new().and_then(|mut c| c.set_text(self.text.clone()))
|
||||
{
|
||||
tracing::error!("could not copy url to clipboard: {e}");
|
||||
self.text = "Could not copy".into();
|
||||
} else {
|
||||
self.visible = false;
|
||||
}
|
||||
}
|
||||
ToastInput::Dismiss => self.visible = false,
|
||||
}
|
||||
}
|
||||
|
||||
fn post_view() {
|
||||
if model.visible {
|
||||
model.root.add_toast(widgets.toast.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue