Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 37 additions & 43 deletions src/ui/contracts_documents/contracts_documents_screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use crate::backend_task::contract::ContractTask;
use crate::backend_task::document::DocumentTask::{self, FetchDocumentsPage}; // Updated import
use crate::context::AppContext;
use crate::model::qualified_contract::QualifiedContract;
use crate::ui::components::Component;
use crate::ui::components::confirmation_dialog::{ConfirmationDialog, ConfirmationStatus};
use crate::ui::components::contract_chooser_panel::{
ContractChooserState, add_contract_chooser_panel,
};
Expand Down Expand Up @@ -57,7 +59,7 @@ pub struct DocumentQueryScreen {
selected_index: Option<Index>,
pub matching_documents: Vec<Document>,
document_query_status: DocumentQueryStatus,
confirm_remove_contract_popup: bool,
confirmation_dialog: Option<ConfirmationDialog>,
contract_to_remove: Option<Identifier>,
pending_document_type: DocumentType,
pending_fields_selection: HashMap<String, bool>,
Expand Down Expand Up @@ -122,7 +124,7 @@ impl DocumentQueryScreen {
selected_index: None,
matching_documents: vec![],
document_query_status: DocumentQueryStatus::NotStarted,
confirm_remove_contract_popup: false,
confirmation_dialog: None,
contract_to_remove: None,
pending_document_type,
pending_fields_selection,
Expand Down Expand Up @@ -490,53 +492,44 @@ impl DocumentQueryScreen {
let contract_to_remove = match &self.contract_to_remove {
Some(contract) => *contract,
None => {
self.confirm_remove_contract_popup = false;
self.confirmation_dialog = None;
return AppAction::None;
}
};

let mut app_action = AppAction::None;
let mut is_open = true;

egui::Window::new("Confirm Remove Contract")
.collapsible(false)
.open(&mut is_open)
.show(ui.ctx(), |ui| {
let contract_alias_or_id =
match self.app_context.get_contract_by_id(&contract_to_remove) {
Ok(Some(contract)) => contract
.alias
.unwrap_or_else(|| contract.contract.id().to_string(Encoding::Base58)),
Ok(None) | Err(_) => contract_to_remove.to_string(Encoding::Base58),
};

ui.label(format!(
let contract_alias_or_id = match self.app_context.get_contract_by_id(&contract_to_remove) {
Ok(Some(contract)) => contract
.alias
.unwrap_or_else(|| contract.contract.id().to_string(Encoding::Base58)),
Ok(None) | Err(_) => contract_to_remove.to_string(Encoding::Base58),
};

let dialog = self.confirmation_dialog.get_or_insert_with(|| {
ConfirmationDialog::new(
"Confirm Remove Contract".to_string(),
format!(
"Are you sure you want to remove contract \"{}\"?",
contract_alias_or_id
));

// Confirm button
if ui.button("Confirm").clicked() {
app_action = AppAction::BackendTask(BackendTask::ContractTask(Box::new(
ContractTask::RemoveContract(contract_to_remove),
)));
self.confirm_remove_contract_popup = false;
self.contract_to_remove = None;
}

// Cancel button
if ui.button("Cancel").clicked() {
self.confirm_remove_contract_popup = false;
self.contract_to_remove = None;
}
});
),
)
});

// If user closes the popup window (the [x] button), also reset state
if !is_open {
self.confirm_remove_contract_popup = false;
self.contract_to_remove = None;
match dialog.show(ui).inner.dialog_response {
Some(ConfirmationStatus::Confirmed) => {
let action = AppAction::BackendTask(BackendTask::ContractTask(Box::new(
ContractTask::RemoveContract(contract_to_remove),
)));
self.confirmation_dialog = None;
self.contract_to_remove = None;
action
}
Some(ConfirmationStatus::Canceled) => {
self.confirmation_dialog = None;
self.contract_to_remove = None;
AppAction::None
}
None => AppAction::None,
}
app_action
}
}

Expand Down Expand Up @@ -708,8 +701,9 @@ impl ScreenLike for DocumentQueryScreen {
if let AppAction::BackendTask(BackendTask::ContractTask(contract_task)) = &action {
if let ContractTask::RemoveContract(contract_id) = **contract_task {
action = AppAction::None;
self.confirm_remove_contract_popup = true;
self.contract_to_remove = Some(contract_id);
// Clear any existing dialog to create a new one with updated content
self.confirmation_dialog = None;
}
}

Expand Down Expand Up @@ -752,7 +746,7 @@ impl ScreenLike for DocumentQueryScreen {
);
});

if self.confirm_remove_contract_popup {
if self.contract_to_remove.is_some() {
inner_action |= self.show_remove_contract_popup(ui);
}
inner_action
Expand Down
15 changes: 10 additions & 5 deletions src/ui/identities/identities_screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -836,8 +836,9 @@ impl IdentitiesScreen {
action
}

fn show_identity_to_remove(&mut self, ctx: &Context) {
fn show_identity_to_remove(&mut self, ctx: &Context) -> AppAction {
if let Some(identity_to_remove) = self.identity_to_remove.clone() {
let action = AppAction::None;
egui::Window::new("Confirm Removal")
.collapsible(false)
.resizable(false)
Expand Down Expand Up @@ -884,6 +885,9 @@ impl IdentitiesScreen {
}
});
});
action
} else {
AppAction::None
}
}

