From fd21b79b3bc9cec5b46ef9a7dc0e7483cd6ccb40 Mon Sep 17 00:00:00 2001 From: dmackdev Date: Sun, 17 Sep 2023 14:15:22 +0100 Subject: [PATCH] Add notification toasts. --- Cargo.lock | 11 +++++++++++ Cargo.toml | 1 - pubsubman/Cargo.toml | 1 + pubsubman/src/app.rs | 11 +++++++++-- pubsubman/src/lib.rs | 1 + pubsubman/src/notifications.rs | 27 +++++++++++++++++++++++++++ pubsubman_backend/Cargo.toml | 1 + pubsubman_backend/src/lib.rs | 12 ++++++++---- pubsubman_backend/src/message.rs | 9 +++++++-- pubsubman_backend/src/model/mod.rs | 14 ++++++++++++++ 10 files changed, 79 insertions(+), 9 deletions(-) create mode 100644 pubsubman/src/notifications.rs diff --git a/Cargo.lock b/Cargo.lock index 8ff939a..06d56b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -980,6 +980,15 @@ dependencies = [ "serde", ] +[[package]] +name = "egui-notify" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d57ed9c398e24c1b9faf2c52cdc305dd29cb1d9dfa12a0166d254582bc47727a" +dependencies = [ + "egui", +] + [[package]] name = "egui-winit" version = "0.22.0" @@ -2559,6 +2568,7 @@ dependencies = [ "clap", "eframe", "egui", + "egui-notify", "egui_extras", "egui_json_tree", "env_logger", @@ -2581,6 +2591,7 @@ dependencies = [ "google-cloud-googleapis", "google-cloud-pubsub", "serde", + "thiserror", "tokio", "tokio-util", "uuid", diff --git a/Cargo.toml b/Cargo.toml index 52495b0..20316a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,6 @@ opt-level = 2 # fast and small wasm [profile.dev.package."*"] opt-level = 2 - [patch.crates-io] egui = { git = "https://github.com/emilk/egui", rev = "23ce4e7" } egui_extras = { git = "https://github.com/emilk/egui", rev = "23ce4e7" } diff --git a/pubsubman/Cargo.toml b/pubsubman/Cargo.toml index 0899450..911b6f6 100644 --- a/pubsubman/Cargo.toml +++ b/pubsubman/Cargo.toml @@ -22,3 +22,4 @@ tokio-util = { workspace = true } pubsubman_backend = { version = "0.1.0", path = "../pubsubman_backend" } serde_json = "1.0.104" clap = { version = "4.4.0", features = ["derive"] } +egui-notify = "0.9.0" diff --git a/pubsubman/src/app.rs b/pubsubman/src/app.rs index 64803e6..555dfed 100644 --- a/pubsubman/src/app.rs +++ b/pubsubman/src/app.rs @@ -11,6 +11,7 @@ use crate::{ actions::{create_subscription, delete_subscriptions, refresh_topics}, column_settings::ColumnSettings, exit_state::{ExitState, SubscriptionCleanupState}, + notifications::Notifications, settings::Settings, ui::{render_topic_name, MessagesView, PublishView}, }; @@ -33,6 +34,7 @@ pub struct App { memory: Memory, front_tx: Sender, back_rx: Receiver, + notifications: Notifications, } impl App { @@ -63,15 +65,19 @@ impl App { memory, front_tx, back_rx, + notifications: Notifications::default(), } } fn handle_backend_message(&mut self) { match self.back_rx.try_recv() { Ok(message) => match message { - BackendMessage::ClientInitialised => {} + BackendMessage::ClientInitialised(project_id) => self + .notifications + .success(format!("Successfully authenticated to: {}.", project_id)), BackendMessage::TopicsUpdated(topic_names) => { self.topic_names = topic_names; + refresh_topics(&self.front_tx, Some(5000)); } BackendMessage::SubscriptionCreated(topic_name, sub_name) => { @@ -94,7 +100,7 @@ impl App { self.exit_state.subscription_cleanup_state = SubscriptionCleanupState::Complete; } - BackendMessage::Error(_) => {} + BackendMessage::Error(err) => self.notifications.error(err), }, Err(_err) => {} } @@ -282,6 +288,7 @@ impl eframe::App for App { self.render_topics_panel(ctx); self.render_central_panel(ctx); self.handle_exit(ctx, frame); + self.notifications.show(ctx); } fn save(&mut self, storage: &mut dyn eframe::Storage) { diff --git a/pubsubman/src/lib.rs b/pubsubman/src/lib.rs index 979502f..9a30f5e 100644 --- a/pubsubman/src/lib.rs +++ b/pubsubman/src/lib.rs @@ -4,6 +4,7 @@ mod actions; mod app; mod column_settings; mod exit_state; +mod notifications; mod settings; mod ui; pub use app::App; diff --git a/pubsubman/src/notifications.rs b/pubsubman/src/notifications.rs new file mode 100644 index 0000000..c81da51 --- /dev/null +++ b/pubsubman/src/notifications.rs @@ -0,0 +1,27 @@ +use egui_notify::Toasts; +use pubsubman_backend::message::BackendError; + +#[derive(Default)] +pub struct Notifications { + toasts: Toasts, +} + +impl Notifications { + pub fn show(&mut self, ctx: &egui::Context) { + let ctx = ctx.clone(); + + ctx.style_mut(|style| { + style.visuals.widgets.noninteractive.bg_fill = egui::Color32::from_rgb(50, 50, 50); + }); + + self.toasts.show(&ctx); + } + + pub fn success(&mut self, message: String) { + self.toasts.success(message).set_show_progress_bar(false); + } + + pub fn error(&mut self, error: BackendError) { + self.toasts.error(error.to_string()); + } +} diff --git a/pubsubman_backend/Cargo.toml b/pubsubman_backend/Cargo.toml index 83b7af5..ddeae8d 100644 --- a/pubsubman_backend/Cargo.toml +++ b/pubsubman_backend/Cargo.toml @@ -13,6 +13,7 @@ google-cloud-gax = "0.15.0" google-cloud-googleapis = "0.11.0" google-cloud-pubsub = "0.20.0" serde = { workspace = true } +thiserror = "1.0.48" tokio = { workspace = true } tokio-util = { workspace = true } diff --git a/pubsubman_backend/src/lib.rs b/pubsubman_backend/src/lib.rs index 4068a49..96dcc8a 100644 --- a/pubsubman_backend/src/lib.rs +++ b/pubsubman_backend/src/lib.rs @@ -42,11 +42,11 @@ impl Backend { .unwrap(); match rt.block_on(async { create_client(emulator_project_id).await }) { - Ok(client) => { + Ok((client, project_id)) => { let back_tx_clone = back_tx.clone(); rt.spawn(async move { back_tx_clone - .send(BackendMessage::ClientInitialised) + .send(BackendMessage::ClientInitialised(project_id)) .await .unwrap(); }); @@ -235,7 +235,9 @@ impl Backend { } } -async fn create_client(emulator_project_id: Option) -> Result> { +async fn create_client( + emulator_project_id: Option, +) -> Result<(Client, String), Box> { let mut config = ClientConfig::default().with_auth().await?; if let (Environment::Emulator(_), Some(emulator_project_id)) = @@ -244,5 +246,7 @@ async fn create_client(emulator_project_id: Option) -> Result), SubscriptionCreated(TopicName, SubscriptionName), MessageReceived(TopicName, PubsubMessage), @@ -21,11 +21,16 @@ pub enum BackendMessage { Error(BackendError), } -#[derive(Debug)] +#[derive(Debug, thiserror::Error)] pub enum BackendError { + #[error("Failed to initialise client.")] ClientInitFailed, + #[error("Failed to get topics.")] GetTopicsFailed, + #[error("Failed to create Subscription for {0}.")] CreateSubscriptionFailed(TopicName), + #[error("Failed to get messages from {0}.")] StreamMessagesFailed(TopicName, SubscriptionName), + #[error("Failed to publish message to {0}.")] PublishMessageFailed(TopicName), } diff --git a/pubsubman_backend/src/model/mod.rs b/pubsubman_backend/src/model/mod.rs index 6887b70..e2d6328 100644 --- a/pubsubman_backend/src/model/mod.rs +++ b/pubsubman_backend/src/model/mod.rs @@ -1,6 +1,8 @@ mod pubsub_message; mod pubsub_message_to_publish; +use std::fmt::Display; + pub use pubsub_message::PubsubMessage; pub use pubsub_message_to_publish::PubsubMessageToPublish; @@ -9,7 +11,19 @@ pub use pubsub_message_to_publish::PubsubMessageToPublish; )] pub struct TopicName(pub String); +impl Display for TopicName { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + #[derive( Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, serde::Deserialize, serde::Serialize, )] pub struct SubscriptionName(pub String); + +impl Display for SubscriptionName { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +}