diff --git a/src/ui/identities/add_new_identity_screen/mod.rs b/src/ui/identities/add_new_identity_screen/mod.rs index 937758127..7b5b89477 100644 --- a/src/ui/identities/add_new_identity_screen/mod.rs +++ b/src/ui/identities/add_new_identity_screen/mod.rs @@ -1113,7 +1113,12 @@ impl ScreenLike for AddNewIdentityScreen { .stroke(egui::Stroke::new(1.0, message_color)) .show(ui, |ui| { ui.horizontal(|ui| { - ui.label(egui::RichText::new(&error_message).color(message_color)); + ui.add( + egui::Label::new( + egui::RichText::new(&error_message).color(message_color), + ) + .wrap(), + ); ui.add_space(10.0); if ui.small_button("Dismiss").clicked() { self.error_message = None; diff --git a/src/ui/identities/keys/key_info_screen.rs b/src/ui/identities/keys/key_info_screen.rs index 1917ab876..1f104c44e 100644 --- a/src/ui/identities/keys/key_info_screen.rs +++ b/src/ui/identities/keys/key_info_screen.rs @@ -5,7 +5,9 @@ use crate::model::qualified_identity::encrypted_key_storage::{ PrivateKeyData, WalletDerivationPath, }; use crate::model::wallet::Wallet; +use crate::ui::MessageType; use crate::ui::ScreenLike; +use crate::ui::components::MessageBanner; use crate::ui::components::info_popup::InfoPopup; use crate::ui::components::left_panel::add_left_panel; use crate::ui::components::styled::island_central_panel; @@ -256,7 +258,12 @@ impl ScreenLike for KeyInfoScreen { ui.label(RichText::new(hash_hex).color(text_primary)); } Err(e) => { - ui.colored_label(egui::Color32::RED, format!("Error: {}", e)); + MessageBanner::set_global( + ui.ctx(), + &format!("Error: {}", e), + MessageType::Error, + ); + ui.label(RichText::new("Unavailable").color(text_primary)); } } @@ -281,7 +288,12 @@ impl ScreenLike for KeyInfoScreen { ); } Err(e) => { - ui.colored_label(egui::Color32::RED, format!("Error: {}", e)); + MessageBanner::set_global( + ui.ctx(), + &format!("Error: {}", e), + MessageType::Error, + ); + ui.label(RichText::new("Unavailable").color(text_primary)); } } } @@ -420,14 +432,22 @@ impl ScreenLike for KeyInfoScreen { self.decrypted_private_key = Some(private_key); } Err(e) => { - ui.label(format!("Error: {}", e)); + ui.add( + egui::Label::new(format!("Error: {}", e)).wrap(), + ); return; } } } self.render_sign_input(ui); } else if self.wallet_open { - ui.colored_label(Color32::DARK_RED, "Key is in encrypted wallet"); + ui.add( + egui::Label::new( + egui::RichText::new("Key is in encrypted wallet") + .color(Color32::DARK_RED), + ) + .wrap(), + ); ui.add_space(10.0); if ui.button("View Private Key").clicked() { @@ -476,14 +496,22 @@ impl ScreenLike for KeyInfoScreen { self.decrypted_private_key = Some(private_key); } Err(e) => { - ui.label(format!("Error: {}", e)); + ui.add( + egui::Label::new(format!("Error: {}", e)).wrap(), + ); return; } } } self.render_sign_input(ui); } else { - ui.colored_label(Color32::DARK_RED, "Key is in encrypted wallet"); + ui.add( + egui::Label::new( + egui::RichText::new("Key is in encrypted wallet") + .color(Color32::DARK_RED), + ) + .wrap(), + ); ui.add_space(10.0); if ui.button("View Private Key").clicked() { diff --git a/src/ui/identities/register_dpns_name_screen.rs b/src/ui/identities/register_dpns_name_screen.rs index 7ceb12809..f937469e9 100644 --- a/src/ui/identities/register_dpns_name_screen.rs +++ b/src/ui/identities/register_dpns_name_screen.rs @@ -5,6 +5,7 @@ use crate::context::AppContext; use crate::model::fee_estimation::format_credits_as_dash; use crate::model::qualified_identity::QualifiedIdentity; use crate::model::wallet::Wallet; +use crate::ui::components::MessageBanner; use crate::ui::components::identity_selector::IdentitySelector; use crate::ui::components::left_panel::add_left_panel; use crate::ui::components::styled::island_central_panel; @@ -296,6 +297,11 @@ impl RegisterDpnsNameScreen { impl ScreenLike for RegisterDpnsNameScreen { fn display_message(&mut self, message: &str, message_type: MessageType) { if let MessageType::Error = message_type { + MessageBanner::set_global( + self.app_context.egui_ctx(), + &format!("Error: {}", message), + MessageType::Error, + ); self.register_dpns_name_status = RegisterDpnsNameStatus::ErrorMessage(message.to_string()); } @@ -306,6 +312,12 @@ impl ScreenLike for RegisterDpnsNameScreen { backend_task_success_result { self.completed_fee_result = Some(fee_result); + if let RegisterDpnsNameStatus::ErrorMessage(msg) = &self.register_dpns_name_status { + MessageBanner::clear_global_message( + self.app_context.egui_ctx(), + &format!("Error: {}", msg), + ); + } self.register_dpns_name_status = RegisterDpnsNameStatus::Complete; } } @@ -589,22 +601,13 @@ impl ScreenLike for RegisterDpnsNameScreen { )); } RegisterDpnsNameStatus::ErrorMessage(msg) => { - let error_color = DashColors::ERROR; - let msg = msg.clone(); - Frame::new() - .fill(error_color.gamma_multiply(0.1)) - .inner_margin(Margin::symmetric(10, 8)) - .corner_radius(5.0) - .stroke(egui::Stroke::new(1.0, error_color)) - .show(ui, |ui| { - ui.horizontal(|ui| { - ui.label(RichText::new(format!("Error: {}", msg)).color(error_color)); - ui.add_space(10.0); - if ui.small_button("Dismiss").clicked() { - self.register_dpns_name_status = RegisterDpnsNameStatus::NotStarted; - } - }); - }); + let banner_text = format!("Error: {}", msg); + ui.horizontal(|ui| { + if ui.small_button("Dismiss").clicked() { + MessageBanner::clear_global_message(ui.ctx(), &banner_text); + self.register_dpns_name_status = RegisterDpnsNameStatus::NotStarted; + } + }); } RegisterDpnsNameStatus::Complete => {} } diff --git a/src/ui/identities/top_up_identity_screen/mod.rs b/src/ui/identities/top_up_identity_screen/mod.rs index cd13a469a..73aaecd09 100644 --- a/src/ui/identities/top_up_identity_screen/mod.rs +++ b/src/ui/identities/top_up_identity_screen/mod.rs @@ -522,6 +522,7 @@ impl ScreenLike for TopUpIdentityScreen { action |= island_central_panel(ctx, |ui| { let mut inner_action = AppAction::None; + let _dark_mode = ui.ctx().style().visuals.dark_mode; ScrollArea::vertical().show(ui, |ui| { let step = { *self.step.read().unwrap() }; diff --git a/src/ui/identities/withdraw_screen.rs b/src/ui/identities/withdraw_screen.rs index b3de54760..e1a29b9c7 100644 --- a/src/ui/identities/withdraw_screen.rs +++ b/src/ui/identities/withdraw_screen.rs @@ -183,7 +183,12 @@ impl WithdrawalScreen { // Show error next to input if let Some(error) = &self.withdrawal_address_error { - ui.colored_label(DashColors::ERROR, error); + ui.add( + egui::Label::new( + egui::RichText::new(error).color(DashColors::ERROR), + ) + .wrap(), + ); } }); diff --git a/src/ui/tokens/set_token_price_screen.rs b/src/ui/tokens/set_token_price_screen.rs index 6e86365b2..4698ec6c2 100644 --- a/src/ui/tokens/set_token_price_screen.rs +++ b/src/ui/tokens/set_token_price_screen.rs @@ -7,6 +7,7 @@ use crate::model::amount::{Amount, DASH_DECIMAL_PLACES}; use crate::model::fee_estimation::format_credits_as_dash; use crate::model::wallet::Wallet; use crate::ui::components::ComponentResponse; +use crate::ui::components::MessageBanner; use crate::ui::components::amount_input::AmountInput; use crate::ui::components::component_trait::Component; use crate::ui::components::confirmation_dialog::{ConfirmationDialog, ConfirmationStatus}; @@ -113,6 +114,7 @@ pub struct SetTokenPriceScreen { // If needed for password-based wallet unlocking: selected_wallet: Option>>, wallet_unlock_popup: WalletUnlockPopup, + remove_pricing_warning_posted: bool, // Fee result from completed operation completed_fee_result: Option, } @@ -283,6 +285,7 @@ impl SetTokenPriceScreen { confirmation_dialog: None, selected_wallet, wallet_unlock_popup: WalletUnlockPopup::new(), + remove_pricing_warning_posted: false, completed_fee_result: None, } } @@ -340,6 +343,8 @@ impl SetTokenPriceScreen { /// Renders the pricing input UI fn render_pricing_input(&mut self, ui: &mut Ui) { + let previous_pricing_type = self.pricing_type.clone(); + // Radio buttons for pricing type ui.horizontal(|ui| { ui.radio_value( @@ -359,6 +364,18 @@ impl SetTokenPriceScreen { ); }); + let remove_pricing_warning = "WARNING: This will remove the pricing schedule, making the token unavailable for direct purchase."; + if self.pricing_type != PricingType::RemovePricing && self.remove_pricing_warning_posted { + MessageBanner::clear_global_message(ui.ctx(), remove_pricing_warning); + self.remove_pricing_warning_posted = false; + } + if self.pricing_type == PricingType::RemovePricing + && (!self.remove_pricing_warning_posted || self.pricing_type != previous_pricing_type) + { + MessageBanner::set_global(ui.ctx(), remove_pricing_warning, MessageType::Warning); + self.remove_pricing_warning_posted = true; + } + ui.add_space(10.0); match self.pricing_type { @@ -519,7 +536,6 @@ impl SetTokenPriceScreen { self.render_tiered_pricing_preview(ui); } PricingType::RemovePricing => { - ui.colored_label(Color32::from_rgb(180, 100, 0), "WARNING: This will remove the pricing schedule, making the token unavailable for direct purchase."); ui.label("Users will no longer be able to buy this token directly."); } } @@ -554,7 +570,13 @@ impl SetTokenPriceScreen { } if has_errors { - ui.colored_label(Color32::DARK_RED, "X Some tiers have invalid values"); + ui.add( + egui::Label::new( + egui::RichText::new("X Some tiers have invalid values") + .color(Color32::DARK_RED), + ) + .wrap(), + ); } if !valid_tiers.is_empty() { @@ -778,6 +800,13 @@ impl SetTokenPriceScreen { fn set_error_state(&mut self, error: String) { self.error_message = Some(error.clone()); self.status = SetTokenPriceStatus::ErrorMessage(error); + if let SetTokenPriceStatus::ErrorMessage(ref msg) = self.status { + MessageBanner::set_global( + self.app_context.egui_ctx(), + &format!("Error: {}", msg), + MessageType::Error, + ); + } } /// Renders a confirm popup with the final "Are you sure?" step @@ -822,12 +851,23 @@ impl ScreenLike for SetTokenPriceScreen { if let MessageType::Error = message_type { self.status = SetTokenPriceStatus::ErrorMessage(message.to_string()); self.error_message = Some(message.to_string()); + MessageBanner::set_global( + self.app_context.egui_ctx(), + &format!("Error: {}", message), + MessageType::Error, + ); } } fn display_task_result(&mut self, backend_task_success_result: BackendTaskSuccessResult) { if let BackendTaskSuccessResult::SetTokenPrice(fee_result) = backend_task_success_result { self.completed_fee_result = Some(fee_result); + if let SetTokenPriceStatus::ErrorMessage(msg) = &self.status { + MessageBanner::clear_global_message( + self.app_context.egui_ctx(), + &format!("Error: {}", msg), + ); + } self.status = SetTokenPriceStatus::Complete; } } @@ -1149,22 +1189,13 @@ impl ScreenLike for SetTokenPriceScreen { ui.label(format!("Setting price... elapsed: {} seconds", elapsed)); } SetTokenPriceStatus::ErrorMessage(msg) => { - let error_color = DashColors::ERROR; - let msg = msg.clone(); - Frame::new() - .fill(error_color.gamma_multiply(0.1)) - .inner_margin(Margin::symmetric(10, 8)) - .corner_radius(5.0) - .stroke(egui::Stroke::new(1.0, error_color)) - .show(ui, |ui| { - ui.horizontal(|ui| { - ui.label(RichText::new(format!("Error: {}", msg)).color(error_color)); - ui.add_space(10.0); - if ui.small_button("Dismiss").clicked() { - self.status = SetTokenPriceStatus::NotStarted; - } - }); - }); + let banner_text = format!("Error: {}", msg); + ui.horizontal(|ui| { + if ui.small_button("Dismiss").clicked() { + MessageBanner::clear_global_message(ui.ctx(), &banner_text); + self.status = SetTokenPriceStatus::NotStarted; + } + }); } SetTokenPriceStatus::Complete => { // handled above diff --git a/src/ui/tokens/tokens_screen/keyword_search.rs b/src/ui/tokens/tokens_screen/keyword_search.rs index 1879675f1..ff3117e45 100644 --- a/src/ui/tokens/tokens_screen/keyword_search.rs +++ b/src/ui/tokens/tokens_screen/keyword_search.rs @@ -148,7 +148,12 @@ impl TokensScreen { .stroke(egui::Stroke::new(1.0, error_color)) .show(ui, |ui| { ui.horizontal(|ui| { - ui.label(RichText::new(format!("Error: {}", msg)).color(error_color)); + ui.add( + egui::Label::new( + RichText::new(format!("Error: {}", msg)).color(error_color), + ) + .wrap(), + ); ui.add_space(10.0); if ui.small_button("Dismiss").clicked() { self.contract_search_status = ContractSearchStatus::NotStarted; diff --git a/src/ui/tokens/tokens_screen/token_creator.rs b/src/ui/tokens/tokens_screen/token_creator.rs index b98924f7a..b7f86c8a3 100644 --- a/src/ui/tokens/tokens_screen/token_creator.rs +++ b/src/ui/tokens/tokens_screen/token_creator.rs @@ -71,7 +71,16 @@ impl TokensScreen { Ok(identities) => identities.into_iter().filter(|qi| !qi.private_keys.private_keys.is_empty()).collect::>(), Err(e) => { tracing::error!(err=?e, "Error loading identities from local DB."); - ui.colored_label(Color32::DARK_RED,format!("Error loading identities from local DB: {}", e)); + ui.add( + egui::Label::new( + egui::RichText::new(format!( + "Error loading identities from local DB: {}", + e + )) + .color(Color32::DARK_RED), + ) + .wrap(), + ); return; } }; @@ -547,7 +556,16 @@ impl TokensScreen { seen_keywords.insert(name.0.clone()); for keyword in contract_keywords.iter() { if seen_keywords.contains(*keyword) { - ui.colored_label(Color32::DARK_RED, format!("Duplicate contract keyword: {}", keyword)); + ui.add( + egui::Label::new( + egui::RichText::new(format!( + "Duplicate contract keyword: {}", + keyword + )) + .color(Color32::DARK_RED), + ) + .wrap(), + ); } seen_keywords.insert(keyword.to_string()); } @@ -979,7 +997,12 @@ impl TokensScreen { .stroke(egui::Stroke::new(1.0, error_color)) .show(ui, |ui| { ui.horizontal(|ui| { - ui.label(RichText::new(format!("Error: {}", err_msg)).color(error_color)); + ui.add( + egui::Label::new( + RichText::new(format!("Error: {}", err_msg)).color(error_color), + ) + .wrap(), + ); ui.add_space(10.0); if ui.small_button("Dismiss").clicked() { self.token_creator_error_message = None; diff --git a/src/ui/tokens/update_token_config.rs b/src/ui/tokens/update_token_config.rs index 1de17195f..94692c8ff 100644 --- a/src/ui/tokens/update_token_config.rs +++ b/src/ui/tokens/update_token_config.rs @@ -6,6 +6,7 @@ use crate::context::AppContext; use crate::model::fee_estimation::format_credits_as_dash; use crate::model::qualified_identity::QualifiedIdentity; use crate::model::wallet::Wallet; +use crate::ui::components::MessageBanner; use crate::ui::components::left_panel::add_left_panel; use crate::ui::components::styled::island_central_panel; use crate::ui::components::tokens_subscreen_chooser_panel::add_tokens_subscreen_chooser_panel; @@ -74,6 +75,23 @@ pub struct UpdateTokenConfigScreen { } impl UpdateTokenConfigScreen { + fn set_text_input_error(&mut self, ctx: &Context, message: impl Into) { + let next_message = message.into(); + if self.text_input_error == next_message { + return; + } + + if !self.text_input_error.is_empty() { + MessageBanner::clear_global_message(ctx, &self.text_input_error); + } + + self.text_input_error = next_message; + + if !self.text_input_error.is_empty() { + MessageBanner::set_global(ctx, &self.text_input_error, MessageType::Error); + } + } + pub fn new(identity_token_info: IdentityTokenInfo, app_context: &Arc) -> Self { let possible_key = identity_token_info .identity @@ -275,7 +293,7 @@ impl UpdateTokenConfigScreen { self.update_text = serde_json::to_string_pretty(default_token_configuration.conventions()) .unwrap_or_default(); - self.text_input_error = "".to_string(); + self.set_text_input_error(ui.ctx(), String::new()); self.update_group_based_on_change_item(); }; if ui @@ -368,8 +386,10 @@ impl UpdateTokenConfigScreen { .clicked() { self.update_text = "".to_string(); - self.text_input_error = - "The perpetual distribution can not be modified".to_string(); + self.set_text_input_error( + ui.ctx(), + "The perpetual distribution can not be modified".to_string(), + ); self.update_group_based_on_change_item(); }; if ui @@ -566,6 +586,7 @@ impl UpdateTokenConfigScreen { ui.add_space(10.0); /* ========== PER‑VARIANT EDITING ========== */ + let mut pending_text_input_error: Option = None; match &mut self.change_item { TokenConfigurationChangeItem::Conventions(conv) => { ui.label("Update the JSON formatted text below to change the token conventions."); @@ -577,10 +598,10 @@ impl UpdateTokenConfigScreen { match serde_json::from_str::(&self.update_text) { Ok(new_conv) => { *conv = new_conv; - self.text_input_error = "".to_string(); + pending_text_input_error = Some(String::new()); } Err(e) => { - self.text_input_error = format!("Invalid JSON: {}", e); + pending_text_input_error = Some(format!("Invalid JSON: {}", e)); } } } @@ -589,11 +610,7 @@ impl UpdateTokenConfigScreen { if ui.button("Reset to Current").clicked() { *conv = self.identity_token_info.token_config.conventions().clone(); self.update_text = serde_json::to_string_pretty(conv).unwrap_or_default(); // Update displayed text - self.text_input_error = "".to_string(); - } - - if !self.text_input_error.is_empty() { - ui.colored_label(Color32::RED, &self.text_input_error); + pending_text_input_error = Some(String::new()); } }); } @@ -626,10 +643,6 @@ impl UpdateTokenConfigScreen { serde_json::to_string_pretty(opt_json).unwrap_or_default(); // Update displayed text } - - if !self.text_input_error.is_empty() { - ui.colored_label(Color32::RED, &self.text_input_error); - } }); } TokenConfigurationChangeItem::MainControlGroup(opt_grp) => { @@ -679,6 +692,9 @@ impl UpdateTokenConfigScreen { ui.label("Marketplace settings are not yet supported."); } } + if let Some(message) = pending_text_input_error { + self.set_text_input_error(ui.ctx(), message); + } }); }); ui.add_space(10.0); @@ -1111,7 +1127,13 @@ impl ScreenLike for UpdateTokenConfigScreen { .stroke(egui::Stroke::new(1.0, error_color)) .show(ui, |ui| { ui.horizontal(|ui| { - ui.label(RichText::new(format!("Error: {}", msg)).color(error_color)); + ui.add( + egui::Label::new( + RichText::new(format!("Error: {}", msg)) + .color(error_color), + ) + .wrap(), + ); ui.add_space(10.0); if ui.small_button("Dismiss").clicked() { self.backend_message = None; diff --git a/src/ui/tokens/view_token_claims_screen.rs b/src/ui/tokens/view_token_claims_screen.rs index adc713c16..b8e7d996b 100644 --- a/src/ui/tokens/view_token_claims_screen.rs +++ b/src/ui/tokens/view_token_claims_screen.rs @@ -154,7 +154,12 @@ impl ScreenLike for ViewTokenClaimsScreen { ui.colored_label(DashColors::success_color(dark_mode), msg); } MessageType::Error | MessageType::Warning => { - ui.colored_label(DashColors::error_color(dark_mode), msg); + ui.add( + egui::Label::new( + egui::RichText::new(msg).color(DashColors::error_color(dark_mode)), + ) + .wrap(), + ); } MessageType::Info => { ui.label(msg); diff --git a/src/ui/wallets/add_new_wallet_screen.rs b/src/ui/wallets/add_new_wallet_screen.rs index f25a320d6..a16ddabb2 100644 --- a/src/ui/wallets/add_new_wallet_screen.rs +++ b/src/ui/wallets/add_new_wallet_screen.rs @@ -895,7 +895,7 @@ impl ScreenLike for AddNewWalletScreen { .collapsible(false) .anchor(egui::Align2::CENTER_CENTER, Vec2::new(0.0, 0.0)) .show(ctx, |ui| { - ui.label(error_message); + ui.add(egui::Label::new(error_message).wrap()); ui.add_space(10.0); if ui.button("Close").clicked() { self.error = None; // Clear the error to close the popup diff --git a/src/ui/wallets/create_asset_lock_screen.rs b/src/ui/wallets/create_asset_lock_screen.rs index b0d28d310..7fa438ecf 100644 --- a/src/ui/wallets/create_asset_lock_screen.rs +++ b/src/ui/wallets/create_asset_lock_screen.rs @@ -615,7 +615,13 @@ impl ScreenLike for CreateAssetLockScreen { ui.add_space(20.0); if let Some(error_message) = self.error_message.as_ref() { - ui.colored_label(egui::Color32::DARK_RED, error_message); + ui.add( + egui::Label::new( + egui::RichText::new(error_message) + .color(egui::Color32::DARK_RED), + ) + .wrap(), + ); ui.add_space(20.0); } diff --git a/src/ui/wallets/import_mnemonic_screen.rs b/src/ui/wallets/import_mnemonic_screen.rs index 85247628a..e1f95d7ab 100644 --- a/src/ui/wallets/import_mnemonic_screen.rs +++ b/src/ui/wallets/import_mnemonic_screen.rs @@ -473,7 +473,7 @@ impl ImportMnemonicScreen { // Show error if any if let Some(ref err) = self.error { ui.add_space(5.0); - ui.colored_label(DashColors::ERROR, err); + ui.add(egui::Label::new(egui::RichText::new(err).color(DashColors::ERROR)).wrap()); } } @@ -603,7 +603,13 @@ impl ScreenLike for ImportMnemonicScreen { if let Some(ref error_msg) = self.error && error_msg.contains("Invalid seed phrase") { ui.add_space(10.0); - ui.colored_label(DashColors::ERROR, error_msg); + ui.add( + egui::Label::new( + egui::RichText::new(error_msg) + .color(DashColors::ERROR), + ) + .wrap(), + ); } if self.seed_phrase.is_none() { diff --git a/src/ui/wallets/send_screen.rs b/src/ui/wallets/send_screen.rs index e27300f80..f7028c9a3 100644 --- a/src/ui/wallets/send_screen.rs +++ b/src/ui/wallets/send_screen.rs @@ -1063,9 +1063,12 @@ impl WalletSendScreen { } if wallet_needs_unlock(wallet) { ui.add_space(10.0); - ui.colored_label( - egui::Color32::from_rgb(200, 150, 50), - "Wallet is locked. Please unlock to continue.", + ui.add( + egui::Label::new( + egui::RichText::new("Wallet is locked. Please unlock to continue.") + .color(egui::Color32::from_rgb(200, 150, 50)), + ) + .wrap(), ); ui.add_space(8.0); if ui.button("Unlock Wallet").clicked() { @@ -1149,7 +1152,12 @@ impl WalletSendScreen { .stroke(egui::Stroke::new(1.0, DashColors::ERROR)) .show(ui, |ui| { ui.horizontal(|ui| { - ui.label(RichText::new(&error_msg).color(DashColors::ERROR)); + ui.add( + egui::Label::new( + RichText::new(&error_msg).color(DashColors::ERROR), + ) + .wrap(), + ); ui.add_space(10.0); if ui.small_button("Dismiss").clicked() { dismiss = true; diff --git a/src/ui/wallets/single_key_send_screen.rs b/src/ui/wallets/single_key_send_screen.rs index 9528d9020..dae6dbd7b 100644 --- a/src/ui/wallets/single_key_send_screen.rs +++ b/src/ui/wallets/single_key_send_screen.rs @@ -378,7 +378,12 @@ impl SingleKeyWalletSendScreen { if let Some(error) = &self.recipients[i].error { ui.add_space(5.0); - ui.label(RichText::new(error).color(DashColors::ERROR).size(12.0)); + ui.add( + egui::Label::new( + RichText::new(error).color(DashColors::ERROR).size(12.0), + ) + .wrap(), + ); } } }); @@ -802,7 +807,10 @@ impl SingleKeyWalletSendScreen { if let Some(error) = &self.error_message { ui.add_space(5.0); - ui.label(RichText::new(error).color(DashColors::ERROR).size(12.0)); + ui.add( + egui::Label::new(RichText::new(error).color(DashColors::ERROR).size(12.0)) + .wrap(), + ); } }); diff --git a/src/ui/wallets/wallets_screen/dialogs.rs b/src/ui/wallets/wallets_screen/dialogs.rs index 5c9b640d2..80c5d1638 100644 --- a/src/ui/wallets/wallets_screen/dialogs.rs +++ b/src/ui/wallets/wallets_screen/dialogs.rs @@ -168,7 +168,13 @@ impl WalletsBalancesScreen { } if let Some(error) = &self.send_dialog.address_error { - ui.colored_label(egui::Color32::from_rgb(255, 100, 100), error); + ui.add( + egui::Label::new( + egui::RichText::new(error) + .color(egui::Color32::from_rgb(255, 100, 100)), + ) + .wrap(), + ); } ui.add_space(8.0); diff --git a/src/ui/wallets/wallets_screen/mod.rs b/src/ui/wallets/wallets_screen/mod.rs index d6bf5a002..aac6616d9 100644 --- a/src/ui/wallets/wallets_screen/mod.rs +++ b/src/ui/wallets/wallets_screen/mod.rs @@ -10,6 +10,7 @@ use crate::context::AppContext; use crate::model::amount::Amount; use crate::model::wallet::{Wallet, WalletSeedHash, WalletTransaction}; use crate::spv::CoreBackendMode; +use crate::ui::components::MessageBanner; use crate::ui::components::component_trait::Component; use crate::ui::components::confirmation_dialog::{ConfirmationDialog, ConfirmationStatus}; use crate::ui::components::left_panel::add_left_panel; @@ -1663,12 +1664,21 @@ impl ScreenLike for WalletsBalancesScreen { match unlock_result { Ok(_) => { + MessageBanner::clear_global_message( + ui.ctx(), + "Error: Incorrect Password", + ); self.sk_error_message = None; close_dialog = true; } Err(_) => { self.sk_error_message = Some("Incorrect Password".to_string()); + MessageBanner::set_global( + ui.ctx(), + "Error: Incorrect Password", + MessageType::Error, + ); } } } @@ -1678,21 +1688,11 @@ impl ScreenLike for WalletsBalancesScreen { // Display error message if the password was incorrect if let Some(error_message) = self.sk_error_message.clone() { ui.add_space(5.0); - let error_color = DashColors::ERROR; - Frame::new() - .fill(error_color.gamma_multiply(0.1)) - .inner_margin(Margin::symmetric(10, 8)) - .corner_radius(5.0) - .stroke(egui::Stroke::new(1.0, error_color)) - .show(ui, |ui| { - ui.horizontal(|ui| { - ui.label(RichText::new(format!("Error: {}", error_message)).color(error_color)); - ui.add_space(10.0); - if ui.small_button("Dismiss").clicked() { - self.sk_error_message = None; - } - }); - }); + let banner_text = format!("Error: {}", error_message); + if ui.small_button("Dismiss").clicked() { + MessageBanner::clear_global_message(ui.ctx(), &banner_text); + self.sk_error_message = None; + } } }); }); @@ -1700,6 +1700,7 @@ impl ScreenLike for WalletsBalancesScreen { if close_dialog { self.show_sk_unlock_dialog = false; self.sk_wallet_password.clear(); + MessageBanner::clear_global_message(ctx, "Error: Incorrect Password"); self.sk_error_message = None; // Check if we were trying to refresh the SK wallet