messages: async invoice and send request creation

This commit is contained in:
ardocrat 2024-05-18 22:17:46 +03:00
parent eedbce8d5c
commit 42146f0d68

View file

@ -12,6 +12,9 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::thread;
use egui::{Id, Margin, RichText, ScrollArea, TextBuffer}; use egui::{Id, Margin, RichText, ScrollArea, TextBuffer};
use egui::os::OperatingSystem; use egui::os::OperatingSystem;
use egui::scroll_area::ScrollBarVisibility; use egui::scroll_area::ScrollBarVisibility;
@ -19,6 +22,7 @@ use egui::text_edit::TextEditState;
use grin_core::core::{amount_from_hr_string, amount_to_hr_string}; use grin_core::core::{amount_from_hr_string, amount_to_hr_string};
use grin_wallet_libwallet::{Slate, SlateState}; use grin_wallet_libwallet::{Slate, SlateState};
use log::error; use log::error;
use parking_lot::RwLock;
use crate::gui::Colors; use crate::gui::Colors;
use crate::gui::icons::{BROOM, CLIPBOARD_TEXT, COPY, DOWNLOAD_SIMPLE, PROHIBIT, UPLOAD_SIMPLE}; use crate::gui::icons::{BROOM, CLIPBOARD_TEXT, COPY, DOWNLOAD_SIMPLE, PROHIBIT, UPLOAD_SIMPLE};
@ -75,6 +79,10 @@ pub struct WalletMessages {
request_edit: String, request_edit: String,
/// Flag to check if there is an error happened on request creation at [`Modal`]. /// Flag to check if there is an error happened on request creation at [`Modal`].
request_error: Option<MessageError>, request_error: Option<MessageError>,
/// Flag to check if request is loading at [`Modal`].
request_loading: Arc<AtomicBool>,
/// Request result if there is no error at [`Modal`].
request_result: Arc<RwLock<Option<Result<(Slate, String), grin_wallet_libwallet::Error>>>>,
} }
/// Identifier for amount input [`Modal`]. /// Identifier for amount input [`Modal`].
@ -139,6 +147,8 @@ impl WalletMessages {
amount_edit: "".to_string(), amount_edit: "".to_string(),
request_edit: "".to_string(), request_edit: "".to_string(),
request_error: None, request_error: None,
request_loading: Arc::new(AtomicBool::new(false)),
request_result: Arc::new(RwLock::new(None)),
} }
} }
@ -207,10 +217,16 @@ impl WalletMessages {
self.send_request = true; self.send_request = true;
self.amount_edit = "".to_string(); self.amount_edit = "".to_string();
self.request_error = None; self.request_error = None;
self.request_loading.store(false, Ordering::Relaxed);
{
let mut w_result = self.request_result.write();
*w_result = None;
}
// Show send amount modal. // Show send amount modal.
Modal::new(AMOUNT_MODAL) Modal::new(AMOUNT_MODAL)
.position(ModalPosition::CenterTop) .position(ModalPosition::CenterTop)
.title(t!("wallets.send")) .title(t!("wallets.send"))
.closeable(false)
.show(); .show();
cb.show_keyboard(); cb.show_keyboard();
}); });
@ -624,7 +640,46 @@ impl WalletMessages {
modal: &Modal, modal: &Modal,
cb: &dyn PlatformCallbacks) { cb: &dyn PlatformCallbacks) {
ui.add_space(6.0); ui.add_space(6.0);
if self.request_edit.is_empty() { if self.request_loading.load(Ordering::Relaxed) {
ui.add_space(42.0);
ui.vertical_centered(|ui| {
View::big_loading_spinner(ui);
});
ui.add_space(50.0);
// Check if there is request result error.
if self.request_error.is_some() {
self.request_loading.store(false, Ordering::Relaxed);
return;
}
// Update data on request result.
let r_request = self.request_result.read();
if r_request.is_some() {
let message = r_request.as_ref().unwrap();
match message {
Ok((_, message)) => {
self.request_edit = message.clone();
}
Err(err) => {
match err {
grin_wallet_libwallet::Error::NotEnoughFunds { .. } => {
let m = t!(
"wallets.pay_balance_error",
"amount" => self.amount_edit
);
self.request_error = Some(MessageError::Other(m));
}
_ => {
let m = t!("wallets.invoice_slatepack_err");
self.request_error = Some(MessageError::Other(m));
}
}
}
}
self.request_loading.store(false, Ordering::Relaxed);
}
} else if self.request_edit.is_empty() {
ui.vertical_centered(|ui| { ui.vertical_centered(|ui| {
let enter_text = if self.send_request { let enter_text = if self.send_request {
let data = wallet.get_data().unwrap(); let data = wallet.get_data().unwrap();
@ -712,32 +767,24 @@ impl WalletMessages {
return; return;
} }
if let Ok(a) = amount_from_hr_string(self.amount_edit.as_str()) { if let Ok(a) = amount_from_hr_string(self.amount_edit.as_str()) {
let message = if self.send_request { cb.hide_keyboard();
wallet.send(a)
} else { // Setup data for request.
wallet.issue_invoice(a) let wallet = wallet.clone();
}; let send_request = self.send_request.clone();
match message { let result = self.request_result.clone();
Ok((_, message)) => {
self.request_edit = message; // Send request at another thread.
cb.hide_keyboard(); self.request_loading.store(true, Ordering::Relaxed);
} thread::spawn(move || {
Err(err) => { let message = if send_request {
match err { wallet.send(a)
grin_wallet_libwallet::Error::NotEnoughFunds { .. } => { } else {
let m = t!( wallet.issue_invoice(a)
"wallets.pay_balance_error", };
"amount" => self.amount_edit let mut w_result = result.write();
); *w_result = Some(message);
self.request_error = Some(MessageError::Other(m)); });
}
_ => {
let m = t!("wallets.invoice_slatepack_err");
self.request_error = Some(MessageError::Other(m));
}
}
}
}
} else { } else {
self.request_error = Some( self.request_error = Some(
MessageError::Other(t!("wallets.invoice_slatepack_err")) MessageError::Other(t!("wallets.invoice_slatepack_err"))