Expand Down Expand Up @@ -1004,6 +1008,11 @@ impl ScreenLike for IdentitiesScreen {
inner_action |= self.render_identities_view(ui, &identities_vec);
}

// Handle identity removal confirmation dialog
if self.identity_to_remove.is_some() {
inner_action |= self.show_identity_to_remove(ctx);
}

// Show either refreshing indicator or message, but not both
if let IdentitiesRefreshingStatus::Refreshing(start_time) = self.refreshing_status {
ui.add_space(25.0); // Space above
Expand Down Expand Up @@ -1040,10 +1049,6 @@ impl ScreenLike for IdentitiesScreen {
inner_action
});

if self.identity_to_remove.is_some() {
self.show_identity_to_remove(ctx);
}

match action {
AppAction::BackendTask(BackendTask::IdentityTask(IdentityTask::RefreshIdentity(_))) => {
self.refreshing_status =
Expand Down
149 changes: 80 additions & 69 deletions src/ui/identities/withdraw_screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::model::qualified_identity::encrypted_key_storage::PrivateKeyData;
use crate::model::qualified_identity::{IdentityType, PrivateKeyTarget, QualifiedIdentity};
use crate::model::wallet::Wallet;
use crate::ui::components::amount_input::AmountInput;
use crate::ui::components::confirmation_dialog::{ConfirmationDialog, ConfirmationStatus};
use crate::ui::components::left_panel::add_left_panel;
use crate::ui::components::styled::island_central_panel;
use crate::ui::components::top_panel::add_top_panel;
Expand Down Expand Up @@ -48,7 +49,7 @@ pub struct WithdrawalScreen {
withdrawal_amount_input: Option<AmountInput>,
max_amount: u64,
pub app_context: Arc<AppContext>,
confirmation_popup: bool,
confirmation_dialog: Option<ConfirmationDialog>,
withdraw_from_identity_status: WithdrawFromIdentityStatus,
selected_wallet: Option<Arc<RwLock<Wallet>>>,
wallet_password: String,
Expand Down Expand Up @@ -77,7 +78,7 @@ impl WithdrawalScreen {
withdrawal_amount_input: None,
max_amount,
app_context: app_context.clone(),
confirmation_popup: false,
confirmation_dialog: None,
withdraw_from_identity_status: WithdrawFromIdentityStatus::NotStarted,
selected_wallet,
wallet_password: String::new(),
Expand Down Expand Up @@ -153,56 +154,68 @@ impl WithdrawalScreen {
}

fn show_confirmation_popup(&mut self, ui: &mut Ui) -> AppAction {
let mut app_action = AppAction::None;
let mut is_open = true;
egui::Window::new("Confirm Withdrawal")
.collapsible(false)
.open(&mut is_open)
.show(ui.ctx(), |ui| {
let address = if self.withdrawal_address.is_empty() {
None
} else {
match Address::from_str(&self.withdrawal_address) {
Ok(address) => Some(address.assume_checked()),
Err(_) => {
self.withdraw_from_identity_status =
WithdrawFromIdentityStatus::ErrorMessage(
"Invalid withdrawal address".to_string(),
);
None
}
}
};

let message_address = if address.is_some() {
self.withdrawal_address.clone()
} else if let Some(payout_address) = self
.identity
.masternode_payout_address(self.app_context.network)
{
format!("masternode payout address {}", payout_address)
} else if !self.app_context.is_developer_mode() {
let address = if self.withdrawal_address.is_empty() {
None
} else {
match Address::from_str(&self.withdrawal_address) {
Ok(address) => Some(address.assume_checked()),
Err(_) => {
self.withdraw_from_identity_status = WithdrawFromIdentityStatus::ErrorMessage(
"No masternode payout address".to_string(),
"Invalid withdrawal address".to_string(),
);
return;
} else {
"to default address".to_string()
};
self.confirmation_dialog = None;
return AppAction::None;
}
}
};

let message_address = if address.is_some() {
self.withdrawal_address.clone()
} else if let Some(payout_address) = self
.identity
.masternode_payout_address(self.app_context.network)
{
format!("masternode payout address {}", payout_address)
} else if !self.app_context.is_developer_mode() {
self.withdraw_from_identity_status = WithdrawFromIdentityStatus::ErrorMessage(
"No masternode payout address".to_string(),
);
self.confirmation_dialog = None;
return AppAction::None;
} else {
"to default address".to_string()
};

let Some(selected_key) = self.selected_key.as_ref() else {
self.withdraw_from_identity_status =
WithdrawFromIdentityStatus::ErrorMessage("No selected key".to_string());
return;
};
let Some(selected_key) = self.selected_key.as_ref() else {
self.withdraw_from_identity_status =
WithdrawFromIdentityStatus::ErrorMessage("No selected key".to_string());
self.confirmation_dialog = None;
return AppAction::None;
};

ui.label(format!(
let dialog = self.confirmation_dialog.get_or_insert_with(|| {
ConfirmationDialog::new(
"Confirm Withdrawal".to_string(),
format!(
"Are you sure you want to withdraw {} to {}",
self.withdrawal_amount
.as_ref()
.expect("Withdrawal amount should be present"),
message_address
));
),
)
.danger_mode(true) // Withdrawal is a destructive operation
});

match dialog.show(ui).inner.dialog_response {
Some(ConfirmationStatus::Confirmed) => {
self.confirmation_dialog = None;
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards")
.as_secs();
self.withdraw_from_identity_status =
WithdrawFromIdentityStatus::WaitingForResult(now);

// Use the amount directly from the stored amount
let credits = self
Expand All @@ -211,31 +224,21 @@ impl WithdrawalScreen {
.expect("Withdrawal amount should be present")
.value() as u128;

if ui.button("Confirm").clicked() {
self.confirmation_popup = false;
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards")
.as_secs();
self.withdraw_from_identity_status =
WithdrawFromIdentityStatus::WaitingForResult(now);
app_action = AppAction::BackendTask(BackendTask::IdentityTask(
IdentityTask::WithdrawFromIdentity(
self.identity.clone(),
address,
credits as Credits,
Some(selected_key.id()),
),
));
}
if ui.button("Cancel").clicked() {
self.confirmation_popup = false;
}
});
if !is_open {
self.confirmation_popup = false;
AppAction::BackendTask(BackendTask::IdentityTask(
IdentityTask::WithdrawFromIdentity(
self.identity.clone(),
address,
credits as Credits,
Some(selected_key.id()),
),
))
}
Some(ConfirmationStatus::Canceled) => {
self.confirmation_dialog = None;
AppAction::None
}
None => AppAction::None,
}
app_action
}

pub fn show_success(&self, ui: &mut Ui) -> AppAction {
Expand Down Expand Up @@ -469,11 +472,19 @@ impl ScreenLike for WithdrawalScreen {
.add_enabled(ready, button)
.on_disabled_hover_text("Please enter a valid amount to withdraw")
.clicked()
&& self.confirmation_dialog.is_none()
{
self.confirmation_popup = true;
// Validation will be done in show_confirmation_popup
self.confirmation_dialog = Some(
ConfirmationDialog::new(
"Confirm Withdrawal".to_string(),
"Loading...".to_string(), // Will be updated in show_confirmation_popup
)
.danger_mode(true),
);
}

if self.confirmation_popup {
if self.confirmation_dialog.is_some() {
inner_action |= self.show_confirmation_popup(ui);
}

Expand Down
Loading
Loading