Add backend section to settings to send invitation

This commit is contained in:
edouardparis 2024-08-09 12:51:00 +02:00
parent 5e4c04fa80
commit 0fbba9eaa2
3 changed files with 211 additions and 21 deletions

View File

@ -7,13 +7,20 @@ use std::sync::Arc;
use iced::Command;
use liana_ui::widget::Element;
use liana_ui::{component::form, widget::Element};
use bitcoind::BitcoindSettingsState;
use wallet::WalletSettingsState;
use crate::{
app::{cache::Cache, error::Error, message::Message, state::State, view, wallet::Wallet},
app::{
cache::Cache,
error::Error,
message::Message,
state::State,
view::{self},
wallet::Wallet,
},
daemon::{Daemon, DaemonBackend},
};
@ -66,6 +73,12 @@ impl State for SettingsState {
.map(|s| s.reload(daemon, wallet))
.unwrap_or_else(Command::none)
}
Message::View(view::Message::Settings(
view::SettingsMessage::EditRemoteBackendSettings,
)) => {
self.setting = Some(BackendSettingsState::new().into());
Command::none()
}
Message::View(view::Message::Settings(view::SettingsMessage::AboutSection)) => {
self.setting = Some(AboutSettingsState::default().into());
let wallet = self.wallet.clone();
@ -138,19 +151,6 @@ pub struct AboutSettingsState {
warning: Option<Error>,
}
impl AboutSettingsState {
pub fn new(daemon_is_external: bool) -> Self {
AboutSettingsState {
daemon_version: if !daemon_is_external {
Some(liana::VERSION.to_string())
} else {
None
},
warning: None,
}
}
}
impl State for AboutSettingsState {
fn view<'a>(&'a self, cache: &'a Cache) -> Element<'a, view::Message> {
view::settings::about_section(cache, self.warning.as_ref(), self.daemon_version.as_ref())
@ -158,13 +158,19 @@ impl State for AboutSettingsState {
fn update(
&mut self,
_daemon: Arc<dyn Daemon + Sync + Send>,
daemon: Arc<dyn Daemon + Sync + Send>,
_cache: &Cache,
message: Message,
) -> Command<Message> {
if let Message::Info(res) = message {
match res {
Ok(info) => self.daemon_version = Some(info.version),
Ok(info) => {
if daemon.backend() == DaemonBackend::RemoteBackend {
self.daemon_version = None;
} else {
self.daemon_version = Some(info.version)
}
}
Err(e) => self.warning = Some(e),
}
}
@ -189,3 +195,94 @@ impl From<AboutSettingsState> for Box<dyn State> {
Box::new(s)
}
}
#[derive(Default)]
pub struct BackendSettingsState {
email_form: form::Value<String>,
processing: bool,
success: bool,
warning: Option<Error>,
}
impl BackendSettingsState {
pub fn new() -> Self {
Self {
email_form: form::Value::default(),
processing: false,
success: false,
warning: None,
}
}
}
impl State for BackendSettingsState {
fn view<'a>(&'a self, cache: &'a Cache) -> Element<'a, view::Message> {
view::settings::remote_backend_section(
cache,
&self.email_form,
self.processing,
self.success,
self.warning.as_ref(),
)
}
fn update(
&mut self,
daemon: Arc<dyn Daemon + Sync + Send>,
_cache: &Cache,
message: Message,
) -> Command<Message> {
match message {
Message::View(view::Message::Settings(
view::SettingsMessage::RemoteBackendSettings(message),
)) => match message {
view::RemoteBackendSettingsMessage::SendInvitation => {
if !self.email_form.valid {
return Command::none();
}
let email = self.email_form.value.clone();
self.processing = true;
self.success = false;
self.warning = None;
Command::perform(
async move {
daemon.send_wallet_invitation(&email).await?;
Ok(())
},
Message::Updated,
)
}
view::RemoteBackendSettingsMessage::EditInvitationEmail(email) => {
if !self.processing {
self.email_form.valid = email_address::EmailAddress::parse_with_options(
&email,
email_address::Options::default().with_required_tld(),
)
.is_ok();
self.email_form.value = email;
self.success = false;
}
Command::none()
}
},
Message::Updated(res) => {
self.processing = false;
match res {
Ok(()) => self.success = true,
Err(e) => {
self.success = false;
self.warning = Some(e);
}
}
Command::none()
}
_ => Command::none(),
}
}
}
impl From<BackendSettingsState> for Box<dyn State> {
fn from(s: BackendSettingsState) -> Box<dyn State> {
Box::new(s)
}
}

View File

@ -68,6 +68,8 @@ pub enum SettingsMessage {
EditBitcoindSettings,
BitcoindSettings(SettingsEditMessage),
RescanSettings(SettingsEditMessage),
EditRemoteBackendSettings,
RemoteBackendSettings(RemoteBackendSettingsMessage),
EditWalletSettings,
AboutSection,
RegisterWallet,
@ -75,6 +77,12 @@ pub enum SettingsMessage {
Save,
}
#[derive(Debug, Clone)]
pub enum RemoteBackendSettingsMessage {
EditInvitationEmail(String),
SendInvitation,
}
#[derive(Debug, Clone)]
pub enum SettingsEditMessage {
Select,

View File

@ -44,9 +44,9 @@ pub fn list(cache: &Cache, is_remote_backend: bool) -> Element<Message> {
Button::new(text("Settings").size(30).bold())
.style(theme::Button::Transparent)
.on_press(Message::Menu(Menu::Settings)))
.push_maybe(
.push(
if !is_remote_backend {
Some(Container::new(
Container::new(
Button::new(
Row::new()
.push(badge::Badge::new(icon::bitcoin_icon()))
@ -61,9 +61,24 @@ pub fn list(cache: &Cache, is_remote_backend: bool) -> Element<Message> {
.on_press(Message::Settings(SettingsMessage::EditBitcoindSettings))
)
.width(Length::Fill)
.style(theme::Container::Card(theme::Card::Simple)))
.style(theme::Container::Card(theme::Card::Simple))
} else {
None
Container::new(
Button::new(
Row::new()
.push(badge::Badge::new(icon::bitcoin_icon()))
.push(text("Backend").bold())
.padding(10)
.spacing(20)
.align_items(Alignment::Center)
.width(Length::Fill),
)
.width(Length::Fill)
.style(theme::Button::TransparentBorder)
.on_press(Message::Settings(SettingsMessage::EditRemoteBackendSettings))
)
.width(Length::Fill)
.style(theme::Container::Card(theme::Card::Simple))
}
)
.push(
@ -211,6 +226,76 @@ pub fn about_section<'a>(
)
}
pub fn remote_backend_section<'a>(
cache: &'a Cache,
email_form: &form::Value<String>,
processing: bool,
success: bool,
warning: Option<&Error>,
) -> Element<'a, Message> {
dashboard(
&Menu::Settings,
cache,
warning,
Column::new()
.spacing(20)
.push(
Row::new()
.spacing(10)
.align_items(Alignment::Center)
.push(
Button::new(text("Settings").size(30).bold())
.style(theme::Button::Transparent)
.on_press(Message::Menu(Menu::Settings)),
)
.push(icon::chevron_right().size(30))
.push(
Button::new(text("Backend").size(30).bold())
.style(theme::Button::Transparent)
.on_press(Message::Settings(SettingsMessage::AboutSection)),
),
)
.push(
card::simple(
Column::new()
.spacing(20)
.push(text("Grant access to wallet to another user"))
.push(
form::Form::new_trimmed("User email", email_form, |email| {
Message::Settings(SettingsMessage::RemoteBackendSettings(
RemoteBackendSettingsMessage::EditInvitationEmail(email),
))
})
.warning("Email is invalid")
.size(P1_SIZE)
.padding(10),
)
.push(
Row::new()
.push_maybe(if success {
Some(text("Invitation was sent").style(color::GREEN))
} else {
None
})
.push(Space::with_width(Length::Fill))
.push(button::primary(None, "Send invitation").on_press_maybe(
if !processing && email_form.valid {
Some(Message::Settings(
SettingsMessage::RemoteBackendSettings(
RemoteBackendSettingsMessage::SendInvitation,
),
))
} else {
None
},
)),
),
)
.width(Length::Fill),
),
)
}
pub fn bitcoind_edit<'a>(
network: Network,
blockheight: i32,